mp4box.js icon indicating copy to clipboard operation
mp4box.js copied to clipboard

'save' function fails to save mdat box

Open oije2333 opened this issue 7 years ago • 3 comments

The following code appends a buffer consisting of an entire MP4 file then reconstructs and saves the result to a new file. The problem is that the mdat box is not written to the new file (only the ftyp and moov boxes are written). I see that in the function BoxParser.Box.prototype.parse, there is a condition, if (this.type != "mdat"), that skips the reading of the mdat data. Removing the condition results in the mdat data being written correctly to the output file. What is the reason the function was written this way? Is there another means of getting the mdat data into the output file that doesn't involve changing the code?

var mp4box = MP4Box.createFile(); mp4box.onReady = function(info) { this.save('example.mp4'); }; var buf; // get buf somehow buf.fileStart = 0; mp4box.appendBuffer(buf);

oije2333 avatar Sep 17 '18 17:09 oije2333

The logic is to do lazy parsing of media data, only when the samples are actually used. This allows processing mdat boxes even when the content of the mdat box has not been retrieved. This is useful in large files. If this is still an issue, can you describe the use case.

cconcolato avatar Dec 12 '20 00:12 cconcolato

@cconcolato I am trying to do something similar. I want to parse mp4 file and then pick random atoms and save them in a file. If that atom is mdat its not saved althrough discardMdatData is false. for some reason this.data is undefined. also there is a TODO to fix this. How can i force the write function to actually write the mdat data?

const mp4box = MP4Box.createFile();
const arrayBuffer = new Uint8Array(fs.readFileSync('some.mp4')).buffer;
arrayBuffer.fileStart = 0;
mp4box.appendBuffer(arrayBuffer);

const stream = new MP4Box.DataStream();
stream.endianness = MP4Box.DataStream.BIG_ENDIAN;
mp4box.boxes[X].write(stream);
fs.writeFileSync('somewhere', toBuffer(stream.buffer));

nklhtv avatar Jan 26 '21 14:01 nklhtv

discardMdatData should really be discardMdatDataAtParsing. Setting it to false will keep the data in order to expose it as part of the samples, but will not keep it for writing. In many cases, I can't afford to keep the data in 2 places: one in the samples, one in the mdat for writing back. You can try to modify :

  • https://github.com/gpac/mp4box.js/blob/master/src/box-parse.js#L106
  • https://github.com/gpac/mp4box.js/blob/master/src/box-parse.js#L123

cconcolato avatar Aug 20 '21 01:08 cconcolato