Add mdat support to the generator. Stub out media segment creation
Create a helper method to build mdat boxes. Generate an empty moof and a real mdat when a NAL unit is parsed.
Showing
4 changed files
with
35 additions
and
6 deletions
1 | (function(window, videojs, undefined) { | 1 | (function(window, videojs, undefined) { |
2 | 'use strict'; | 2 | 'use strict'; |
3 | 3 | ||
4 | var box, dinf, ftyp, minf, moof, moov, mvex, mvhd, trak, tkhd, mdia, mdhd, hdlr, stbl, | 4 | var box, dinf, ftyp, mdat, minf, moof, moov, mvex, mvhd, trak, tkhd, mdia, mdhd, hdlr, stbl, |
5 | stsd, styp, types, MAJOR_BRAND, MINOR_VERSION, VIDEO_HDLR, AUDIO_HDLR, HDLR_TYPES, VMHD, DREF, STCO, STSC, STSZ, STTS, TREX, | 5 | stsd, styp, types, MAJOR_BRAND, MINOR_VERSION, VIDEO_HDLR, AUDIO_HDLR, HDLR_TYPES, VMHD, DREF, STCO, STSC, STSZ, STTS, TREX, |
6 | Uint8Array, DataView; | 6 | Uint8Array, DataView; |
7 | 7 | ||
... | @@ -19,6 +19,7 @@ DataView = window.DataView; | ... | @@ -19,6 +19,7 @@ DataView = window.DataView; |
19 | dref: [], | 19 | dref: [], |
20 | ftyp: [], | 20 | ftyp: [], |
21 | hdlr: [], | 21 | hdlr: [], |
22 | mdat: [], | ||
22 | mdhd: [], | 23 | mdhd: [], |
23 | mdia: [], | 24 | mdia: [], |
24 | mfhd: [], | 25 | mfhd: [], |
... | @@ -165,6 +166,9 @@ ftyp = function() { | ... | @@ -165,6 +166,9 @@ ftyp = function() { |
165 | hdlr = function(type) { | 166 | hdlr = function(type) { |
166 | return box(types.hdlr, HDLR_TYPES[type]); | 167 | return box(types.hdlr, HDLR_TYPES[type]); |
167 | }; | 168 | }; |
169 | mdat = function(data) { | ||
170 | return box(types.mdat, data); | ||
171 | }; | ||
168 | mdhd = function(duration) { | 172 | mdhd = function(duration) { |
169 | return box(types.mdhd, new Uint8Array([ | 173 | return box(types.mdhd, new Uint8Array([ |
170 | 0x00, // version 0 | 174 | 0x00, // version 0 |
... | @@ -359,6 +363,7 @@ trak = function(duration, width, height, type) { | ... | @@ -359,6 +363,7 @@ trak = function(duration, width, height, type) { |
359 | 363 | ||
360 | window.videojs.mp4 = { | 364 | window.videojs.mp4 = { |
361 | ftyp: ftyp, | 365 | ftyp: ftyp, |
366 | mdat: mdat, | ||
362 | moof: moof, | 367 | moof: moof, |
363 | moov: moov, | 368 | moov: moov, |
364 | initSegment: function() { | 369 | initSegment: function() { | ... | ... |
... | @@ -440,10 +440,19 @@ Transmuxer = function() { | ... | @@ -440,10 +440,19 @@ Transmuxer = function() { |
440 | this.initSegment = mp4.initSegment(); | 440 | this.initSegment = mp4.initSegment(); |
441 | 441 | ||
442 | aacStream.on('data', function(data) { | 442 | aacStream.on('data', function(data) { |
443 | self.trigger('data', data); | ||
444 | }); | 443 | }); |
445 | h264Stream.on('data', function(data) { | 444 | h264Stream.on('data', function(data) { |
446 | self.trigger('data', data); | 445 | var |
446 | moof = mp4.moof([]), | ||
447 | mdat = mp4.mdat(data.data), | ||
448 | boxes = new Uint8Array(moof.byteLength + mdat.byteLength); | ||
449 | |||
450 | boxes.set(moof); | ||
451 | boxes.set(mdat, moof.byteLength); | ||
452 | |||
453 | self.trigger('data', { | ||
454 | data: boxes | ||
455 | }); | ||
447 | }); | 456 | }); |
448 | // feed incoming data to the front of the parsing pipeline | 457 | // feed incoming data to the front of the parsing pipeline |
449 | this.push = function(data) { | 458 | this.push = function(data) { | ... | ... |
... | @@ -264,5 +264,15 @@ test('generates a minimal moof', function() { | ... | @@ -264,5 +264,15 @@ test('generates a minimal moof', function() { |
264 | equal(moof[0].boxes[1].boxes[1].trackId, 2, 'wrote the second track id'); | 264 | equal(moof[0].boxes[1].boxes[1].trackId, 2, 'wrote the second track id'); |
265 | }); | 265 | }); |
266 | 266 | ||
267 | test('generates an mdat', function() { | ||
268 | var | ||
269 | data = mp4.mdat(new Uint8Array([1, 2, 3, 4])), | ||
270 | mdat = videojs.inspectMp4(data); | ||
271 | |||
272 | equal(mdat.length, 1, 'generated one box'); | ||
273 | equal(mdat[0].type, 'mdat', 'generated an mdat box'); | ||
274 | deepEqual(mdat[0].byteLength, 4, 'encapsulated the data'); | ||
275 | }); | ||
276 | |||
267 | 277 | ||
268 | })(window, window.videojs); | 278 | })(window, window.videojs); | ... | ... |
... | @@ -643,7 +643,7 @@ test('generates an init segment', function() { | ... | @@ -643,7 +643,7 @@ test('generates an init segment', function() { |
643 | }); | 643 | }); |
644 | 644 | ||
645 | test('parses an example mp2t file and generates media segments', function() { | 645 | test('parses an example mp2t file and generates media segments', function() { |
646 | var segments = [], i, segment; | 646 | var segments = [], i, boxes; |
647 | transmuxer.on('data', function(segment) { | 647 | transmuxer.on('data', function(segment) { |
648 | segments.push(segment); | 648 | segments.push(segment); |
649 | }); | 649 | }); |
... | @@ -653,9 +653,14 @@ test('parses an example mp2t file and generates media segments', function() { | ... | @@ -653,9 +653,14 @@ test('parses an example mp2t file and generates media segments', function() { |
653 | ok(segments.length, 'generated media segments'); | 653 | ok(segments.length, 'generated media segments'); |
654 | i = segments.length; | 654 | i = segments.length; |
655 | while (i--) { | 655 | while (i--) { |
656 | segment = videojs.inspectMp4(segments[i].data); | 656 | boxes = videojs.inspectMp4(segments[i].data); |
657 | equal(boxes.length, 2, 'segments are composed of two boxes'); | ||
658 | equal(boxes[0].type, 'moof', 'first box is a moof'); | ||
659 | equal(boxes[0].boxes.length, 2, 'moof has three children'); | ||
660 | equal(boxes[0].boxes[0].type, 'mfhd', 'mfhd is a child of the moof'); | ||
661 | equal(boxes[0].boxes[1].type, 'traf', 'traf is a child of the moof'); | ||
662 | equal(boxes[1].type, 'mdat', 'second box is an mdat'); | ||
657 | } | 663 | } |
658 | console.log(segments); | ||
659 | }); | 664 | }); |
660 | 665 | ||
661 | })(window, window.videojs); | 666 | })(window, window.videojs); | ... | ... |
-
Please register or sign in to post a comment