49e93b2e by David LaPalomento

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.
1 parent 85815fdb
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);
......