123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732 |
- 'use strict';
- /*
- ======== A Handy Little QUnit Reference ========
- http://api.qunitjs.com/
- Test methods:
- module(name, {[setup][ ,teardown]})
- test(name, callback)
- expect(numberOfAssertions)
- stop(increment)
- start(decrement)
- Test assertions:
- ok(value, [message])
- equal(actual, expected, [message])
- notEqual(actual, expected, [message])
- deepEqual(actual, expected, [message])
- notDeepEqual(actual, expected, [message])
- strictEqual(actual, expected, [message])
- notStrictEqual(actual, expected, [message])
- throws(block, [expected], [message])
- */
- var metadataStream, stringToInts, stringToCString, id3Tag, id3Frame, id3Generator, mp2t, QUnit,
- webworkify, MetadataStreamTestWorker;
- mp2t = require('../lib/m2ts');
- QUnit = require('qunit');
- id3Generator = require('./utils/id3-generator');
- MetadataStreamTestWorker = require('worker!./metadata-stream-test-worker.js');
- stringToInts = id3Generator.stringToInts;
- stringToCString = id3Generator.stringToCString;
- id3Tag = id3Generator.id3Tag;
- id3Frame = id3Generator.id3Frame;
- QUnit.module('MetadataStream', {
- beforeEach: function() {
- metadataStream = new mp2t.MetadataStream();
- }
- });
- QUnit.test('can construct a MetadataStream', function(assert) {
- assert.ok(metadataStream, 'does not return null');
- });
- QUnit.test('triggers log for non-id3/invalid data', function(assert) {
- var logs = [];
- metadataStream.on('log', function(log) {
- logs.push(log);
- });
- // id3 not long enough
- metadataStream.push({type: 'timed-metadata', data: new Uint8Array()});
- // invalid data
- metadataStream.push({type: 'timed-metadata', data: new Uint8Array([
- 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01
- ])});
- const zeroFrames = new Uint8Array(stringToInts('ID3').concat([
- 0x03, 0x00, // version 3.0 of ID3v2 (aka ID3v.2.3.0)
- 0x40, // flags. include an extended header
- 0x00, 0x00, 0x00, 0x00, // size. set later
- // extended header
- 0x00, 0x00, 0x00, 0x06, // extended header size. no CRC
- 0x00, 0x00, // extended flags
- 0x00, 0x00, 0x00, 0x02 // size of padding
- ]));
- metadataStream.push({type: 'timed-metadata', data: zeroFrames});
- assert.deepEqual(logs, [
- {level: 'warn', message: 'Skipping unrecognized metadata packet'},
- {level: 'warn', message: 'Skipping unrecognized metadata packet'},
- {level: 'warn', message: 'Malformed ID3 frame encountered. Skipping remaining metadata parsing.'}
- ], 'logs as expected.');
- });
- QUnit.test('parses simple ID3 metadata out of PES packets', function(assert) {
- var
- events = [],
- wxxxPayload = [
- 0x00 // text encoding. ISO-8859-1
- ].concat(stringToCString('ad tag URL'), // description
- stringToInts('http://example.com/ad?v=1234&q=7')), // value
- id3Bytes,
- size;
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- id3Bytes = new Uint8Array(stringToInts('ID3').concat([
- 0x03, 0x00, // version 3.0 of ID3v2 (aka ID3v.2.3.0)
- 0x40, // flags. include an extended header
- 0x00, 0x00, 0x00, 0x00, // size. set later
- // extended header
- 0x00, 0x00, 0x00, 0x06, // extended header size. no CRC
- 0x00, 0x00, // extended flags
- 0x00, 0x00, 0x00, 0x02 // size of padding
- // frame 0
- // http://id3.org/id3v2.3.0#User_defined_text_information_frame
- ], id3Frame('WXXX',
- wxxxPayload), // value
- // frame 1
- // custom tag
- id3Frame('XINF',
- [
- 0x04, 0x03, 0x02, 0x01 // arbitrary data
- ]), [
- 0x00, 0x00 // padding
- ]));
- // set header size field
- size = id3Bytes.byteLength - 10;
- id3Bytes[6] = (size >>> 21) & 0x7f;
- id3Bytes[7] = (size >>> 14) & 0x7f;
- id3Bytes[8] = (size >>> 7) & 0x7f;
- id3Bytes[9] = (size) & 0x7f;
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 1000,
- // header
- data: id3Bytes
- });
- assert.equal(events.length, 1, 'parsed one tag');
- assert.equal(events[0].frames.length, 2, 'parsed two frames');
- assert.equal(events[0].frames[0].key, 'WXXX', 'parsed a WXXX frame');
- assert.deepEqual(new Uint8Array(events[0].frames[0].data),
- new Uint8Array(wxxxPayload),
- 'attached the frame payload');
- assert.equal(events[0].frames[1].key, 'XINF', 'parsed a user-defined frame');
- assert.deepEqual(new Uint8Array(events[0].frames[1].data),
- new Uint8Array([0x04, 0x03, 0x02, 0x01]),
- 'attached the frame payload');
- assert.equal(events[0].pts, 1000, 'did not modify the PTS');
- assert.equal(events[0].dts, 1000, 'did not modify the PTS');
- });
- QUnit.test('skips non-ID3 metadata events', function(assert) {
- var events = [];
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 1000,
- // header
- data: new Uint8Array([0])
- });
- assert.equal(events.length, 0, 'did not emit an event');
- });
- // missing cases:
- // unsynchronization
- // CRC
- // no extended header
- // compressed frames
- // encrypted frames
- // frame groups
- // too large/small tag size values
- // too large/small frame size values
- QUnit.test('parses TXXX frames without null terminators', function(assert) {
- var events = [];
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('TXXX',
- 0x03, // utf-8
- stringToCString('get done'),
- stringToInts('{ "key": "value" }')),
- [0x00, 0x00]))
- });
- assert.equal(events.length, 1, 'parsed one tag');
- assert.equal(events[0].frames.length, 1, 'parsed one frame');
- assert.equal(events[0].frames[0].key, 'TXXX', 'parsed the frame key');
- assert.equal(events[0].frames[0].description, 'get done', 'parsed the description');
- assert.deepEqual(JSON.parse(events[0].frames[0].data), { key: 'value' }, 'parsed the data');
- });
- QUnit.test('parses TXXX frames with null terminators', function(assert) {
- var events = [];
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('TXXX',
- 0x03, // utf-8
- stringToCString('get done'),
- stringToCString('{ "key": "value" }')),
- [0x00, 0x00]))
- });
- assert.equal(events.length, 1, 'parsed one tag');
- assert.equal(events[0].frames.length, 1, 'parsed one frame');
- assert.equal(events[0].frames[0].key, 'TXXX', 'parsed the frame key');
- assert.equal(events[0].frames[0].description, 'get done', 'parsed the description');
- assert.deepEqual(JSON.parse(events[0].frames[0].data), { key: 'value' }, 'parsed the data');
- });
- QUnit.test('parses WXXX frames', function(assert) {
- var events = [], url = 'http://example.com/path/file?abc=7&d=4#ty';
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('WXXX',
- 0x03, // utf-8
- stringToCString(''),
- stringToInts(url)),
- [0x00, 0x00]))
- });
- assert.equal(events.length, 1, 'parsed one tag');
- assert.equal(events[0].frames.length, 1, 'parsed one frame');
- assert.equal(events[0].frames[0].key, 'WXXX', 'parsed the frame key');
- assert.equal(events[0].frames[0].description, '', 'parsed the description');
- assert.equal(events[0].frames[0].url, url, 'parsed the value');
- });
- QUnit.test('parses TXXX frames with characters that have a single-digit hexadecimal representation', function(assert) {
- var events = [], value = String.fromCharCode(7);
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('TXXX',
- 0x03, // utf-8
- stringToCString(''),
- stringToCString(value)),
- [0x00, 0x00]))
- });
- assert.equal(events[0].frames[0].data,
- value,
- 'parsed the single-digit character');
- });
- QUnit.test('parses PRIV frames', function(assert) {
- var
- events = [],
- payload = stringToInts('arbitrary data may be included in the payload ' +
- 'of a PRIV frame');
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('PRIV',
- stringToCString('priv-owner@example.com'),
- payload)))
- });
- assert.equal(events.length, 1, 'parsed a tag');
- assert.equal(events[0].frames.length, 1, 'parsed a frame');
- assert.equal(events[0].frames[0].key, 'PRIV', 'frame key is PRIV');
- assert.equal(events[0].frames[0].owner, 'priv-owner@example.com', 'parsed the owner');
- assert.deepEqual(new Uint8Array(events[0].frames[0].data),
- new Uint8Array(payload),
- 'parsed the frame private data');
- });
- QUnit.test('parses tags split across pushes', function(assert) {
- var
- events = [],
- owner = stringToCString('owner@example.com'),
- payload = stringToInts('A TS packet is 188 bytes in length so that it can' +
- ' be easily transmitted over ATM networks, an ' +
- 'important medium at one time. We want to be sure' +
- ' that ID3 frames larger than a TS packet are ' +
- 'properly re-assembled.'),
- tag = new Uint8Array(id3Tag(id3Frame('PRIV', owner, payload))),
- front = tag.subarray(0, 100),
- back = tag.subarray(100);
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: front,
- dataAlignmentIndicator: true
- });
- assert.equal(events.length, 0, 'parsed zero tags');
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: back,
- dataAlignmentIndicator: false
- });
- assert.equal(events.length, 1, 'parsed a tag');
- assert.equal(events[0].frames.length, 1, 'parsed a frame');
- assert.equal(events[0].frames[0].data.byteLength,
- payload.length,
- 'collected data across pushes');
- // parses subsequent fragmented tags
- tag = new Uint8Array(id3Tag(id3Frame('PRIV',
- owner, payload, payload)));
- front = tag.subarray(0, 188);
- back = tag.subarray(188);
- events = [];
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 2000,
- dts: 2000,
- data: front,
- dataAlignmentIndicator: true
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 2000,
- dts: 2000,
- data: back,
- dataAlignmentIndicator: false
- });
- assert.equal(events.length, 1, 'parsed a tag');
- assert.equal(events[0].frames.length, 1, 'parsed a frame');
- assert.equal(events[0].frames[0].data.byteLength,
- 2 * payload.length,
- 'collected data across pushes');
- });
- QUnit.test('id3 frame is malformed first time but gets corrected in the next frame', function(assert) {
- var
- events = [],
- owner = stringToCString('owner@example.com'),
- payload = stringToInts('A TS packet is 188 bytes in length so that it can' +
- ' be easily transmitted over ATM networks, an ' +
- 'important medium at one time. We want to be sure' +
- ' that ID3 frames larger than a TS packet are ' +
- 'properly re-assembled.'),
- tag = new Uint8Array(id3Tag(id3Frame('PRIV', owner, payload))),
- front = tag.subarray(0, 100);
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- // receives incomplete id3
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: front,
- dataAlignmentIndicator: true
- });
- assert.equal(events.length, 0, 'parsed zero tags');
- // receives complete id3
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: tag,
- dataAlignmentIndicator: true
- });
- assert.equal(events.length, 1, 'parsed a tag');
- assert.equal(events[0].frames.length, 1, 'parsed a frame');
- assert.equal(events[0].frames[0].data.byteLength,
- payload.length,
- 'collected data across pushes');
- });
- QUnit.test('id3 frame reports more data than its tagsize ', function(assert) {
- var
- events = [],
- owner = stringToCString('owner@example.com'),
- payload = stringToInts('A TS packet is 188 bytes in length so that it can' +
- ' be easily transmitted over ATM networks, an ' +
- 'important medium at one time. We want to be sure' +
- ' that ID3 frames larger than a TS packet are ' +
- 'properly re-assembled.'),
- tag = new Uint8Array(id3Tag(id3Frame('PRIV', owner, payload))),
- d = new Uint8Array([0x04, 0x05, 0x06]),
- data = new Uint8Array(tag.byteLength + d.byteLength);
- data.set(tag);
- data.set(d, tag.length);
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: data,
- dataAlignmentIndicator: true
- });
- assert.equal(events.length, 1, 'parsed a tag');
- assert.equal(events[0].frames.length, 1, 'parsed a frame');
- assert.equal(events[0].frames[0].data.byteLength,
- payload.length,
- 'collected data across pushes');
- });
- QUnit.test('ignores tags when the header is fragmented', function(assert) {
- var
- events = [],
- tag = new Uint8Array(id3Tag(id3Frame('PRIV',
- stringToCString('owner@example.com'),
- stringToInts('payload')))),
- // split the 10-byte ID3 tag header in half
- front = tag.subarray(0, 5),
- back = tag.subarray(5);
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: front
- });
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- data: back
- });
- assert.equal(events.length, 0, 'parsed zero tags');
- metadataStream.push({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1500,
- dts: 1500,
- data: new Uint8Array(id3Tag(id3Frame('PRIV',
- stringToCString('owner2'),
- stringToInts('payload2'))))
- });
- assert.equal(events.length, 1, 'parsed one tag');
- assert.equal(events[0].frames[0].owner, 'owner2', 'dropped the first tag');
- });
- // https://html.spec.whatwg.org/multipage/embedded-content.html#steps-to-expose-a-media-resource-specific-text-track
- QUnit.test('constructs the dispatch type', function(assert) {
- metadataStream = new mp2t.MetadataStream({
- descriptor: new Uint8Array([0x03, 0x02, 0x01, 0x00])
- });
- assert.equal(metadataStream.dispatchType, '1503020100', 'built the dispatch type');
- });
- QUnit.test('should skip tag frame parsing on malformed frame, preserving previous frames', function(assert) {
- var events = [],
- validFrame = id3Frame('TIT2',
- 0x03, // utf-8
- stringToCString('sample title')),
- malformedFrame = id3Frame('WOAF'), // frame with size of 0B
- tag = id3Tag(validFrame, malformedFrame);
-
- metadataStream.on('data', function(event) {
- events.push(event);
- });
- metadataStream.push({
- type: 'timed-metadata',
- data: new Uint8Array(tag)
- })
-
- assert.equal(events.length, 1, 'parsed 1 tag')
- assert.equal(events[0].frames.length, 1, 'parsed 1 frame');
- assert.equal(events[0].frames[0].key, 'TIT2');
- });
- QUnit.test('can parse APIC frame in web worker', function(assert) {
- var worker = new MetadataStreamTestWorker(),
- done = assert.async();
- worker.addEventListener('message', function(e) {
- assert.equal(e.data.frames[0].key, 'APIC', 'frame key is APIC');
- assert.equal(e.data.frames[0].mimeType, 'image/jpeg', 'parsed MIME type is "image/jpeg"');
- assert.equal(e.data.frames[0].pictureType, 0x03, 'parsed picture type is 0x03');
- assert.equal(e.data.frames[0].description, 'sample description', 'parsed description');
- assert.deepEqual(e.data.frames[0].pictureData, new Uint8Array(stringToInts("picture binary data")), 'parsed picture data');
- assert.equal(e.data.frames[1].key, 'APIC', 'frame key is APIC');
- assert.equal(e.data.frames[1].mimeType, '-->', 'parsed MIME type is "-->"');
- assert.equal(e.data.frames[1].pictureType, 0x04, 'parsed picture type is 0x04');
- assert.equal(e.data.frames[1].description, 'sample description 2', 'parsed description');
- assert.equal(e.data.frames[1].url, 'http://example.org/cover-back.jpg', 'parsed picture data');
- worker.terminate();
- done();
- });
- worker.postMessage({
- type: 'timed-metadata',
- data: new Uint8Array(id3Tag(id3Frame('APIC',
- 0x03, // Text encoding: UTF-8
- stringToCString('image/jpeg'), // MIME type + \0
- 0x03, // Picture type: Cover (front) [ID3v2.4.0 section 4.14]
- stringToCString('sample description'), // Decription + \0
- stringToInts('picture binary data')
- ),
- id3Frame('APIC',
- 0x03, // Text encoding: UTF-8
- stringToCString('-->'), // MIME type: link to the image [ID3v2.4.0 section 4.14] + \0
- 0x04, // Picture type: Cover (back) [ID3v2.4.0 section 4.14]
- stringToCString('sample description 2'), // Decription + \0
- stringToInts('http://example.org/cover-back.jpg')
- )))
- });
- });
- QUnit.test('can parse PRIV frames in web worker', function(assert) {
- var payload = stringToInts('arbitrary'),
- worker = new MetadataStreamTestWorker(),
- done = assert.async();
- worker.addEventListener('message', function(e) {
- assert.equal(e.data.frames[0].key, 'PRIV', 'frame key is PRIV');
- assert.deepEqual(new Uint8Array(e.data.frames[0].data), new Uint8Array(payload),
- 'parsed the frame private data');
- worker.terminate();
- done();
- });
- worker.postMessage({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('PRIV',
- stringToCString('priv-owner@example.com'),
- payload)))
- });
- });
- QUnit.test('can parse TXXX frames in web worker', function(assert) {
- var worker = new MetadataStreamTestWorker(),
- done = assert.async();
- worker.addEventListener('message', function(e) {
- assert.equal(e.data.frames[0].key, 'TXXX', 'frame key is TXXX');
- assert.equal(e.data.frames[0].description, 'get done', 'parsed the description');
- assert.deepEqual(JSON.parse(e.data.frames[0].data), { key: 'value' }, 'parsed the data');
- worker.terminate();
- done();
- });
- worker.postMessage({
- type: 'timed-metadata',
- trackId: 7,
- pts: 1000,
- dts: 900,
- // header
- data: new Uint8Array(id3Tag(id3Frame('TXXX',
- 0x03, // utf-8
- stringToCString('get done'),
- stringToCString('{ "key": "value" }')),
- [0x00, 0x00]))
- });
- });
- QUnit.test('should parse text frames in web worker', function(assert) {
- var worker = new MetadataStreamTestWorker(),
- done = assert.async();
- worker.addEventListener('message', function(e) {
- assert.equal(e.data.frames.length, 2, 'got 2 frames');
- assert.equal(e.data.frames[0].key, 'TIT2', 'frame key is TIT2');
- assert.equal(e.data.frames[0].value, 'sample song title', 'parsed value')
- assert.equal(e.data.frames[0].values.length, 1, 'parsed value is an array of size 1')
- assert.equal(e.data.frames[0].values[0], 'sample song title', 'parsed a non multiple strings value')
- assert.equal(e.data.frames[1].key, 'TIT3', 'frame key is TIT3');
- assert.equal(e.data.frames[1].value, 'sample title 1\0sample title 2', 'parsed value')
- assert.equal(e.data.frames[1].values.length, 2, 'parsed value is an array of size 2')
- assert.equal(e.data.frames[1].values[0], 'sample title 1', 'parsed 1st multiple strings value')
- assert.equal(e.data.frames[1].values[1], 'sample title 2', 'parsed 2nd multiple strings value')
- worker.terminate();
- done();
- });
- worker.postMessage({
- type: 'timed-metadata',
- data: new Uint8Array(id3Tag(id3Frame('TIT2',
- 0x03, // utf-8
- // frames that allow different types of encoding contain terminated text [ID3v2.4.0 section 4.]
- stringToCString('sample song title')),
- id3Frame('TIT3',
- 0x03, // utf-8
- // frames that allow different types of encoding contain terminated text [ID3v2.4.0 section 4.]
- // text information frames supports multiple strings, stored as a terminator separated list [ID3v2.4.0 section 4.2.]
- stringToCString('sample title 1'), stringToCString('sample title 2'))))
- });
- });
- QUnit.test('should parse URL link frames in web worker', function(assert) {
- var worker = new MetadataStreamTestWorker(),
- done = assert.async(),
- payloadBytes;
- // if the payload is followed by a string termination all the following information should be ignored [ID3v2.4.0 section 4.3]
- payloadBytes = stringToInts('http://example.org\0 ignored \0 part')
- worker.addEventListener('message', function(e) {
- assert.equal(e.data.frames[0].key, 'WOAF', 'frame key is WOAF');
- assert.equal(e.data.frames[0].url, 'http://example.org', 'parsed URL')
- worker.terminate();
- done();
- });
- worker.postMessage({
- type: 'timed-metadata',
- data: new Uint8Array(id3Tag(id3Frame('WOAF', payloadBytes)))
- });
- });
- QUnit.test('triggers special event after parsing a timestamp ID3 tag', function(assert) {
- var
- array = new Uint8Array(73),
- streamTimestamp = 'com.apple.streaming.transportStreamTimestamp',
- priv = 'PRIV',
- count = 0,
- frame,
- tag,
- metadataStream,
- chunk,
- i;
- metadataStream = new mp2t.MetadataStream();
- metadataStream.on('timestamp', function(f) {
- frame = f;
- count += 1;
- });
- metadataStream.on('data', function(t) {
- tag = t;
- });
- array[0] = 73;
- array[1] = 68;
- array[2] = 51;
- array[3] = 4;
- array[9] = 63;
- array[17] = 53;
- array[70] = 13;
- array[71] = 187;
- array[72] = 160;
- for (i = 0; i < priv.length; i++) {
- array[i + 10] = priv.charCodeAt(i);
- }
- for (i = 0; i < streamTimestamp.length; i++) {
- array[i + 20] = streamTimestamp.charCodeAt(i);
- }
- chunk = {
- type: 'timed-metadata',
- data: array
- };
- metadataStream.push(chunk);
- assert.equal(count, 1, 'timestamp event triggered once');
- assert.equal(frame.timeStamp, 900000, 'Initial timestamp fired and calculated correctly');
- assert.equal(tag.pts, 10 * 90e3, 'set tag PTS');
- assert.equal(tag.dts, 10 * 90e3, 'set tag DTS');
- });
|