baa54acc by David LaPalomento

Parse out frame payload from ID3 frames

Fix up karma configuration so tests pass from the command line. Attach the bytes of the ID3 frame body in metadata stream events.
1 parent 622d5984
...@@ -49,13 +49,7 @@ ...@@ -49,13 +49,7 @@
49 // http://id3.org/id3v2.3.0#ID3v2_frame_overview 49 // http://id3.org/id3v2.3.0#ID3v2_frame_overview
50 chunk.frames = []; 50 chunk.frames = [];
51 do { 51 do {
52 chunk.frames.push({ 52 // determine the number of bytes in this frame
53 id: String.fromCharCode(chunk.data[frameStart]) +
54 String.fromCharCode(chunk.data[frameStart + 1]) +
55 String.fromCharCode(chunk.data[frameStart + 2]) +
56 String.fromCharCode(chunk.data[frameStart + 3])
57 });
58
59 frameSize = (chunk.data[frameStart + 4] << 24) | 53 frameSize = (chunk.data[frameStart + 4] << 24) |
60 (chunk.data[frameStart + 5] << 16) | 54 (chunk.data[frameStart + 5] << 16) |
61 (chunk.data[frameStart + 6] << 8) | 55 (chunk.data[frameStart + 6] << 8) |
...@@ -63,13 +57,22 @@ ...@@ -63,13 +57,22 @@
63 if (frameSize < 1) { 57 if (frameSize < 1) {
64 return videojs.log('Malformed ID3 frame encountered. Skipping metadata parsing.'); 58 return videojs.log('Malformed ID3 frame encountered. Skipping metadata parsing.');
65 } 59 }
60
61 chunk.frames.push({
62 id: String.fromCharCode(chunk.data[frameStart]) +
63 String.fromCharCode(chunk.data[frameStart + 1]) +
64 String.fromCharCode(chunk.data[frameStart + 2]) +
65 String.fromCharCode(chunk.data[frameStart + 3]),
66 data: chunk.data.subarray(frameStart + 10, frameStart + frameSize + 10)
67 });
68
66 frameStart += 10; // advance past the frame header 69 frameStart += 10; // advance past the frame header
67 frameStart += frameSize; // advance past the frame body 70 frameStart += frameSize; // advance past the frame body
68 } while (frameStart < tagSize) 71 } while (frameStart < tagSize);
69 this.trigger('data', chunk); 72 this.trigger('data', chunk);
70 }; 73 };
71 }; 74 };
72 MetadataStream.prototype = new videojs.Hls.Stream(); 75 MetadataStream.prototype = new videojs.Hls.Stream();
73 76
74 videojs.Hls.MetadataStream = MetadataStream; 77 videojs.Hls.MetadataStream = MetadataStream;
75 })(window, videojs); 78 })(window, window.videojs);
......
...@@ -80,14 +80,15 @@ module.exports = function(config) { ...@@ -80,14 +80,15 @@ module.exports = function(config) {
80 '../node_modules/pkcs7/dist/pkcs7.unpad.js', 80 '../node_modules/pkcs7/dist/pkcs7.unpad.js',
81 '../test/karma-qunit-shim.js', 81 '../test/karma-qunit-shim.js',
82 '../src/videojs-hls.js', 82 '../src/videojs-hls.js',
83 '../src/xhr.js', 83 '../src/stream.js',
84 '../src/flv-tag.js', 84 '../src/flv-tag.js',
85 '../src/exp-golomb.js', 85 '../src/exp-golomb.js',
86 '../src/h264-stream.js', 86 '../src/h264-stream.js',
87 '../src/aac-stream.js', 87 '../src/aac-stream.js',
88 '../src/metadata-stream.js',
88 '../src/segment-parser.js', 89 '../src/segment-parser.js',
89 '../src/stream.js',
90 '../src/m3u8/m3u8-parser.js', 90 '../src/m3u8/m3u8-parser.js',
91 '../src/xhr.js',
91 '../src/playlist-loader.js', 92 '../src/playlist-loader.js',
92 '../src/decrypter.js', 93 '../src/decrypter.js',
93 '../tmp/manifests.js', 94 '../tmp/manifests.js',
......
...@@ -44,14 +44,15 @@ module.exports = function(config) { ...@@ -44,14 +44,15 @@ module.exports = function(config) {
44 '../node_modules/pkcs7/dist/pkcs7.unpad.js', 44 '../node_modules/pkcs7/dist/pkcs7.unpad.js',
45 '../test/karma-qunit-shim.js', 45 '../test/karma-qunit-shim.js',
46 '../src/videojs-hls.js', 46 '../src/videojs-hls.js',
47 '../src/xhr.js', 47 '../src/stream.js',
48 '../src/flv-tag.js', 48 '../src/flv-tag.js',
49 '../src/exp-golomb.js', 49 '../src/exp-golomb.js',
50 '../src/h264-stream.js', 50 '../src/h264-stream.js',
51 '../src/aac-stream.js', 51 '../src/aac-stream.js',
52 '../src/metadata-stream.js',
52 '../src/segment-parser.js', 53 '../src/segment-parser.js',
53 '../src/stream.js',
54 '../src/m3u8/m3u8-parser.js', 54 '../src/m3u8/m3u8-parser.js',
55 '../src/xhr.js',
55 '../src/playlist-loader.js', 56 '../src/playlist-loader.js',
56 '../src/decrypter.js', 57 '../src/decrypter.js',
57 '../tmp/manifests.js', 58 '../tmp/manifests.js',
......
...@@ -66,7 +66,15 @@ ...@@ -66,7 +66,15 @@
66 }; 66 };
67 67
68 test('parses simple ID3 metadata out of PES packets', function() { 68 test('parses simple ID3 metadata out of PES packets', function() {
69 var events = [], id3Bytes, size; 69 var
70 events = [],
71 wxxxPayload = [
72 0x00 // text encoding. ISO-8859-1
73 ].concat(stringToCString('ad tag URL'), // description
74 stringToInts('http://example.com/ad?v=1234&q=7')), // value
75 id3Bytes,
76 size;
77
70 metadataStream.on('data', function(event) { 78 metadataStream.on('data', function(event) {
71 events.push(event); 79 events.push(event);
72 }); 80 });
...@@ -84,9 +92,7 @@ ...@@ -84,9 +92,7 @@
84 // frame 0 92 // frame 0
85 // http://id3.org/id3v2.3.0#User_defined_text_information_frame 93 // http://id3.org/id3v2.3.0#User_defined_text_information_frame
86 ], id3Frame('WXXX', 94 ], id3Frame('WXXX',
87 [0x00], // text encoding. ISO-8859-1 95 wxxxPayload), // value
88 stringToCString('ad tag URL'), // description
89 stringToInts('http://example.com/ad?v=1234&q=7')), // value
90 // frame 1 96 // frame 1
91 // custom tag 97 // custom tag
92 id3Frame('XINF', 98 id3Frame('XINF',
...@@ -115,11 +121,17 @@ ...@@ -115,11 +121,17 @@
115 equal(events.length, 1, 'parsed one tag'); 121 equal(events.length, 1, 'parsed one tag');
116 equal(events[0].frames.length, 2, 'parsed two frames'); 122 equal(events[0].frames.length, 2, 'parsed two frames');
117 equal(events[0].frames[0].id, 'WXXX', 'parsed a WXXX frame'); 123 equal(events[0].frames[0].id, 'WXXX', 'parsed a WXXX frame');
124 deepEqual(new Uint8Array(events[0].frames[0].data),
125 new Uint8Array(wxxxPayload),
126 'attached the frame payload');
118 equal(events[0].frames[1].id, 'XINF', 'parsed a user-defined frame'); 127 equal(events[0].frames[1].id, 'XINF', 'parsed a user-defined frame');
128 deepEqual(new Uint8Array(events[0].frames[1].data),
129 new Uint8Array([0x04, 0x03, 0x02, 0x01]),
130 'attached the frame payload');
119 }); 131 });
120 132
121 test('skips non-ID3 metadata events', function() { 133 test('skips non-ID3 metadata events', function() {
122 var events = [], id3Bytes, size; 134 var events = [];
123 metadataStream.on('data', function(event) { 135 metadataStream.on('data', function(event) {
124 events.push(event); 136 events.push(event);
125 }); 137 });
...@@ -143,5 +155,7 @@ ...@@ -143,5 +155,7 @@
143 // compressed frames 155 // compressed frames
144 // encrypted frames 156 // encrypted frames
145 // frame groups 157 // frame groups
158 // too large/small tag size values
159 // too large/small frame size values
146 160
147 })(window, videojs); 161 })(window, window.videojs);
......