diff --git a/lib/codecs/h264.js b/lib/codecs/h264.js index 1b66cdad..ec619c8a 100644 --- a/lib/codecs/h264.js +++ b/lib/codecs/h264.js @@ -40,6 +40,7 @@ NalByteStream = function() { swapBuffer.set(data.data, buffer.byteLength); buffer = swapBuffer; } + var len = buffer.byteLength; // Rec. ITU-T H.264, Annex B // scan for NAL unit boundaries @@ -52,7 +53,7 @@ NalByteStream = function() { // ^ sync point ^ i // advance the sync point to a NAL start, if necessary - for (; syncPoint < buffer.byteLength - 3; syncPoint++) { + for (; syncPoint < len - 3; syncPoint++) { if (buffer[syncPoint + 2] === 1) { // the sync point is properly aligned i = syncPoint + 5; @@ -60,7 +61,7 @@ NalByteStream = function() { } } - while (i < buffer.byteLength) { + while (i < len) { // look at the current byte to determine if we've hit the end of // a NAL unit boundary switch (buffer[i]) { @@ -82,7 +83,7 @@ NalByteStream = function() { // drop trailing zeroes do { i++; - } while (buffer[i] !== 1 && i < buffer.length); + } while (buffer[i] !== 1 && i < len); syncPoint = i - 2; i += 3; break; diff --git a/lib/mp4/audio-frame-utils.js b/lib/mp4/audio-frame-utils.js index faa5f4ab..93813d3f 100644 --- a/lib/mp4/audio-frame-utils.js +++ b/lib/mp4/audio-frame-utils.js @@ -121,7 +121,7 @@ var generateSampleTable = function(frames) { currentFrame = frames[i]; samples.push({ size: currentFrame.data.byteLength, - duration: 1024 // For AAC audio, all samples contain 1024 samples + duration: currentFrame.duration || 1024 // For AAC audio, all samples contain 1024 samples }); } return samples; diff --git a/lib/mp4/mp4-generator.js b/lib/mp4/mp4-generator.js index 032a7ba2..74f4806f 100644 --- a/lib/mp4/mp4-generator.js +++ b/lib/mp4/mp4-generator.js @@ -11,7 +11,7 @@ var UINT32_MAX = Math.pow(2, 32) - 1; -var box, dinf, esds, ftyp, mdat, mfhd, minf, moof, moov, mvex, mvhd, +var box, dfLa, dinf, esds, ftyp, mdat, mfhd, minf, moof, moov, mvex, mvhd, trak, tkhd, mdia, mdhd, hdlr, sdtp, stbl, stsd, traf, trex, trun, types, MAJOR_BRAND, MINOR_VERSION, AVC1_BRAND, VIDEO_HDLR, AUDIO_HDLR, HDLR_TYPES, VMHD, SMHD, DREF, STCO, STSC, STSZ, STTS; @@ -23,10 +23,12 @@ var box, dinf, esds, ftyp, mdat, mfhd, minf, moof, moov, mvex, mvhd, avc1: [], // codingname avcC: [], btrt: [], + dfLa: [], dinf: [], dref: [], esds: [], ftyp: [], + fLaC: [], hdlr: [], mdat: [], mdhd: [], @@ -184,6 +186,13 @@ box = function(type) { return result; }; +dfLa = function(track) { + return box(types.dfLa, new Uint8Array([ + 0x00, // version + 0x00, 0x00, 0x00 // flags + ]), track.metadata || []); +}; + dinf = function() { return box(types.dinf, box(types.dref, DREF)); }; @@ -465,7 +474,10 @@ stbl = function(track) { }; audioSample = function(track) { - return box(types.mp4a, new Uint8Array([ + var audioSampleBox = new Uint8Array([ + + // FLACSampleEntry extends AudioSampleEntry + // https://github.com/xiph/flac/blob/master/doc/isoflac.txt // SampleEntry, ISO/IEC 14496-12 0x00, 0x00, 0x00, @@ -488,7 +500,11 @@ stbl = function(track) { 0x00, 0x00 // samplerate, 16.16 // MP4AudioSampleEntry, ISO/IEC 14496-14 - ]), esds(track)); + ]); + if (track.codec === 'fLaC') { + return box(types.fLaC, audioSampleBox, dfLa(track)); + } + return box(types.mp4a, audioSampleBox, esds(track)); }; }());