First release
This commit is contained in:
commit
fa6c85266e
2339 changed files with 761050 additions and 0 deletions
5
node_modules/mux.js/test/.eslintrc.json
generated
vendored
Normal file
5
node_modules/mux.js/test/.eslintrc.json
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"env": {
|
||||
"qunit": true
|
||||
}
|
||||
}
|
289
node_modules/mux.js/test/aac-stream.test.js
generated
vendored
Normal file
289
node_modules/mux.js/test/aac-stream.test.js
generated
vendored
Normal file
|
@ -0,0 +1,289 @@
|
|||
'use strict';
|
||||
|
||||
var
|
||||
aacStream,
|
||||
AacStream = require('../lib/aac'),
|
||||
QUnit = require('qunit'),
|
||||
utils = require('./utils'),
|
||||
createId3Header,
|
||||
createId3FrameHeader,
|
||||
createAdtsHeader;
|
||||
|
||||
createId3Header = function(tagSize) {
|
||||
var header = [];
|
||||
|
||||
header[0] = 'I'.charCodeAt(0);
|
||||
header[1] = 'D'.charCodeAt(0);
|
||||
header[2] = '3'.charCodeAt(0);
|
||||
// 2 version bytes, ID3v2.4.0 (major 4, revision 0)
|
||||
header[3] = 4;
|
||||
header[4] = 0;
|
||||
// unsynchronization, extended header, experimental indicator, footer present flags
|
||||
header[5] = 0;
|
||||
// "The ID3v2 tag size is the sum of the byte length of the extended
|
||||
// header, the padding and the frames after unsynchronisation. If a
|
||||
// footer is present this equals to ('total size' - 20) bytes, otherwise
|
||||
// ('total size' - 10) bytes."
|
||||
// http://id3.org/id3v2.4.0-structure
|
||||
header[6] = 0;
|
||||
header[7] = 0;
|
||||
header[8] = 0;
|
||||
header[9] = tagSize;
|
||||
|
||||
return header;
|
||||
};
|
||||
|
||||
createId3FrameHeader = function() {
|
||||
var header = [];
|
||||
|
||||
// four byte frame ID, XYZ are experimental
|
||||
header[0] = 'X'.charCodeAt(0);
|
||||
header[1] = 'Y'.charCodeAt(0);
|
||||
header[2] = 'Z'.charCodeAt(0);
|
||||
header[3] = '0'.charCodeAt(0);
|
||||
// four byte sync safe integer size (excluding frame header)
|
||||
header[4] = 0;
|
||||
header[5] = 0;
|
||||
header[6] = 0;
|
||||
header[7] = 10;
|
||||
// two bytes for flags
|
||||
header[8] = 0;
|
||||
header[9] = 0;
|
||||
|
||||
return header;
|
||||
};
|
||||
|
||||
createAdtsHeader = function(frameLength) {
|
||||
// Header consists of 7 or 9 bytes (without or with CRC).
|
||||
// see: https://wiki.multimedia.cx/index.php/ADTS
|
||||
return utils.binaryStringToArrayOfBytes(''.concat(
|
||||
// 12 bits for syncword (0xFFF)
|
||||
'111111111111',
|
||||
// 1 bit MPEG version
|
||||
'0',
|
||||
// 2 bit layer (always 0)
|
||||
'00',
|
||||
// 1 bit protection absent (1 for no CRC)
|
||||
'1',
|
||||
// 2 bit profile
|
||||
'10',
|
||||
// 4 bit sampling frequency index
|
||||
'0110',
|
||||
// 1 bit private bit
|
||||
'0',
|
||||
// 3 bit channel config
|
||||
'100',
|
||||
// 2 bit (ignore)
|
||||
'00',
|
||||
// 2 bit (copright bits)
|
||||
'00',
|
||||
// 13 bit frame length (includes header length)
|
||||
utils.leftPad(frameLength.toString(2), 13),
|
||||
// 11 bit buffer fullness
|
||||
'11111111111',
|
||||
// 2 bit number of AAC frames minus 1
|
||||
'00'
|
||||
// 16 bit CRC (if present)
|
||||
));
|
||||
};
|
||||
|
||||
QUnit.module('AAC Stream', {
|
||||
beforeEach: function() {
|
||||
aacStream = new AacStream();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('parses ID3 tag', function(assert) {
|
||||
var
|
||||
id3Count = 0,
|
||||
adtsCount = 0,
|
||||
frameHeader = createId3FrameHeader(),
|
||||
id3Tag = createId3Header(frameHeader.length).concat(frameHeader);
|
||||
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.type === 'timed-metadata') {
|
||||
id3Count += 1;
|
||||
} else if (frame.type === 'audio') {
|
||||
adtsCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
aacStream.push(new Uint8Array(id3Tag));
|
||||
|
||||
assert.equal(adtsCount, 0, 'no adts frames');
|
||||
assert.equal(id3Count, 1, 'one id3 chunk');
|
||||
});
|
||||
|
||||
QUnit.test('parses two ID3 tags in sequence', function(assert) {
|
||||
var
|
||||
id3Count = 0,
|
||||
adtsCount = 0,
|
||||
frameHeader = createId3FrameHeader(),
|
||||
id3Tag = createId3Header(frameHeader.length).concat(frameHeader);
|
||||
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.type === 'timed-metadata') {
|
||||
id3Count += 1;
|
||||
} else if (frame.type === 'audio') {
|
||||
adtsCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
aacStream.push(new Uint8Array(id3Tag.concat(id3Tag)));
|
||||
|
||||
assert.equal(adtsCount, 0, 'no adts frames');
|
||||
assert.equal(id3Count, 2, 'two id3 chunks');
|
||||
});
|
||||
|
||||
QUnit.test('does not parse second ID3 tag if it\'s incomplete', function(assert) {
|
||||
var
|
||||
id3Count = 0,
|
||||
adtsCount = 0,
|
||||
frameHeader = createId3FrameHeader(),
|
||||
id3Tag = createId3Header(frameHeader.length).concat(frameHeader);
|
||||
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.type === 'timed-metadata') {
|
||||
id3Count += 1;
|
||||
} else if (frame.type === 'audio') {
|
||||
adtsCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
aacStream.push(new Uint8Array(id3Tag.concat(id3Tag.slice(0, id3Tag.length - 1))));
|
||||
|
||||
assert.equal(adtsCount, 0, 'no adts frames');
|
||||
assert.equal(id3Count, 1, 'one id3 chunk');
|
||||
});
|
||||
|
||||
QUnit.test('handles misaligned adts header', function(assert) {
|
||||
var
|
||||
id3Count = 0,
|
||||
adtsCount = 0,
|
||||
// fake adts frame
|
||||
adtsFrame = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
packetStream = createAdtsHeader(adtsFrame.length).concat(adtsFrame);
|
||||
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.type === 'timed-metadata') {
|
||||
id3Count += 1;
|
||||
} else if (frame.type === 'audio') {
|
||||
adtsCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
// misalign by two bytes specific to a bug related to detecting sync bytes
|
||||
// (where we were only properly checking the second byte)
|
||||
aacStream.push(new Uint8Array([0x01, 0xf0].concat(packetStream)));
|
||||
|
||||
assert.equal(adtsCount, 1, 'one adts frames');
|
||||
assert.equal(id3Count, 0, 'no id3 chunk');
|
||||
});
|
||||
|
||||
QUnit.test('handles incomplete adts frame after id3 frame', function(assert) {
|
||||
var
|
||||
id3Count = 0,
|
||||
adtsCount = 0,
|
||||
id3FrameHeader = createId3FrameHeader(),
|
||||
id3Tag = createId3Header(id3FrameHeader.length).concat(id3FrameHeader),
|
||||
// in this case:
|
||||
// id3 tag = 20 bytes
|
||||
// adts header = 7 bytes
|
||||
// total = 27 bytes
|
||||
// report the ADTS frame size as 20 bytes
|
||||
adtsHeader = createAdtsHeader(20),
|
||||
// no adts frame, stream was cut off
|
||||
packetStream = id3Tag.concat(adtsHeader);
|
||||
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.type === 'timed-metadata') {
|
||||
id3Count += 1;
|
||||
} else if (frame.type === 'audio') {
|
||||
adtsCount += 1;
|
||||
}
|
||||
});
|
||||
|
||||
aacStream.push(new Uint8Array(packetStream));
|
||||
|
||||
assert.equal(adtsCount, 0, 'no adts frame');
|
||||
assert.equal(id3Count, 1, 'one id3 chunk');
|
||||
});
|
||||
|
||||
QUnit.test('emits data after receiving push', function(assert) {
|
||||
var
|
||||
array = new Uint8Array(109),
|
||||
count = 0;
|
||||
|
||||
array[0] = 255;
|
||||
array[1] = 241;
|
||||
array[2] = 92;
|
||||
array[3] = 128;
|
||||
array[4] = 13;
|
||||
array[5] = 191;
|
||||
array[6] = 252;
|
||||
array[7] = 33;
|
||||
array[8] = 32;
|
||||
array[9] = 3;
|
||||
array[10] = 64;
|
||||
array[11] = 104;
|
||||
array[12] = 27;
|
||||
array[13] = 212;
|
||||
aacStream.setTimestamp(90);
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.pts === 90 && frame.dts === 90) {
|
||||
count += 1;
|
||||
}
|
||||
});
|
||||
aacStream.push(array);
|
||||
assert.equal(count, 1);
|
||||
});
|
||||
|
||||
QUnit.test('continues parsing after corrupted stream', function(assert) {
|
||||
var
|
||||
array = new Uint8Array(10000),
|
||||
adtsCount = 0,
|
||||
id3Count = 0;
|
||||
|
||||
// an ID3 frame
|
||||
array[0] = 73;
|
||||
array[1] = 68;
|
||||
array[2] = 51;
|
||||
array[3] = 4;
|
||||
array[4] = 0;
|
||||
array[5] = 0;
|
||||
array[6] = 0;
|
||||
array[7] = 0;
|
||||
array[8] = 0;
|
||||
array[9] = 63;
|
||||
array[10] = 80;
|
||||
array[11] = 82;
|
||||
array[12] = 73;
|
||||
array[13] = 86;
|
||||
|
||||
// an atds frame
|
||||
array[1020] = 255;
|
||||
array[1021] = 241;
|
||||
array[1022] = 92;
|
||||
array[1023] = 128;
|
||||
array[1024] = 13;
|
||||
array[1025] = 191;
|
||||
array[1026] = 252;
|
||||
array[1027] = 33;
|
||||
array[1028] = 32;
|
||||
array[1029] = 3;
|
||||
array[1030] = 64;
|
||||
array[1031] = 104;
|
||||
array[1032] = 27;
|
||||
array[1033] = 212;
|
||||
|
||||
aacStream.on('data', function(frame) {
|
||||
if (frame.type === 'timed-metadata') {
|
||||
id3Count += 1;
|
||||
} else if (frame.type === 'audio') {
|
||||
adtsCount += 1;
|
||||
}
|
||||
});
|
||||
aacStream.push(array);
|
||||
assert.equal(adtsCount, 1);
|
||||
assert.equal(id3Count, 1);
|
||||
});
|
89
node_modules/mux.js/test/aac-utils.test.js
generated
vendored
Normal file
89
node_modules/mux.js/test/aac-utils.test.js
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
'use strict';
|
||||
|
||||
var segments = require('data-files!segments');
|
||||
|
||||
var
|
||||
QUnit = require('qunit'),
|
||||
utils = require('../lib/aac/utils.js'),
|
||||
testSegment = segments['test-aac-segment.aac']();
|
||||
|
||||
var id3TagOffset = 0;
|
||||
var audioFrameOffset = 73;
|
||||
|
||||
|
||||
QUnit.module('AAC Utils');
|
||||
|
||||
QUnit.test('correctly determines aac data', function(assert) {
|
||||
assert.ok(utils.isLikelyAacData(testSegment), 'test segment is aac');
|
||||
|
||||
|
||||
var id3Offset = utils.parseId3TagSize(testSegment, 0);
|
||||
var id3 = Array.prototype.slice.call(testSegment, 0, id3Offset);
|
||||
var segmentOnly = testSegment.subarray(id3Offset);
|
||||
var multipleId3 = new Uint8Array([]
|
||||
.concat(id3)
|
||||
.concat(id3)
|
||||
.concat(id3)
|
||||
.concat(id3)
|
||||
.concat(Array.prototype.slice.call(segmentOnly))
|
||||
);
|
||||
|
||||
assert.ok(utils.isLikelyAacData(segmentOnly), 'test segment is aac without id3');
|
||||
assert.notOk(utils.isLikelyAacData(testSegment.subarray(id3Offset + 25)), 'non aac data not recognized');
|
||||
assert.notOk(utils.isLikelyAacData(testSegment.subarray(0, 5)), 'not enough aac data is not recognized');
|
||||
assert.ok(utils.isLikelyAacData(multipleId3), 'test segment with multilpe id3');
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('correctly parses aac packet type', function(assert) {
|
||||
assert.equal(utils.parseType(testSegment, id3TagOffset), 'timed-metadata',
|
||||
'parsed timed-metadata type');
|
||||
assert.equal(utils.parseType(testSegment, 1), null,
|
||||
'parsed unknown type');
|
||||
assert.equal(utils.parseType(testSegment, audioFrameOffset), 'audio',
|
||||
'parsed audio type');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses ID3 tag size', function(assert) {
|
||||
assert.equal(utils.parseId3TagSize(testSegment, id3TagOffset), 73,
|
||||
'correct id3 tag size');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses timestamp from ID3 metadata', function(assert) {
|
||||
var frameSize = utils.parseId3TagSize(testSegment, id3TagOffset);
|
||||
var frame = testSegment.subarray(id3TagOffset, id3TagOffset + frameSize);
|
||||
|
||||
assert.equal(utils.parseAacTimestamp(frame), 895690, 'correct aac timestamp');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses adts frame size', function(assert) {
|
||||
assert.equal(utils.parseAdtsSize(testSegment, audioFrameOffset), 13,
|
||||
'correct adts frame size');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses packet sample rate', function(assert) {
|
||||
var frameSize = utils.parseAdtsSize(testSegment, audioFrameOffset);
|
||||
var frame = testSegment.subarray(audioFrameOffset, audioFrameOffset + frameSize);
|
||||
|
||||
assert.equal(utils.parseSampleRate(frame), 44100, 'correct sample rate');
|
||||
});
|
||||
|
||||
QUnit.test('parses correct ID3 tag size', function(assert) {
|
||||
var packetStream = new Uint8Array(10);
|
||||
|
||||
packetStream[9] = 63;
|
||||
|
||||
assert.equal(utils.parseId3TagSize(packetStream, 0),
|
||||
73,
|
||||
'correctly parsed a header without a footer');
|
||||
});
|
||||
|
||||
QUnit.test('parses correct ADTS Frame size', function(assert) {
|
||||
var packetStream = new Uint8Array(6);
|
||||
|
||||
packetStream[3] = 128;
|
||||
packetStream[4] = 29;
|
||||
packetStream[5] = 255;
|
||||
|
||||
assert.equal(utils.parseAdtsSize(packetStream, 0), 239, 'correctly parsed framesize');
|
||||
});
|
17
node_modules/mux.js/test/base64-to-uint8-array.js
generated
vendored
Normal file
17
node_modules/mux.js/test/base64-to-uint8-array.js
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
var window = require('global/window');
|
||||
// TODO: use vhs-utils here
|
||||
|
||||
var atob = (s) => window.atob ? window.atob(s) : Buffer.from(s, 'base64').toString('binary');
|
||||
|
||||
var base64ToUint8Array = function(base64) {
|
||||
var decoded = atob(base64);
|
||||
var uint8Array = new Uint8Array(new ArrayBuffer(decoded.length));
|
||||
|
||||
for (var i = 0; i < decoded.length; i++) {
|
||||
uint8Array[i] = decoded.charCodeAt(i);
|
||||
}
|
||||
|
||||
return uint8Array;
|
||||
};
|
||||
|
||||
module.exports = base64ToUint8Array;
|
253
node_modules/mux.js/test/caption-parser.test.js
generated
vendored
Normal file
253
node_modules/mux.js/test/caption-parser.test.js
generated
vendored
Normal file
|
@ -0,0 +1,253 @@
|
|||
'use strict';
|
||||
|
||||
var segments = require('data-files!segments');
|
||||
|
||||
var probe = require('../lib/mp4/probe');
|
||||
var CaptionParser = require('../lib/mp4').CaptionParser;
|
||||
var captionParser;
|
||||
|
||||
var dashInit = segments['dash-608-captions-init.mp4']();
|
||||
// This file includes 2 segments data to force a flush
|
||||
// of the first caption. The second caption is at 200s
|
||||
var dashSegment = segments['dash-608-captions-seg.m4s']();
|
||||
|
||||
var mp4Helpers = require('./utils/mp4-helpers');
|
||||
var box = mp4Helpers.box;
|
||||
var seiNalUnitGenerator = require('./utils/sei-nal-unit-generator');
|
||||
var makeMdatFromCaptionPackets = seiNalUnitGenerator.makeMdatFromCaptionPackets;
|
||||
var characters = seiNalUnitGenerator.characters;
|
||||
|
||||
var packets0;
|
||||
var version0Moof;
|
||||
var version0Segment;
|
||||
|
||||
var packets1;
|
||||
var version1Moof;
|
||||
var version1Segment;
|
||||
|
||||
QUnit.module('MP4 Caption Parser', {
|
||||
beforeEach: function() {
|
||||
captionParser = new CaptionParser();
|
||||
captionParser.init();
|
||||
},
|
||||
|
||||
afterEach: function() {
|
||||
captionParser.reset();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('parse captions from real segment', function(assert) {
|
||||
var trackIds;
|
||||
var timescales;
|
||||
var cc;
|
||||
|
||||
trackIds = probe.videoTrackIds(dashInit);
|
||||
timescales = probe.timescale(dashInit);
|
||||
|
||||
cc = captionParser.parse(dashSegment, trackIds, timescales);
|
||||
|
||||
assert.equal(cc.captions.length, 1);
|
||||
assert.equal(cc.captions[0].text, '00:00:00',
|
||||
'real segment caption has correct text');
|
||||
assert.equal(cc.captions[0].stream, 'CC1',
|
||||
'real segment caption has correct stream');
|
||||
assert.equal(cc.captions[0].startTime, 0,
|
||||
'real segment caption has correct startTime');
|
||||
assert.equal(cc.captions[0].endTime, 119,
|
||||
'real segment caption has correct endTime');
|
||||
assert.equal(cc.captionStreams.CC1, true,
|
||||
'real segment caption streams have correct settings');
|
||||
});
|
||||
|
||||
QUnit.test('parse captions when init segment received late', function(assert) {
|
||||
var trackIds;
|
||||
var timescales;
|
||||
var cc;
|
||||
|
||||
trackIds = probe.videoTrackIds(dashInit);
|
||||
timescales = probe.timescale(dashInit);
|
||||
|
||||
cc = captionParser.parse(dashSegment, [], {});
|
||||
assert.ok(!cc, 'there should not be any parsed captions yet');
|
||||
|
||||
cc = captionParser.parse(dashSegment, trackIds, timescales);
|
||||
assert.equal(cc.captions.length, 1);
|
||||
});
|
||||
|
||||
QUnit.test('parseTrackId for version 0 and version 1 boxes', function(assert) {
|
||||
var v0Captions;
|
||||
var v1Captions;
|
||||
|
||||
v0Captions = captionParser.parse(
|
||||
new Uint8Array(version0Segment), // segment
|
||||
[1], // trackIds
|
||||
{ 1: 90000 }); // timescales);
|
||||
|
||||
assert.equal(v0Captions.captions.length, 1, 'got 1 version0 caption');
|
||||
assert.equal(v0Captions.captions[0].text, 'test string #1',
|
||||
'got the expected version0 caption text');
|
||||
assert.equal(v0Captions.captions[0].stream, 'CC1',
|
||||
'returned the correct caption stream CC1');
|
||||
assert.equal(v0Captions.captions[0].startTime, 10 / 90000,
|
||||
'the start time for version0 caption is correct');
|
||||
assert.equal(v0Captions.captions[0].endTime, 10 / 90000,
|
||||
'the end time for version0 caption is correct');
|
||||
assert.equal(v0Captions.captionStreams.CC1, true,
|
||||
'stream is CC1');
|
||||
assert.ok(!v0Captions.captionStreams.CC4,
|
||||
'stream is not CC4');
|
||||
|
||||
// Clear parsed captions
|
||||
captionParser.clearParsedCaptions();
|
||||
|
||||
v1Captions = captionParser.parse(
|
||||
new Uint8Array(version1Segment),
|
||||
[2], // trackIds
|
||||
{ 2: 90000 }); // timescales
|
||||
|
||||
assert.equal(v1Captions.captions.length, 1, 'got version1 caption');
|
||||
assert.equal(v1Captions.captions[0].text, 'test string #2',
|
||||
'got the expected version1 caption text');
|
||||
assert.equal(v1Captions.captions[0].stream, 'CC4',
|
||||
'returned the correct caption stream CC4');
|
||||
assert.equal(v1Captions.captions[0].startTime, 30 / 90000,
|
||||
'the start time for version1 caption is correct');
|
||||
assert.equal(v1Captions.captions[0].endTime, 30 / 90000,
|
||||
'the end time for version1 caption is correct');
|
||||
assert.equal(v1Captions.captionStreams.CC4, true,
|
||||
'stream is CC4');
|
||||
assert.ok(!v1Captions.captionStreams.CC1,
|
||||
'stream is not CC1');
|
||||
});
|
||||
|
||||
// ---------
|
||||
// Test Data
|
||||
// ---------
|
||||
|
||||
// "test string #1", channel 1, field 1
|
||||
packets0 = [
|
||||
// Send another command so that the second EOC isn't ignored
|
||||
{ ccData: 0x1420, type: 0 },
|
||||
// RCL, resume caption loading
|
||||
{ ccData: 0x1420, type: 0 },
|
||||
// 'test string #1'
|
||||
{ ccData: characters('te'), type: 0 },
|
||||
{ ccData: characters('st'), type: 0 },
|
||||
{ ccData: characters(' s'), type: 0 },
|
||||
// 'test string #1' continued
|
||||
{ ccData: characters('tr'), type: 0 },
|
||||
{ ccData: characters('in'), type: 0 },
|
||||
{ ccData: characters('g '), type: 0 },
|
||||
{ ccData: characters('#1'), type: 0 },
|
||||
// EOC, End of Caption. End display
|
||||
{ ccData: 0x142f, type: 0 },
|
||||
// EOC, End of Caption. Finished transmitting, begin display
|
||||
{ ccData: 0x142f, type: 0 },
|
||||
// Send another command so that the second EOC isn't ignored
|
||||
{ ccData: 0x1420, type: 0 },
|
||||
// EOC, End of Caption. End display
|
||||
{ ccData: 0x142f, type: 0 }
|
||||
];
|
||||
|
||||
// "test string #2", channel 2, field 2
|
||||
packets1 = [
|
||||
// Send another command so that the second EOC isn't ignored
|
||||
{ ccData: 0x1d20, type: 1 },
|
||||
// RCL, resume caption loading
|
||||
{ ccData: 0x1d20, type: 1 },
|
||||
// 'test string #2'
|
||||
{ ccData: characters('te'), type: 1 },
|
||||
{ ccData: characters('st'), type: 1 },
|
||||
{ ccData: characters(' s'), type: 1 },
|
||||
// 'test string #2' continued
|
||||
{ ccData: characters('tr'), type: 1 },
|
||||
{ ccData: characters('in'), type: 1 },
|
||||
{ ccData: characters('g '), type: 1 },
|
||||
{ ccData: characters('#2'), type: 1 },
|
||||
// EOC, End of Caption. End display
|
||||
{ ccData: 0x1d2f, type: 1 },
|
||||
// EOC, End of Caption. Finished transmitting, begin display
|
||||
{ ccData: 0x1d2f, type: 1 },
|
||||
// Send another command so that the second EOC isn't ignored
|
||||
{ ccData: 0x1d20, type: 1 },
|
||||
// EOC, End of Caption. End display
|
||||
{ ccData: 0x1d2f, type: 1 }
|
||||
];
|
||||
|
||||
/**
|
||||
* version 0:
|
||||
* Uses version 0 boxes, no first sample flags
|
||||
* sample size, flags, duration, composition time offset included.
|
||||
**/
|
||||
version0Moof =
|
||||
box('moof',
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // track_ID
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x00, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x00, // default_sample_duration
|
||||
0x00, 0x00, 0x00, 0x00, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x00), // default_sample_flags
|
||||
box('tfdt',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00), // baseMediaDecodeTime,
|
||||
box('trun',
|
||||
0x00, // version
|
||||
0x00, 0x0f, 0x01, // flags: dataOffsetPresent, sampleDurationPresent,
|
||||
// sampleSizePresent, sampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x02, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00, // data_offset, no first_sample_flags
|
||||
// sample 1
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x0a, // signed sample_composition_time_offset = 10
|
||||
// sample 2
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x14))); // signed sample_composition_time_offset = 20
|
||||
|
||||
version0Segment = version0Moof.concat(makeMdatFromCaptionPackets(packets0));
|
||||
|
||||
/**
|
||||
* version 1:
|
||||
* Uses version 1 boxes, has first sample flags,
|
||||
* other samples include flags and composition time offset only.
|
||||
**/
|
||||
version1Moof =
|
||||
box('moof',
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x01, // version
|
||||
0x00, 0x00, 0x18, // flags
|
||||
0x00, 0x00, 0x00, 0x02, // track_ID
|
||||
// no base_data_offset, sample_description_index
|
||||
0x00, 0x00, 0x00, 0x0a, // default_sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a), // default_sample_size = 10
|
||||
box('tfdt',
|
||||
0x01, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x14), // baseMediaDecodeTime = 20,
|
||||
box('trun',
|
||||
0x01, // version
|
||||
0x00, 0x0c, 0x05, // flags: dataOffsetPresent, sampleFlagsPresent,
|
||||
// firstSampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x02, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00, // data_offset, has first_sample_flags
|
||||
// sample 1
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x0a, // signed sample_composition_time_offset = 10
|
||||
// sample 2
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x14))); // signed sample_composition_time_offset = 20
|
||||
|
||||
version1Segment = version1Moof.concat(makeMdatFromCaptionPackets(packets1));
|
3008
node_modules/mux.js/test/caption-stream.test.js
generated
vendored
Normal file
3008
node_modules/mux.js/test/caption-stream.test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1114
node_modules/mux.js/test/captions.dfxp
generated
vendored
Normal file
1114
node_modules/mux.js/test/captions.dfxp
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
113
node_modules/mux.js/test/exp-golomb.test.js
generated
vendored
Normal file
113
node_modules/mux.js/test/exp-golomb.test.js
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
======== 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:
|
||||
assert.ok(value, [message])
|
||||
assert.equal(actual, expected, [message])
|
||||
assert.notEqual(actual, expected, [message])
|
||||
assert.deepEqual(actual, expected, [message])
|
||||
assert.notDeepEqual(actual, expected, [message])
|
||||
assert.strictEqual(actual, expected, [message])
|
||||
assert.notStrictEqual(actual, expected, [message])
|
||||
assert.throws(block, [expected], [message])
|
||||
*/
|
||||
var
|
||||
buffer,
|
||||
ExpGolomb = require('../lib/utils/exp-golomb'),
|
||||
expGolomb;
|
||||
|
||||
QUnit.module('Exponential Golomb coding');
|
||||
|
||||
QUnit.test('small numbers are coded correctly', function(assert) {
|
||||
var
|
||||
expected = [
|
||||
[0xF8, 0],
|
||||
[0x5F, 1],
|
||||
[0x7F, 2],
|
||||
[0x27, 3],
|
||||
[0x2F, 4],
|
||||
[0x37, 5],
|
||||
[0x3F, 6],
|
||||
[0x11, 7],
|
||||
[0x13, 8],
|
||||
[0x15, 9]
|
||||
],
|
||||
i = expected.length,
|
||||
result;
|
||||
|
||||
while (i--) {
|
||||
buffer = new Uint8Array([expected[i][0]]);
|
||||
expGolomb = new ExpGolomb(buffer);
|
||||
result = expGolomb.readUnsignedExpGolomb();
|
||||
assert.equal(expected[i][1], result, expected[i][0] + ' is decoded to ' + expected[i][1]);
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('drops working data as it is parsed', function(assert) {
|
||||
var expGolomb = new ExpGolomb(new Uint8Array([0x00, 0xFF]));
|
||||
expGolomb.skipBits(8);
|
||||
assert.equal(8, expGolomb.bitsAvailable(), '8 bits remain');
|
||||
assert.equal(0xFF, expGolomb.readBits(8), 'the second byte is read');
|
||||
});
|
||||
|
||||
QUnit.test('drops working data when skipping leading zeros', function(assert) {
|
||||
var expGolomb = new ExpGolomb(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0xFF]));
|
||||
assert.equal(32, expGolomb.skipLeadingZeros(), '32 leading zeros are dropped');
|
||||
assert.equal(8, expGolomb.bitsAvailable(), '8 bits remain');
|
||||
assert.equal(0xFF, expGolomb.readBits(8), 'the second byte is read');
|
||||
});
|
||||
|
||||
QUnit.test('drops working data when skipping leading zeros', function(assert) {
|
||||
var expGolomb = new ExpGolomb(new Uint8Array([0x15, 0xab, 0x40, 0xc8, 0xFF]));
|
||||
assert.equal(3, expGolomb.skipLeadingZeros(), '3 leading zeros are dropped');
|
||||
assert.equal((8 * 4) + 5, expGolomb.bitsAvailable(), '37 bits remain');
|
||||
expGolomb.skipBits(1);
|
||||
assert.equal(0x5a, expGolomb.readBits(8), 'the next bits are read');
|
||||
});
|
||||
|
||||
QUnit.test('skipBits correctly across word-boundaries', function(assert) {
|
||||
var expGolomb = new ExpGolomb(new Uint8Array([0x15, 0x00, 0x00, 0x28, 0x00, 0x0a, 0x00, 0x00]));
|
||||
assert.equal(expGolomb.readUnsignedExpGolomb(), 9, 'the first number is read');
|
||||
expGolomb.skipBits(17);
|
||||
assert.equal(expGolomb.readUnsignedExpGolomb(), 4, 'the second number is read');
|
||||
expGolomb.skipBits(13); // Crosses word boundary
|
||||
assert.equal(expGolomb.readUnsignedExpGolomb(), 4, 'the third number is read');
|
||||
});
|
||||
|
||||
QUnit.test('parses a sequence parameter set', function(assert) {
|
||||
var
|
||||
sps = new Uint8Array([
|
||||
0x27, 0x42, 0xe0, 0x0b,
|
||||
0xa9, 0x18, 0x60, 0x9d,
|
||||
0x80, 0x35, 0x06, 0x01,
|
||||
0x06, 0xb6, 0xc2, 0xb5,
|
||||
0xef, 0x7c, 0x04
|
||||
]),
|
||||
expGolomb = new ExpGolomb(sps);
|
||||
|
||||
assert.strictEqual(expGolomb.readBits(8), 0x27, 'the NAL type specifies an SPS');
|
||||
assert.strictEqual(expGolomb.readBits(8), 66, 'profile_idc is 66');
|
||||
assert.strictEqual(expGolomb.readBits(4), 0x0E, 'constraints 0-3 are correct');
|
||||
|
||||
expGolomb.skipBits(4);
|
||||
assert.strictEqual(expGolomb.readBits(8), 11, 'level_idc is 11');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 0, 'seq_parameter_set_id is 0');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 1, 'log2_max_frame_num_minus4 is 1');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 0, 'pic_order_cnt_type is 0');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 3, 'log2_max_pic_order_cnt_lsb_minus4 is 3');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 2, 'max_num_ref_frames is 2');
|
||||
assert.strictEqual(expGolomb.readBits(1), 0, 'gaps_in_frame_num_value_allowed_flag is false');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 11, 'pic_width_in_mbs_minus1 is 11');
|
||||
assert.strictEqual(expGolomb.readUnsignedExpGolomb(), 8, 'pic_height_in_map_units_minus1 is 8');
|
||||
assert.strictEqual(expGolomb.readBits(1), 1, 'frame_mbs_only_flag is true');
|
||||
assert.strictEqual(expGolomb.readBits(1), 1, 'direct_8x8_inference_flag is true');
|
||||
assert.strictEqual(expGolomb.readBits(1), 0, 'frame_cropping_flag is false');
|
||||
});
|
||||
|
75
node_modules/mux.js/test/m2ts-probe.test.js
generated
vendored
Normal file
75
node_modules/mux.js/test/m2ts-probe.test.js
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
'use strict';
|
||||
|
||||
var segments = require('data-files!segments');
|
||||
|
||||
var
|
||||
QUnit = require('qunit'),
|
||||
probe = require('../lib/m2ts/probe.js'),
|
||||
testSegment = segments['test-segment.ts'](),
|
||||
stuffedPesPacket = segments['test-stuffed-pes.ts']();
|
||||
|
||||
/**
|
||||
* All subarray indices verified with the use of thumbcoil.
|
||||
*/
|
||||
var patPacket = testSegment.subarray(188, 376);
|
||||
var pmtPid = 4095;
|
||||
var programMapTable = {
|
||||
256: 0x1B,
|
||||
257: 0x0F
|
||||
};
|
||||
var pmtPacket = testSegment.subarray(376, 564);
|
||||
var pesPacket = testSegment.subarray(564, 752);
|
||||
var videoPacket = testSegment.subarray(564, 1692);
|
||||
var videoNoKeyFramePacket = testSegment.subarray(1880, 2820);
|
||||
var audioPacket = testSegment.subarray(6956, 7144);
|
||||
var notPusiPacket = testSegment.subarray(1316, 1504);
|
||||
|
||||
QUnit.module('M2TS Probe');
|
||||
|
||||
QUnit.test('correctly parses packet type', function(assert) {
|
||||
assert.equal(probe.parseType(patPacket), 'pat', 'parses pat type');
|
||||
assert.equal(probe.parseType(pmtPacket), null,
|
||||
'cannot determine type of pmt packet when pmt pid has not been parsed yet');
|
||||
assert.equal(probe.parseType(pmtPacket, pmtPid), 'pmt', 'parses pmt type');
|
||||
assert.equal(probe.parseType(pesPacket), null,
|
||||
'cannot determine type of pes packet when pmt pid has not been parsed yet');
|
||||
assert.equal(probe.parseType(pesPacket, pmtPid), 'pes', 'parses pes type');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses pmt pid from pat packet', function(assert) {
|
||||
assert.equal(probe.parsePat(patPacket), pmtPid, 'parses pmt pid from pat');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses program map table from pmt packet', function(assert) {
|
||||
assert.deepEqual(probe.parsePmt(pmtPacket), programMapTable, 'generates correct pmt');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses payload unit start indicator', function(assert) {
|
||||
assert.ok(probe.parsePayloadUnitStartIndicator(pesPacket),
|
||||
'detects payload unit start indicator');
|
||||
assert.ok(!probe.parsePayloadUnitStartIndicator(notPusiPacket),
|
||||
'detects no payload unit start indicator');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses type of pes packet', function(assert) {
|
||||
assert.equal(probe.parsePesType(videoPacket, programMapTable), 'video',
|
||||
'parses video pes type');
|
||||
assert.equal(probe.parsePesType(audioPacket, programMapTable), 'audio',
|
||||
'parses audio pes type');
|
||||
});
|
||||
|
||||
QUnit.test('correctly parses dts and pts values of pes packet', function(assert) {
|
||||
var videoPes = probe.parsePesTime(videoPacket);
|
||||
assert.equal(videoPes.dts, 126000, 'correct dts value');
|
||||
assert.equal(videoPes.pts, 126000, 'correct pts value');
|
||||
|
||||
videoPes = probe.parsePesTime(stuffedPesPacket);
|
||||
assert.equal(videoPes, null,
|
||||
'correctly returned null when there is no packet data, only stuffing');
|
||||
});
|
||||
|
||||
QUnit.test('correctly determines if video pes packet contains a key frame', function(assert) {
|
||||
assert.ok(probe.videoPacketContainsKeyFrame(videoPacket), 'detects key frame in packet');
|
||||
assert.ok(!probe.videoPacketContainsKeyFrame(videoNoKeyFramePacket),
|
||||
'detects no key frame in packet');
|
||||
});
|
11
node_modules/mux.js/test/metadata-stream-test-worker.js
generated
vendored
Normal file
11
node_modules/mux.js/test/metadata-stream-test-worker.js
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
var mp2t, metadataStream;
|
||||
|
||||
mp2t = require('../lib/m2ts');
|
||||
metadataStream = new mp2t.MetadataStream();
|
||||
|
||||
self.addEventListener('message', function(e) {
|
||||
metadataStream.on('data', function(data) {
|
||||
self.postMessage(data);
|
||||
});
|
||||
metadataStream.push(e.data);
|
||||
});
|
586
node_modules/mux.js/test/metadata-stream.test.js
generated
vendored
Normal file
586
node_modules/mux.js/test/metadata-stream.test.js
generated
vendored
Normal file
|
@ -0,0 +1,586 @@
|
|||
'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('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('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('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');
|
||||
});
|
581
node_modules/mux.js/test/mp4-generator.test.js
generated
vendored
Normal file
581
node_modules/mux.js/test/mp4-generator.test.js
generated
vendored
Normal file
|
@ -0,0 +1,581 @@
|
|||
'use strict';
|
||||
/*
|
||||
======== A Handy Little QUnit Reference ========
|
||||
http://api.qunitjs.com/
|
||||
|
||||
Test methods:
|
||||
module(name, {[setup][ ,teardown]})
|
||||
QUnit.test(name, callback)
|
||||
expect(numberOfAssertions)
|
||||
stop(increment)
|
||||
start(decrement)
|
||||
Test assertions:
|
||||
assert.ok(value, [message])
|
||||
assert.equal(actual, expected, [message])
|
||||
notEqual(actual, expected, [message])
|
||||
assert.deepEqual(actual, expected, [message])
|
||||
notDeepEqual(actual, expected, [message])
|
||||
assert.strictEqual(actual, expected, [message])
|
||||
notStrictEqual(actual, expected, [message])
|
||||
throws(block, [expected], [message])
|
||||
*/
|
||||
var
|
||||
mp4 = require('../lib/mp4'),
|
||||
QUnit = require('qunit'),
|
||||
validateMvhd, validateTrak, validateTkhd, validateMdia,
|
||||
validateMdhd, validateHdlr, validateMinf, validateDinf,
|
||||
validateStbl, validateStsd, validateMvex,
|
||||
validateVideoSample, validateAudioSample;
|
||||
|
||||
QUnit.module('MP4 Generator');
|
||||
|
||||
QUnit.test('generates a BSMFF ftyp', function(assert) {
|
||||
var data = mp4.generator.ftyp(), boxes;
|
||||
|
||||
assert.ok(data, 'box is not null');
|
||||
|
||||
boxes = mp4.tools.inspect(data);
|
||||
assert.equal(1, boxes.length, 'generated a single box');
|
||||
assert.equal(boxes[0].type, 'ftyp', 'generated ftyp type');
|
||||
assert.equal(boxes[0].size, data.byteLength, 'generated size');
|
||||
assert.equal(boxes[0].majorBrand, 'isom', 'major version is "isom"');
|
||||
assert.equal(boxes[0].minorVersion, 1, 'minor version is one');
|
||||
});
|
||||
|
||||
validateMvhd = function(mvhd) {
|
||||
QUnit.assert.equal(mvhd.type, 'mvhd', 'generated a mvhd');
|
||||
QUnit.assert.equal(mvhd.duration, 0xffffffff, 'wrote the maximum movie header duration');
|
||||
QUnit.assert.equal(mvhd.nextTrackId, 0xffffffff, 'wrote the max next track id');
|
||||
};
|
||||
|
||||
validateTrak = function(trak, expected) {
|
||||
expected = expected || {};
|
||||
QUnit.assert.equal(trak.type, 'trak', 'generated a trak');
|
||||
QUnit.assert.equal(trak.boxes.length, 2, 'generated two track sub boxes');
|
||||
|
||||
validateTkhd(trak.boxes[0], expected);
|
||||
validateMdia(trak.boxes[1], expected);
|
||||
};
|
||||
|
||||
validateTkhd = function(tkhd, expected) {
|
||||
QUnit.assert.equal(tkhd.type, 'tkhd', 'generated a tkhd');
|
||||
QUnit.assert.equal(tkhd.trackId, 7, 'wrote the track id');
|
||||
QUnit.assert.deepEqual(tkhd.flags, new Uint8Array([0, 0, 7]), 'flags should QUnit.equal 7');
|
||||
QUnit.assert.equal(tkhd.duration,
|
||||
expected.duration || Math.pow(2, 32) - 1,
|
||||
'wrote duration into the track header');
|
||||
QUnit.assert.equal(tkhd.width, expected.width || 0, 'wrote width into the track header');
|
||||
QUnit.assert.equal(tkhd.height, expected.height || 0, 'wrote height into the track header');
|
||||
QUnit.assert.equal(tkhd.volume, 1, 'set volume to 1');
|
||||
};
|
||||
|
||||
validateMdia = function(mdia, expected) {
|
||||
QUnit.assert.equal(mdia.type, 'mdia', 'generated an mdia type');
|
||||
QUnit.assert.equal(mdia.boxes.length, 3, 'generated three track media sub boxes');
|
||||
|
||||
validateMdhd(mdia.boxes[0], expected);
|
||||
validateHdlr(mdia.boxes[1], expected);
|
||||
validateMinf(mdia.boxes[2], expected);
|
||||
};
|
||||
|
||||
validateMdhd = function(mdhd, expected) {
|
||||
QUnit.assert.equal(mdhd.type, 'mdhd', 'generate an mdhd type');
|
||||
QUnit.assert.equal(mdhd.language, 'und', 'wrote undetermined language');
|
||||
QUnit.assert.equal(mdhd.timescale, expected.timescale || 90000, 'wrote the timescale');
|
||||
QUnit.assert.equal(mdhd.duration,
|
||||
expected.duration || Math.pow(2, 32) - 1,
|
||||
'wrote duration into the media header');
|
||||
};
|
||||
|
||||
validateHdlr = function(hdlr, expected) {
|
||||
QUnit.assert.equal(hdlr.type, 'hdlr', 'generate an hdlr type');
|
||||
if (expected.type !== 'audio') {
|
||||
QUnit.assert.equal(hdlr.handlerType, 'vide', 'wrote a video handler');
|
||||
QUnit.assert.equal(hdlr.name, 'VideoHandler', 'wrote the handler name');
|
||||
} else {
|
||||
QUnit.assert.equal(hdlr.handlerType, 'soun', 'wrote a sound handler');
|
||||
QUnit.assert.equal(hdlr.name, 'SoundHandler', 'wrote the sound handler name');
|
||||
}
|
||||
};
|
||||
|
||||
validateMinf = function(minf, expected) {
|
||||
QUnit.assert.equal(minf.type, 'minf', 'generate an minf type');
|
||||
QUnit.assert.equal(minf.boxes.length, 3, 'generates three minf sub boxes');
|
||||
|
||||
if (expected.type !== 'audio') {
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'vmhd',
|
||||
size: 20,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 1]),
|
||||
graphicsmode: 0,
|
||||
opcolor: new Uint16Array([0, 0, 0])
|
||||
}, minf.boxes[0], 'generates a vhmd');
|
||||
} else {
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'smhd',
|
||||
size: 16,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
balance: 0
|
||||
}, minf.boxes[0], 'generates an smhd');
|
||||
}
|
||||
|
||||
validateDinf(minf.boxes[1]);
|
||||
validateStbl(minf.boxes[2], expected);
|
||||
};
|
||||
|
||||
validateDinf = function(dinf) {
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'dinf',
|
||||
size: 36,
|
||||
boxes: [{
|
||||
type: 'dref',
|
||||
size: 28,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
dataReferences: [{
|
||||
type: 'url ',
|
||||
size: 12,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 1])
|
||||
}]
|
||||
}]
|
||||
}, dinf, 'generates a dinf');
|
||||
};
|
||||
|
||||
validateStbl = function(stbl, expected) {
|
||||
QUnit.assert.equal(stbl.type, 'stbl', 'generates an stbl type');
|
||||
QUnit.assert.equal(stbl.boxes.length, 5, 'generated five stbl child boxes');
|
||||
|
||||
validateStsd(stbl.boxes[0], expected);
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'stts',
|
||||
size: 16,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
timeToSamples: []
|
||||
}, stbl.boxes[1], 'generated an stts');
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'stsc',
|
||||
size: 16,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
sampleToChunks: []
|
||||
}, stbl.boxes[2], 'generated an stsc');
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'stsz',
|
||||
version: 0,
|
||||
size: 20,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
sampleSize: 0,
|
||||
entries: []
|
||||
}, stbl.boxes[3], 'generated an stsz');
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'stco',
|
||||
size: 16,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
chunkOffsets: []
|
||||
}, stbl.boxes[4], 'generated and stco');
|
||||
};
|
||||
|
||||
validateStsd = function(stsd, expected) {
|
||||
QUnit.assert.equal(stsd.type, 'stsd', 'generated an stsd');
|
||||
QUnit.assert.equal(stsd.sampleDescriptions.length, 1, 'generated one sample');
|
||||
if (expected.type !== 'audio') {
|
||||
validateVideoSample(stsd.sampleDescriptions[0]);
|
||||
} else {
|
||||
validateAudioSample(stsd.sampleDescriptions[0]);
|
||||
}
|
||||
};
|
||||
|
||||
validateVideoSample = function(sample) {
|
||||
QUnit.assert.deepEqual(sample, {
|
||||
type: 'avc1',
|
||||
size: 152,
|
||||
dataReferenceIndex: 1,
|
||||
width: 600,
|
||||
height: 300,
|
||||
horizresolution: 72,
|
||||
vertresolution: 72,
|
||||
frameCount: 1,
|
||||
depth: 24,
|
||||
config: [{
|
||||
type: 'avcC',
|
||||
size: 30,
|
||||
configurationVersion: 1,
|
||||
avcProfileIndication: 3,
|
||||
avcLevelIndication: 5,
|
||||
profileCompatibility: 7,
|
||||
lengthSizeMinusOne: 3,
|
||||
sps: [new Uint8Array([
|
||||
0, 1, 2
|
||||
]), new Uint8Array([
|
||||
3, 4, 5
|
||||
])],
|
||||
pps: [new Uint8Array([
|
||||
6, 7, 8
|
||||
])]
|
||||
}, {
|
||||
type: 'btrt',
|
||||
size: 20,
|
||||
bufferSizeDB: 1875072,
|
||||
maxBitrate: 3000000,
|
||||
avgBitrate: 3000000
|
||||
}, {
|
||||
type: 'pasp',
|
||||
size: 16,
|
||||
data: new Uint8Array([0, 0, 0, 1, 0, 0, 0, 1])
|
||||
}]
|
||||
}, 'generated a video sample');
|
||||
};
|
||||
|
||||
validateAudioSample = function(sample) {
|
||||
QUnit.assert.deepEqual(sample, {
|
||||
type: 'mp4a',
|
||||
size: 75,
|
||||
dataReferenceIndex: 1,
|
||||
channelcount: 2,
|
||||
samplesize: 16,
|
||||
samplerate: 48000,
|
||||
streamDescriptor: {
|
||||
type: 'esds',
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
size: 39,
|
||||
esId: 0,
|
||||
streamPriority: 0,
|
||||
// these values were hard-coded based on a working audio init segment
|
||||
decoderConfig: {
|
||||
avgBitrate: 56000,
|
||||
maxBitrate: 56000,
|
||||
bufferSize: 1536,
|
||||
objectProfileIndication: 64,
|
||||
streamType: 5,
|
||||
decoderConfigDescriptor: {
|
||||
audioObjectType: 2,
|
||||
channelConfiguration: 2,
|
||||
length: 2,
|
||||
samplingFrequencyIndex: 3,
|
||||
tag: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 'generated an audio sample');
|
||||
};
|
||||
|
||||
validateMvex = function(mvex, options) {
|
||||
options = options || {
|
||||
sampleDegradationPriority: 1
|
||||
};
|
||||
QUnit.assert.deepEqual({
|
||||
type: 'mvex',
|
||||
size: 40,
|
||||
boxes: [{
|
||||
type: 'trex',
|
||||
size: 32,
|
||||
version: 0,
|
||||
flags: new Uint8Array([0, 0, 0]),
|
||||
trackId: 7,
|
||||
defaultSampleDescriptionIndex: 1,
|
||||
defaultSampleDuration: 0,
|
||||
defaultSampleSize: 0,
|
||||
sampleDependsOn: 0,
|
||||
sampleIsDependedOn: 0,
|
||||
sampleHasRedundancy: 0,
|
||||
samplePaddingValue: 0,
|
||||
sampleIsDifferenceSample: true,
|
||||
sampleDegradationPriority: options.sampleDegradationPriority
|
||||
}]
|
||||
}, mvex, 'writes a movie extends box');
|
||||
};
|
||||
|
||||
QUnit.test('generates a video moov', function(assert) {
|
||||
var
|
||||
boxes,
|
||||
data = mp4.generator.moov([{
|
||||
id: 7,
|
||||
duration: 100,
|
||||
width: 600,
|
||||
height: 300,
|
||||
type: 'video',
|
||||
profileIdc: 3,
|
||||
levelIdc: 5,
|
||||
profileCompatibility: 7,
|
||||
sarRatio: [1, 1],
|
||||
sps: [new Uint8Array([0, 1, 2]), new Uint8Array([3, 4, 5])],
|
||||
pps: [new Uint8Array([6, 7, 8])]
|
||||
}]);
|
||||
|
||||
assert.ok(data, 'box is not null');
|
||||
boxes = mp4.tools.inspect(data);
|
||||
assert.equal(boxes.length, 1, 'generated a single box');
|
||||
assert.equal(boxes[0].type, 'moov', 'generated a moov type');
|
||||
assert.equal(boxes[0].size, data.byteLength, 'generated size');
|
||||
assert.equal(boxes[0].boxes.length, 3, 'generated three sub boxes');
|
||||
|
||||
validateMvhd(boxes[0].boxes[0]);
|
||||
validateTrak(boxes[0].boxes[1], {
|
||||
duration: 100,
|
||||
width: 600,
|
||||
height: 300
|
||||
});
|
||||
validateMvex(boxes[0].boxes[2]);
|
||||
});
|
||||
|
||||
QUnit.test('generates an audio moov', function(assert) {
|
||||
var
|
||||
data = mp4.generator.moov([{
|
||||
id: 7,
|
||||
type: 'audio',
|
||||
audioobjecttype: 2,
|
||||
channelcount: 2,
|
||||
samplerate: 48000,
|
||||
samplingfrequencyindex: 3,
|
||||
samplesize: 16
|
||||
}]),
|
||||
boxes;
|
||||
|
||||
assert.ok(data, 'box is not null');
|
||||
boxes = mp4.tools.inspect(data);
|
||||
assert.equal(boxes.length, 1, 'generated a single box');
|
||||
assert.equal(boxes[0].type, 'moov', 'generated a moov type');
|
||||
assert.equal(boxes[0].size, data.byteLength, 'generated size');
|
||||
assert.equal(boxes[0].boxes.length, 3, 'generated three sub boxes');
|
||||
|
||||
validateMvhd(boxes[0].boxes[0]);
|
||||
validateTrak(boxes[0].boxes[1], {
|
||||
type: 'audio',
|
||||
timescale: 48000
|
||||
});
|
||||
validateMvex(boxes[0].boxes[2], {
|
||||
sampleDegradationPriority: 0
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('generates a sound hdlr', function(assert) {
|
||||
var boxes, hdlr,
|
||||
data = mp4.generator.moov([{
|
||||
duration: 100,
|
||||
type: 'audio'
|
||||
}]);
|
||||
|
||||
assert.ok(data, 'box is not null');
|
||||
|
||||
boxes = mp4.tools.inspect(data);
|
||||
|
||||
hdlr = boxes[0].boxes[1].boxes[1].boxes[1];
|
||||
assert.equal(hdlr.type, 'hdlr', 'generate an hdlr type');
|
||||
assert.equal(hdlr.handlerType, 'soun', 'wrote a sound handler');
|
||||
assert.equal(hdlr.name, 'SoundHandler', 'wrote the handler name');
|
||||
});
|
||||
|
||||
QUnit.test('generates a video hdlr', function(assert) {
|
||||
var boxes, hdlr,
|
||||
data = mp4.generator.moov([{
|
||||
duration: 100,
|
||||
width: 600,
|
||||
height: 300,
|
||||
type: 'video',
|
||||
sps: [],
|
||||
pps: []
|
||||
}]);
|
||||
|
||||
assert.ok(data, 'box is not null');
|
||||
|
||||
boxes = mp4.tools.inspect(data);
|
||||
|
||||
hdlr = boxes[0].boxes[1].boxes[1].boxes[1];
|
||||
assert.equal(hdlr.type, 'hdlr', 'generate an hdlr type');
|
||||
assert.equal(hdlr.handlerType, 'vide', 'wrote a video handler');
|
||||
assert.equal(hdlr.name, 'VideoHandler', 'wrote the handler name');
|
||||
});
|
||||
|
||||
QUnit.test('generates an initialization segment', function(assert) {
|
||||
var
|
||||
data = mp4.generator.initSegment([{
|
||||
id: 1,
|
||||
width: 600,
|
||||
height: 300,
|
||||
type: 'video',
|
||||
sps: [new Uint8Array([0])],
|
||||
pps: [new Uint8Array([1])]
|
||||
}, {
|
||||
id: 2,
|
||||
type: 'audio'
|
||||
}]),
|
||||
init, mvhd, trak1, trak2, mvex;
|
||||
|
||||
init = mp4.tools.inspect(data);
|
||||
assert.equal(init.length, 2, 'generated two boxes');
|
||||
assert.equal(init[0].type, 'ftyp', 'generated a ftyp box');
|
||||
assert.equal(init[1].type, 'moov', 'generated a moov box');
|
||||
assert.equal(init[1].boxes[0].duration, 0xffffffff, 'wrote a maximum duration');
|
||||
|
||||
mvhd = init[1].boxes[0];
|
||||
assert.equal(mvhd.type, 'mvhd', 'wrote an mvhd');
|
||||
|
||||
trak1 = init[1].boxes[1];
|
||||
assert.equal(trak1.type, 'trak', 'wrote a trak');
|
||||
assert.equal(trak1.boxes[0].trackId, 1, 'wrote the first track id');
|
||||
assert.equal(trak1.boxes[0].width, 600, 'wrote the first track width');
|
||||
assert.equal(trak1.boxes[0].height, 300, 'wrote the first track height');
|
||||
assert.equal(trak1.boxes[1].boxes[1].handlerType, 'vide', 'wrote the first track type');
|
||||
|
||||
trak2 = init[1].boxes[2];
|
||||
assert.equal(trak2.type, 'trak', 'wrote a trak');
|
||||
assert.equal(trak2.boxes[0].trackId, 2, 'wrote the second track id');
|
||||
assert.equal(trak2.boxes[1].boxes[1].handlerType, 'soun', 'wrote the second track type');
|
||||
|
||||
mvex = init[1].boxes[3];
|
||||
assert.equal(mvex.type, 'mvex', 'wrote an mvex');
|
||||
});
|
||||
|
||||
QUnit.test('generates a minimal moof', function(assert) {
|
||||
var
|
||||
data = mp4.generator.moof(7, [{
|
||||
id: 17,
|
||||
samples: [{
|
||||
duration: 9000,
|
||||
size: 10,
|
||||
flags: {
|
||||
isLeading: 0,
|
||||
dependsOn: 2,
|
||||
isDependedOn: 1,
|
||||
hasRedundancy: 0,
|
||||
paddingValue: 0,
|
||||
isNonSyncSample: 0,
|
||||
degradationPriority: 14
|
||||
},
|
||||
compositionTimeOffset: 500
|
||||
}, {
|
||||
duration: 10000,
|
||||
size: 11,
|
||||
flags: {
|
||||
isLeading: 0,
|
||||
dependsOn: 1,
|
||||
isDependedOn: 0,
|
||||
hasRedundancy: 0,
|
||||
paddingValue: 0,
|
||||
isNonSyncSample: 0,
|
||||
degradationPriority: 9
|
||||
},
|
||||
compositionTimeOffset: 1000
|
||||
}]
|
||||
}]),
|
||||
moof = mp4.tools.inspect(data),
|
||||
trun,
|
||||
sdtp;
|
||||
|
||||
assert.equal(moof.length, 1, 'generated one box');
|
||||
assert.equal(moof[0].type, 'moof', 'generated a moof box');
|
||||
assert.equal(moof[0].boxes.length, 2, 'generated two child boxes');
|
||||
assert.equal(moof[0].boxes[0].type, 'mfhd', 'generated an mfhd box');
|
||||
assert.equal(moof[0].boxes[0].sequenceNumber, 7, 'included the sequence_number');
|
||||
assert.equal(moof[0].boxes[1].type, 'traf', 'generated a traf box');
|
||||
assert.equal(moof[0].boxes[1].boxes.length, 4, 'generated track fragment info');
|
||||
assert.equal(moof[0].boxes[1].boxes[0].type, 'tfhd', 'generated a tfhd box');
|
||||
assert.equal(moof[0].boxes[1].boxes[0].trackId, 17, 'wrote the first track id');
|
||||
assert.equal(moof[0].boxes[1].boxes[0].baseDataOffset, undefined, 'did not set a base data offset');
|
||||
|
||||
assert.equal(moof[0].boxes[1].boxes[1].type, 'tfdt', 'generated a tfdt box');
|
||||
assert.ok(moof[0].boxes[1].boxes[1].baseMediaDecodeTime >= 0,
|
||||
'media decode time is non-negative');
|
||||
|
||||
trun = moof[0].boxes[1].boxes[2];
|
||||
assert.equal(trun.type, 'trun', 'generated a trun box');
|
||||
assert.equal(typeof trun.dataOffset, 'number', 'has a data offset');
|
||||
assert.ok(trun.dataOffset >= 0, 'has a non-negative data offset');
|
||||
assert.equal(trun.dataOffset, moof[0].size + 8, 'sets the data offset past the mdat header');
|
||||
assert.equal(trun.samples.length, 2, 'wrote two samples');
|
||||
|
||||
assert.equal(trun.samples[0].duration, 9000, 'wrote a sample duration');
|
||||
assert.equal(trun.samples[0].size, 10, 'wrote a sample size');
|
||||
assert.deepEqual(trun.samples[0].flags, {
|
||||
isLeading: 0,
|
||||
dependsOn: 2,
|
||||
isDependedOn: 1,
|
||||
hasRedundancy: 0,
|
||||
paddingValue: 0,
|
||||
isNonSyncSample: 0,
|
||||
degradationPriority: 14
|
||||
}, 'wrote the sample flags');
|
||||
assert.equal(trun.samples[0].compositionTimeOffset, 500, 'wrote the composition time offset');
|
||||
|
||||
assert.equal(trun.samples[1].duration, 10000, 'wrote a sample duration');
|
||||
assert.equal(trun.samples[1].size, 11, 'wrote a sample size');
|
||||
assert.deepEqual(trun.samples[1].flags, {
|
||||
isLeading: 0,
|
||||
dependsOn: 1,
|
||||
isDependedOn: 0,
|
||||
hasRedundancy: 0,
|
||||
paddingValue: 0,
|
||||
isNonSyncSample: 0,
|
||||
degradationPriority: 9
|
||||
}, 'wrote the sample flags');
|
||||
assert.equal(trun.samples[1].compositionTimeOffset, 1000, 'wrote the composition time offset');
|
||||
|
||||
sdtp = moof[0].boxes[1].boxes[3];
|
||||
assert.equal(sdtp.type, 'sdtp', 'generated an sdtp box');
|
||||
assert.equal(sdtp.samples.length, 2, 'wrote two samples');
|
||||
assert.deepEqual(sdtp.samples[0], {
|
||||
dependsOn: 2,
|
||||
isDependedOn: 1,
|
||||
hasRedundancy: 0
|
||||
}, 'wrote the sample data table');
|
||||
assert.deepEqual(sdtp.samples[1], {
|
||||
dependsOn: 1,
|
||||
isDependedOn: 0,
|
||||
hasRedundancy: 0
|
||||
}, 'wrote the sample data table');
|
||||
});
|
||||
|
||||
QUnit.test('generates a moof for audio', function(assert) {
|
||||
var
|
||||
data = mp4.generator.moof(7, [{
|
||||
id: 17,
|
||||
type: 'audio',
|
||||
samples: [{
|
||||
duration: 9000,
|
||||
size: 10
|
||||
}, {
|
||||
duration: 10000,
|
||||
size: 11
|
||||
}]
|
||||
}]),
|
||||
moof = mp4.tools.inspect(data),
|
||||
trun;
|
||||
|
||||
assert.deepEqual(moof[0].boxes[1].boxes.length, 3, 'generated three traf children');
|
||||
trun = moof[0].boxes[1].boxes[2];
|
||||
assert.ok(trun, 'generated a trun');
|
||||
assert.equal(trun.dataOffset, data.byteLength + 8, 'calculated the data offset');
|
||||
assert.deepEqual(trun.samples, [{
|
||||
duration: 9000,
|
||||
size: 10
|
||||
}, {
|
||||
duration: 10000,
|
||||
size: 11
|
||||
}], 'wrote simple audio samples');
|
||||
});
|
||||
|
||||
QUnit.test('can generate a traf without samples', function(assert) {
|
||||
var
|
||||
data = mp4.generator.moof(8, [{
|
||||
trackId: 13
|
||||
}]),
|
||||
moof = mp4.tools.inspect(data);
|
||||
|
||||
assert.equal(moof[0].boxes[1].boxes[2].samples.length, 0, 'generated no samples');
|
||||
});
|
||||
|
||||
QUnit.test('generates an mdat', function(assert) {
|
||||
var
|
||||
data = mp4.generator.mdat(new Uint8Array([1, 2, 3, 4])),
|
||||
mdat = mp4.tools.inspect(data);
|
||||
|
||||
assert.equal(mdat.length, 1, 'generated one box');
|
||||
assert.equal(mdat[0].type, 'mdat', 'generated an mdat box');
|
||||
assert.deepEqual(mdat[0].byteLength, 4, 'encapsulated the data');
|
||||
});
|
1121
node_modules/mux.js/test/mp4-inspector.test.js
generated
vendored
Normal file
1121
node_modules/mux.js/test/mp4-inspector.test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
407
node_modules/mux.js/test/mp4-probe.test.js
generated
vendored
Normal file
407
node_modules/mux.js/test/mp4-probe.test.js
generated
vendored
Normal file
|
@ -0,0 +1,407 @@
|
|||
'use strict';
|
||||
|
||||
var
|
||||
QUnit = require('qunit'),
|
||||
probe = require('../lib/mp4/probe'),
|
||||
mp4Helpers = require('./utils/mp4-helpers'),
|
||||
box = mp4Helpers.box,
|
||||
|
||||
// defined below
|
||||
moovWithoutMdhd,
|
||||
moovWithoutTkhd,
|
||||
moofWithTfdt,
|
||||
multiMoof,
|
||||
multiTraf,
|
||||
noTrunSamples,
|
||||
v1boxes;
|
||||
|
||||
QUnit.module('MP4 Probe');
|
||||
|
||||
QUnit.test('reads the timescale from an mdhd', function(assert) {
|
||||
// sampleMoov has a base timescale of 1000 with an override to 90kHz
|
||||
// in the mdhd
|
||||
assert.deepEqual(probe.timescale(new Uint8Array(mp4Helpers.sampleMoov)), {
|
||||
1: 90e3,
|
||||
2: 90e3
|
||||
}, 'found the timescale');
|
||||
});
|
||||
|
||||
QUnit.test('reads tracks', function(assert) {
|
||||
var tracks = probe.tracks(new Uint8Array(mp4Helpers.sampleMoov));
|
||||
|
||||
assert.equal(tracks.length, 2, 'two tracks');
|
||||
assert.equal(tracks[0].codec, 'avc1.4d400d', 'codec is correct');
|
||||
assert.equal(tracks[0].id, 1, 'id is correct');
|
||||
assert.equal(tracks[0].type, 'video', 'type is correct');
|
||||
assert.equal(tracks[0].timescale, 90e3, 'timescale is correct');
|
||||
|
||||
assert.equal(tracks[1].codec, 'mp4a.40.2', 'codec is correct');
|
||||
assert.equal(tracks[1].id, 2, 'id is correct');
|
||||
assert.equal(tracks[1].type, 'audio', 'type is correct');
|
||||
assert.equal(tracks[1].timescale, 90e3, 'timescale is correct');
|
||||
});
|
||||
|
||||
QUnit.test('returns null if the tkhd is missing', function(assert) {
|
||||
assert.equal(probe.timescale(new Uint8Array(moovWithoutTkhd)), null, 'indicated missing info');
|
||||
});
|
||||
|
||||
QUnit.test('returns null if the mdhd is missing', function(assert) {
|
||||
assert.equal(probe.timescale(new Uint8Array(moovWithoutMdhd)), null, 'indicated missing info');
|
||||
});
|
||||
|
||||
QUnit.test('startTime reads the base decode time from a tfdt', function(assert) {
|
||||
assert.equal(probe.startTime({
|
||||
4: 2
|
||||
}, new Uint8Array(moofWithTfdt)),
|
||||
0x01020304 / 2,
|
||||
'calculated base decode time');
|
||||
});
|
||||
|
||||
QUnit.test('startTime returns the earliest base decode time', function(assert) {
|
||||
assert.equal(probe.startTime({
|
||||
4: 2,
|
||||
6: 1
|
||||
}, new Uint8Array(multiMoof)),
|
||||
0x01020304 / 2,
|
||||
'returned the earlier time');
|
||||
});
|
||||
|
||||
QUnit.test('startTime parses 64-bit base decode times', function(assert) {
|
||||
assert.equal(probe.startTime({
|
||||
4: 3
|
||||
}, new Uint8Array(v1boxes)),
|
||||
0x0101020304 / 3,
|
||||
'parsed a long value');
|
||||
});
|
||||
|
||||
QUnit.test('compositionStartTime calculates composition time using composition time' +
|
||||
'offset from first trun sample', function(assert) {
|
||||
assert.equal(probe.compositionStartTime({
|
||||
1: 6,
|
||||
4: 3
|
||||
}, new Uint8Array(moofWithTfdt)),
|
||||
(0x01020304 + 10) / 3,
|
||||
'calculated correct composition start time');
|
||||
});
|
||||
|
||||
QUnit.test('compositionStartTime looks at only the first traf', function(assert) {
|
||||
assert.equal(probe.compositionStartTime({
|
||||
2: 6,
|
||||
4: 3
|
||||
}, new Uint8Array(multiTraf)),
|
||||
(0x01020304 + 10) / 3,
|
||||
'calculated composition start time from first traf');
|
||||
});
|
||||
|
||||
QUnit.test('compositionStartTime uses default composition time offset of 0' +
|
||||
'if no trun samples present', function(assert) {
|
||||
assert.equal(probe.compositionStartTime({
|
||||
2: 6,
|
||||
4: 3
|
||||
}, new Uint8Array(noTrunSamples)),
|
||||
(0x01020304 + 0) / 3,
|
||||
'calculated correct composition start time using default offset');
|
||||
});
|
||||
|
||||
QUnit.test('getTimescaleFromMediaHeader gets timescale for version 0 mdhd', function(assert) {
|
||||
var mdhd = new Uint8Array([
|
||||
0x00, // version 0
|
||||
0x00, 0x00, 0x00, // flags
|
||||
// version 0 has 32 bit creation_time, modification_time, and duration
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x00, 0x03, 0xe8, // timescale = 1000
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x15, 0xc7 // 'eng' language
|
||||
]);
|
||||
|
||||
assert.equal(
|
||||
probe.getTimescaleFromMediaHeader(mdhd),
|
||||
1000,
|
||||
'got timescale from version 0 mdhd'
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test('getTimescaleFromMediaHeader gets timescale for version 0 mdhd', function(assert) {
|
||||
var mdhd = new Uint8Array([
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
// version 1 has 64 bit creation_time, modification_time, and duration
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x00, 0x03, 0xe8, // timescale = 1000
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x15, 0xc7 // 'eng' language
|
||||
]);
|
||||
|
||||
assert.equal(
|
||||
probe.getTimescaleFromMediaHeader(mdhd),
|
||||
1000,
|
||||
'got timescale from version 1 mdhd'
|
||||
);
|
||||
});
|
||||
|
||||
// ---------
|
||||
// Test Data
|
||||
// ---------
|
||||
|
||||
moovWithoutTkhd =
|
||||
box('moov',
|
||||
box('trak',
|
||||
box('mdia',
|
||||
box('mdhd',
|
||||
0x00, // version 0
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x00, 0x03, 0xe8, // timescale = 1000
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x15, 0xc7, // 'eng' language
|
||||
0x00, 0x00),
|
||||
box('hdlr',
|
||||
0x00, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00, // pre_defined
|
||||
mp4Helpers.typeBytes('vide'), // handler_type
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
mp4Helpers.typeBytes('one'), 0x00)))); // name
|
||||
|
||||
moovWithoutMdhd =
|
||||
box('moov',
|
||||
box('trak',
|
||||
box('tkhd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x00, 0x00, 0x01, // track_ID
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, // layer
|
||||
0x00, 0x00, // alternate_group
|
||||
0x00, 0x00, // non-audio track volume
|
||||
0x00, 0x00, // reserved
|
||||
mp4Helpers.unityMatrix,
|
||||
0x01, 0x2c, 0x00, 0x00, // 300 in 16.16 fixed-point
|
||||
0x00, 0x96, 0x00, 0x00), // 150 in 16.16 fixed-point
|
||||
box('mdia',
|
||||
box('hdlr',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00, // pre_defined
|
||||
mp4Helpers.typeBytes('vide'), // handler_type
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
mp4Helpers.typeBytes('one'), 0x00)))); // name
|
||||
|
||||
moofWithTfdt =
|
||||
box('moof',
|
||||
box('mfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x04), // sequence_number
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x3b, // flags
|
||||
0x00, 0x00, 0x00, 0x04, // track_ID = 4
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x02, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x03, // default_sample_duration,
|
||||
0x00, 0x00, 0x00, 0x04, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x05),
|
||||
box('tfdt',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x01, 0x02, 0x03, 0x04), // baseMediaDecodeTime
|
||||
box('trun',
|
||||
0x00, // version
|
||||
0x00, 0x0f, 0x01, // flags: dataOffsetPresent, sampleDurationPresent,
|
||||
// sampleSizePresent, sampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x02, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00, // data_offset, no first_sample_flags
|
||||
// sample 1
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x0a, // signed sample_composition_time_offset = 10
|
||||
// sample 2
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x14))); // signed sample_composition_time_offset = 20
|
||||
|
||||
noTrunSamples =
|
||||
box('moof',
|
||||
box('mfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x04), // sequence_number
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x3b, // flags
|
||||
0x00, 0x00, 0x00, 0x04, // track_ID = 4
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x02, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x03, // default_sample_duration,
|
||||
0x00, 0x00, 0x00, 0x04, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x05),
|
||||
box('tfdt',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x01, 0x02, 0x03, 0x04), // baseMediaDecodeTime
|
||||
box('trun',
|
||||
0x00, // version
|
||||
0x00, 0x0f, 0x01, // flags: dataOffsetPresent, sampleDurationPresent,
|
||||
// sampleSizePresent, sampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x00, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00))); // data_offset, no first_sample_flags
|
||||
|
||||
|
||||
multiTraf =
|
||||
box('moof',
|
||||
box('mfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x04), // sequence_number
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x3b, // flags
|
||||
0x00, 0x00, 0x00, 0x04, // track_ID = 4
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x02, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x03, // default_sample_duration,
|
||||
0x00, 0x00, 0x00, 0x04, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x05),
|
||||
box('tfdt',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x01, 0x02, 0x03, 0x04), // baseMediaDecodeTime
|
||||
box('trun',
|
||||
0x00, // version
|
||||
0x00, 0x0f, 0x01, // flags: dataOffsetPresent, sampleDurationPresent,
|
||||
// sampleSizePresent, sampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x02, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00, // data_offset, no first_sample_flags
|
||||
// sample 1
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x0a, // signed sample_composition_time_offset = 10
|
||||
// sample 2
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x14)), // signed sample_composition_time_offset = 20
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x3b, // flags
|
||||
0x00, 0x00, 0x00, 0x02, // track_ID = 2
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x02, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x03, // default_sample_duration,
|
||||
0x00, 0x00, 0x00, 0x04, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x05),
|
||||
box('tfdt',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x01, 0x02, 0x01, 0x02), // baseMediaDecodeTime
|
||||
box('trun',
|
||||
0x00, // version
|
||||
0x00, 0x0f, 0x01, // flags: dataOffsetPresent, sampleDurationPresent,
|
||||
// sampleSizePresent, sampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x02, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00, // data_offset, no first_sample_flags
|
||||
// sample 1
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x0b, // signed sample_composition_time_offset = 11
|
||||
// sample 2
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x05))); // signed sample_composition_time_offset = 5
|
||||
|
||||
multiMoof = moofWithTfdt
|
||||
.concat(box('moof',
|
||||
box('mfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x04), // sequence_number
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x3b, // flags
|
||||
0x00, 0x00, 0x00, 0x06, // track_ID = 6
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x02, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x03, // default_sample_duration,
|
||||
0x00, 0x00, 0x00, 0x04, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x05),
|
||||
box('tfdt',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x01, 0x02, 0x03, 0x04), // baseMediaDecodeTime
|
||||
box('trun',
|
||||
0x00, // version
|
||||
0x00, 0x0f, 0x01, // flags: dataOffsetPresent, sampleDurationPresent,
|
||||
// sampleSizePresent, sampleFlagsPresent,
|
||||
// sampleCompositionTimeOffsetsPresent
|
||||
0x00, 0x00, 0x00, 0x02, // sample_count
|
||||
0x00, 0x00, 0x00, 0x00, // data_offset, no first_sample_flags
|
||||
// sample 1
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x14, // signed sample_composition_time_offset = 20
|
||||
// sample 2
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_duration = 10
|
||||
0x00, 0x00, 0x00, 0x0a, // sample_size = 10
|
||||
0x00, 0x00, 0x00, 0x00, // sample_flags
|
||||
0x00, 0x00, 0x00, 0x0a)))); // signed sample_composition_time_offset = 10
|
||||
v1boxes =
|
||||
box('moof',
|
||||
box('mfhd',
|
||||
0x01, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x04), // sequence_number
|
||||
box('traf',
|
||||
box('tfhd',
|
||||
0x01, // version
|
||||
0x00, 0x00, 0x3b, // flags
|
||||
0x00, 0x00, 0x00, 0x04, // track_ID = 4
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // base_data_offset
|
||||
0x00, 0x00, 0x00, 0x02, // sample_description_index
|
||||
0x00, 0x00, 0x00, 0x03, // default_sample_duration,
|
||||
0x00, 0x00, 0x00, 0x04, // default_sample_size
|
||||
0x00, 0x00, 0x00, 0x05),
|
||||
box('tfdt',
|
||||
0x01, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x01, 0x02, 0x03, 0x04))); // baseMediaDecodeTime
|
142
node_modules/mux.js/test/partial.test.js
generated
vendored
Normal file
142
node_modules/mux.js/test/partial.test.js
generated
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
var Transmuxer = require('../lib/partial/transmuxer.js');
|
||||
var utils = require('./utils');
|
||||
var generatePMT = utils.generatePMT;
|
||||
var videoPes = utils.videoPes;
|
||||
var audioPes = utils.audioPes;
|
||||
var packetize = utils.packetize;
|
||||
var PAT = utils.PAT;
|
||||
|
||||
QUnit.module('Partial Transmuxer - Options');
|
||||
[
|
||||
{options: {keepOriginalTimestamps: false}},
|
||||
{options: {keepOriginalTimestamps: true}},
|
||||
{options: {keepOriginalTimestamps: false, baseMediaDecodeTime: 15000}},
|
||||
{options: {keepOriginalTimestamps: true, baseMediaDecodeTime: 15000}},
|
||||
{options: {keepOriginalTimestamps: false}, baseMediaSetter: 15000},
|
||||
{options: {keepOriginalTimestamps: true}, baseMediaSetter: 15000}
|
||||
].forEach(function(test) {
|
||||
var createTransmuxer = function() {
|
||||
var transmuxer = new Transmuxer(test.options);
|
||||
|
||||
if (test.baseMediaSetter) {
|
||||
transmuxer.setBaseMediaDecodeTime(test.baseMediaSetter);
|
||||
}
|
||||
|
||||
return transmuxer;
|
||||
};
|
||||
|
||||
var name = '';
|
||||
|
||||
Object.keys(test.options).forEach(function(optionName) {
|
||||
name += '' + optionName + ' ' + test.options[optionName] + ' ';
|
||||
});
|
||||
|
||||
if (test.baseMediaSetter) {
|
||||
name += 'baseMediaDecodeTime setter ' + test.baseMediaSetter;
|
||||
}
|
||||
|
||||
QUnit.test('Audio frames after video not trimmed, ' + name, function(assert) {
|
||||
var
|
||||
segments = [],
|
||||
earliestDts = 15000,
|
||||
transmuxer = createTransmuxer();
|
||||
|
||||
transmuxer.on('data', function(segment) {
|
||||
segments.push(segment);
|
||||
});
|
||||
|
||||
// the following transmuxer pushes add tiny video and
|
||||
// audio data to the transmuxer. When we add the data
|
||||
// we also set the pts/dts time so that audio should
|
||||
// not be trimmed.
|
||||
transmuxer.push(packetize(PAT));
|
||||
transmuxer.push(packetize(generatePMT({
|
||||
hasVideo: true,
|
||||
hasAudio: true
|
||||
})));
|
||||
|
||||
transmuxer.push(packetize(audioPes([
|
||||
0x19, 0x47
|
||||
], true, earliestDts + 1)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x09, 0x01 // access_unit_delimiter_rbsp
|
||||
], true, earliestDts)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x08, 0x01 // pic_parameter_set_rbsp
|
||||
], true, earliestDts)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x07, // seq_parameter_set_rbsp
|
||||
0x27, 0x42, 0xe0, 0x0b,
|
||||
0xa9, 0x18, 0x60, 0x9d,
|
||||
0x80, 0x53, 0x06, 0x01,
|
||||
0x06, 0xb6, 0xc2, 0xb5,
|
||||
0xef, 0x7c, 0x04
|
||||
], false, earliestDts)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x05, 0x01 // slice_layer_without_partitioning_rbsp_idr
|
||||
], true, earliestDts)));
|
||||
transmuxer.flush();
|
||||
|
||||
// the partial transmuxer only generates a video segment
|
||||
// when all audio frames are trimmed. So we should have an audio and video
|
||||
// segment
|
||||
assert.equal(segments.length, 2, 'generated a video and an audio segment');
|
||||
assert.equal(segments[0].type, 'video', 'video segment exists');
|
||||
assert.equal(segments[1].type, 'audio', 'audio segment exists');
|
||||
});
|
||||
|
||||
QUnit.test('Audio frames trimmed before video, ' + name, function(assert) {
|
||||
var
|
||||
segments = [],
|
||||
earliestDts = 15000,
|
||||
baseTime = test.options.baseMediaDecodeTime || test.baseMediaSetter || 0,
|
||||
transmuxer = createTransmuxer();
|
||||
|
||||
transmuxer.on('data', function(segment) {
|
||||
segments.push(segment);
|
||||
});
|
||||
|
||||
// the following transmuxer pushes add tiny video and
|
||||
// audio data to the transmuxer. When we add the data
|
||||
// we also set the pts/dts time so that audio should
|
||||
// be trimmed.
|
||||
transmuxer.push(packetize(PAT));
|
||||
transmuxer.push(packetize(generatePMT({
|
||||
hasVideo: true,
|
||||
hasAudio: true
|
||||
})));
|
||||
|
||||
transmuxer.push(packetize(audioPes([
|
||||
0x19, 0x47
|
||||
], true, earliestDts - baseTime - 1)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x09, 0x01 // access_unit_delimiter_rbsp
|
||||
], true, earliestDts)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x08, 0x01 // pic_parameter_set_rbsp
|
||||
], true, earliestDts)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x07, // seq_parameter_set_rbsp
|
||||
0x27, 0x42, 0xe0, 0x0b,
|
||||
0xa9, 0x18, 0x60, 0x9d,
|
||||
0x80, 0x53, 0x06, 0x01,
|
||||
0x06, 0xb6, 0xc2, 0xb5,
|
||||
0xef, 0x7c, 0x04
|
||||
], false, earliestDts)));
|
||||
transmuxer.push(packetize(videoPes([
|
||||
0x05, 0x01 // slice_layer_without_partitioning_rbsp_idr
|
||||
], true, earliestDts)));
|
||||
transmuxer.flush();
|
||||
|
||||
// the partial transmuxer only generates a video segment
|
||||
// when all audio frames are trimmed.
|
||||
if (test.options.keepOriginalTimestamps && !baseTime) {
|
||||
assert.equal(segments.length, 2, 'generated both a video/audio segment');
|
||||
assert.equal(segments[0].type, 'video', 'segment is video');
|
||||
assert.equal(segments[1].type, 'audio', 'segment is audio');
|
||||
} else {
|
||||
assert.equal(segments.length, 1, 'generated only a video segment');
|
||||
assert.equal(segments[0].type, 'video', 'segment is video');
|
||||
}
|
||||
});
|
||||
});
|
BIN
node_modules/mux.js/test/segments/dash-608-captions-init.mp4
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/dash-608-captions-init.mp4
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/dash-608-captions-seg.m4s
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/dash-608-captions-seg.m4s
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/multi-channel-608-captions.ts
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/multi-channel-608-captions.ts
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/sintel-captions.ts
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/sintel-captions.ts
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/test-aac-segment.aac
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/test-aac-segment.aac
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/test-middle-pat-pmt.ts
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/test-middle-pat-pmt.ts
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/test-no-audio-segment.ts
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/test-no-audio-segment.ts
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/test-segment.ts
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/test-segment.ts
generated
vendored
Normal file
Binary file not shown.
BIN
node_modules/mux.js/test/segments/test-stuffed-pes.ts
generated
vendored
Normal file
BIN
node_modules/mux.js/test/segments/test-stuffed-pes.ts
generated
vendored
Normal file
Binary file not shown.
48
node_modules/mux.js/test/stream.test.js
generated
vendored
Normal file
48
node_modules/mux.js/test/stream.test.js
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
'use strict';
|
||||
|
||||
var
|
||||
stream,
|
||||
Stream = require('../lib/utils/stream'),
|
||||
QUnit = require('qunit');
|
||||
|
||||
QUnit.module('Stream', {
|
||||
beforeEach: function() {
|
||||
stream = new Stream();
|
||||
stream.init();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('trigger calls listeners', function(assert) {
|
||||
var args = [];
|
||||
|
||||
stream.on('test', function(data) {
|
||||
args.push(data);
|
||||
});
|
||||
|
||||
stream.trigger('test', 1);
|
||||
stream.trigger('test', 2);
|
||||
|
||||
assert.deepEqual(args, [1, 2]);
|
||||
});
|
||||
|
||||
QUnit.test('callbacks can remove themselves', function(assert) {
|
||||
var args1 = [], args2 = [], args3 = [];
|
||||
|
||||
stream.on('test', function(event) {
|
||||
args1.push(event);
|
||||
});
|
||||
stream.on('test', function t(event) {
|
||||
args2.push(event);
|
||||
stream.off('test', t);
|
||||
});
|
||||
stream.on('test', function(event) {
|
||||
args3.push(event);
|
||||
});
|
||||
|
||||
stream.trigger('test', 1);
|
||||
stream.trigger('test', 2);
|
||||
|
||||
assert.deepEqual(args1, [1, 2], 'first callback ran all times');
|
||||
assert.deepEqual(args2, [1], 'second callback removed after first run');
|
||||
assert.deepEqual(args3, [1, 2], 'third callback ran all times');
|
||||
});
|
4498
node_modules/mux.js/test/transmuxer.test.js
generated
vendored
Normal file
4498
node_modules/mux.js/test/transmuxer.test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
205
node_modules/mux.js/test/ts-inspector.test.js
generated
vendored
Normal file
205
node_modules/mux.js/test/ts-inspector.test.js
generated
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
'use strict';
|
||||
var segments = require('data-files!segments');
|
||||
|
||||
var
|
||||
QUnit = require('qunit'),
|
||||
tsInspector = require('../lib/tools/ts-inspector.js'),
|
||||
StreamTypes = require('../lib/m2ts/stream-types.js'),
|
||||
tsSegment = segments['test-segment.ts'](),
|
||||
tsNoAudioSegment = segments['test-no-audio-segment.ts'](),
|
||||
aacSegment = segments['test-aac-segment.aac'](),
|
||||
utils = require('./utils'),
|
||||
inspect = tsInspector.inspect,
|
||||
parseAudioPes_ = tsInspector.parseAudioPes_,
|
||||
packetize = utils.packetize,
|
||||
audioPes = utils.audioPes,
|
||||
PES_TIMESCALE = 90000;
|
||||
|
||||
QUnit.module('TS Inspector');
|
||||
|
||||
QUnit.test('returns null for empty segment input', function(assert) {
|
||||
assert.equal(inspect(new Uint8Array([])), null, 'returned null');
|
||||
});
|
||||
|
||||
QUnit.test('can parse a ts segment', function(assert) {
|
||||
var expected = {
|
||||
video: [
|
||||
{
|
||||
type: 'video',
|
||||
pts: 126000,
|
||||
dts: 126000,
|
||||
ptsTime: 126000 / PES_TIMESCALE,
|
||||
dtsTime: 126000 / PES_TIMESCALE
|
||||
},
|
||||
{
|
||||
type: 'video',
|
||||
pts: 924000,
|
||||
dts: 924000,
|
||||
ptsTime: 924000 / PES_TIMESCALE,
|
||||
dtsTime: 924000 / PES_TIMESCALE
|
||||
}
|
||||
],
|
||||
firstKeyFrame: {
|
||||
type: 'video',
|
||||
pts: 126000,
|
||||
dts: 126000,
|
||||
ptsTime: 126000 / PES_TIMESCALE,
|
||||
dtsTime: 126000 / PES_TIMESCALE
|
||||
},
|
||||
audio: [
|
||||
{
|
||||
type: 'audio',
|
||||
pts: 126000,
|
||||
dts: 126000,
|
||||
ptsTime: 126000 / PES_TIMESCALE,
|
||||
dtsTime: 126000 / PES_TIMESCALE
|
||||
},
|
||||
{
|
||||
type: 'audio',
|
||||
pts: 859518,
|
||||
dts: 859518,
|
||||
ptsTime: 859518 / PES_TIMESCALE,
|
||||
dtsTime: 859518 / PES_TIMESCALE
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
assert.deepEqual(inspect(tsSegment), expected, 'parses ts segment timing data');
|
||||
});
|
||||
|
||||
QUnit.test('adjusts timestamp values based on provided reference', function(assert) {
|
||||
var rollover = Math.pow(2, 33);
|
||||
|
||||
var expected = {
|
||||
video: [
|
||||
{
|
||||
type: 'video',
|
||||
pts: (126000 + rollover),
|
||||
dts: (126000 + rollover),
|
||||
ptsTime: (126000 + rollover) / PES_TIMESCALE,
|
||||
dtsTime: (126000 + rollover) / PES_TIMESCALE
|
||||
},
|
||||
{
|
||||
type: 'video',
|
||||
pts: (924000 + rollover),
|
||||
dts: (924000 + rollover),
|
||||
ptsTime: (924000 + rollover) / PES_TIMESCALE,
|
||||
dtsTime: (924000 + rollover) / PES_TIMESCALE
|
||||
}
|
||||
],
|
||||
firstKeyFrame: {
|
||||
type: 'video',
|
||||
pts: (126000 + rollover),
|
||||
dts: (126000 + rollover),
|
||||
ptsTime: (126000 + rollover) / PES_TIMESCALE,
|
||||
dtsTime: (126000 + rollover) / PES_TIMESCALE
|
||||
},
|
||||
audio: [
|
||||
{
|
||||
type: 'audio',
|
||||
pts: (126000 + rollover),
|
||||
dts: (126000 + rollover),
|
||||
ptsTime: (126000 + rollover) / PES_TIMESCALE,
|
||||
dtsTime: (126000 + rollover) / PES_TIMESCALE
|
||||
},
|
||||
{
|
||||
type: 'audio',
|
||||
pts: (859518 + rollover),
|
||||
dts: (859518 + rollover),
|
||||
ptsTime: (859518 + rollover) / PES_TIMESCALE,
|
||||
dtsTime: (859518 + rollover) / PES_TIMESCALE
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
assert.deepEqual(inspect(tsSegment, rollover - 1), expected,
|
||||
'adjusts inspected time data to account for pts rollover');
|
||||
});
|
||||
|
||||
QUnit.test('can parse an aac segment', function(assert) {
|
||||
var expected = {
|
||||
audio: [
|
||||
{
|
||||
type: 'audio',
|
||||
pts: 895690,
|
||||
dts: 895690,
|
||||
ptsTime: 895690 / PES_TIMESCALE,
|
||||
dtsTime: 895690 / PES_TIMESCALE
|
||||
},
|
||||
{
|
||||
type: 'audio',
|
||||
pts: (895690 + (430 * 1024 * PES_TIMESCALE / 44100)),
|
||||
dts: (895690 + (430 * 1024 * PES_TIMESCALE / 44100)),
|
||||
ptsTime: (895690 + (430 * 1024 * PES_TIMESCALE / 44100)) / PES_TIMESCALE,
|
||||
dtsTime: (895690 + (430 * 1024 * PES_TIMESCALE / 44100)) / PES_TIMESCALE
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
assert.deepEqual(inspect(aacSegment), expected, 'parses aac segment timing data');
|
||||
});
|
||||
|
||||
QUnit.test('can parse ts segment with no audio muxed in', function(assert) {
|
||||
var expected = {
|
||||
video: [
|
||||
{
|
||||
type: 'video',
|
||||
pts: 126000,
|
||||
dts: 126000,
|
||||
ptsTime: 126000 / PES_TIMESCALE,
|
||||
dtsTime: 126000 / PES_TIMESCALE
|
||||
},
|
||||
{
|
||||
type: 'video',
|
||||
pts: 924000,
|
||||
dts: 924000,
|
||||
ptsTime: 924000 / PES_TIMESCALE,
|
||||
dtsTime: 924000 / PES_TIMESCALE
|
||||
}
|
||||
],
|
||||
firstKeyFrame: {
|
||||
type: 'video',
|
||||
pts: 126000,
|
||||
dts: 126000,
|
||||
ptsTime: 126000 / PES_TIMESCALE,
|
||||
dtsTime: 126000 / PES_TIMESCALE
|
||||
}
|
||||
};
|
||||
|
||||
var actual = inspect(tsNoAudioSegment);
|
||||
|
||||
assert.equal(typeof actual.audio, 'undefined', 'results do not contain audio info');
|
||||
assert.deepEqual(actual, expected,
|
||||
'parses ts segment without audio timing data');
|
||||
});
|
||||
|
||||
QUnit.test('can parse audio PES when it\'s the only packet in a stream', function(assert) {
|
||||
var
|
||||
pts = 90000,
|
||||
pmt = {
|
||||
// fake pmt pid that doesn't clash with the audio pid
|
||||
pid: 0x10,
|
||||
table: {
|
||||
// pid copied over from default of audioPes function
|
||||
0x12: StreamTypes.ADTS_STREAM_TYPE
|
||||
}
|
||||
},
|
||||
result = { audio: [] };
|
||||
|
||||
parseAudioPes_(packetize(audioPes([0x00], true, pts)), pmt, result);
|
||||
|
||||
// note that both the first and last packet timings are the same, as there's only one
|
||||
// packet to parse
|
||||
assert.deepEqual(
|
||||
result.audio,
|
||||
[{
|
||||
dts: pts,
|
||||
pts: pts,
|
||||
type: 'audio'
|
||||
}, {
|
||||
dts: pts,
|
||||
pts: pts,
|
||||
type: 'audio'
|
||||
}],
|
||||
'parses audio pes for timing info');
|
||||
});
|
32
node_modules/mux.js/test/utils.bin.test.js
generated
vendored
Normal file
32
node_modules/mux.js/test/utils.bin.test.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
var
|
||||
QUnit = require('qunit'),
|
||||
toUnsigned = require('../lib/utils/bin').toUnsigned;
|
||||
|
||||
QUnit.module('Binary Utils');
|
||||
|
||||
QUnit.test('converts values to unsigned integers after bitwise operations', function(assert) {
|
||||
var bytes;
|
||||
|
||||
bytes = [0, 0, 124, 129];
|
||||
|
||||
assert.equal(toUnsigned(bytes[0] << 24 |
|
||||
bytes[1] << 16 |
|
||||
bytes[2] << 8 |
|
||||
bytes[3]),
|
||||
31873, 'positive signed result stays positive');
|
||||
|
||||
bytes = [150, 234, 221, 192];
|
||||
|
||||
// sanity check
|
||||
assert.equal(bytes[0] << 24 |
|
||||
bytes[1] << 16 |
|
||||
bytes[2] << 8 |
|
||||
bytes[3],
|
||||
-1762992704, 'bitwise operation produces negative signed result');
|
||||
|
||||
assert.equal(toUnsigned(bytes[0] << 24 |
|
||||
bytes[1] << 16 |
|
||||
bytes[2] << 8 |
|
||||
bytes[3]),
|
||||
2531974592, 'negative signed result becomes unsigned positive');
|
||||
});
|
181
node_modules/mux.js/test/utils.clock.test.js
generated
vendored
Normal file
181
node_modules/mux.js/test/utils.clock.test.js
generated
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
'use strict';
|
||||
|
||||
var
|
||||
QUnit = require('qunit'),
|
||||
clock = require('../lib/utils/clock');
|
||||
|
||||
QUnit.module('Clock Utils');
|
||||
|
||||
QUnit.test('converts from seconds to video timestamps', function(assert) {
|
||||
assert.equal(clock.secondsToVideoTs(0), 0, 'converts seconds to video timestamp');
|
||||
assert.equal(clock.secondsToVideoTs(1), 90000, 'converts seconds to video timestamp');
|
||||
assert.equal(clock.secondsToVideoTs(10), 900000, 'converts seconds to video timestamp');
|
||||
assert.equal(clock.secondsToVideoTs(-1), -90000, 'converts seconds to video timestamp');
|
||||
assert.equal(clock.secondsToVideoTs(3), 270000, 'converts seconds to video timestamp');
|
||||
assert.equal(clock.secondsToVideoTs(0.1), 9000, 'converts seconds to video timestamp');
|
||||
});
|
||||
|
||||
QUnit.test('converts from seconds to audio timestamps', function(assert) {
|
||||
assert.equal(clock.secondsToAudioTs(0, 90000),
|
||||
0,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(1, 90000),
|
||||
90000,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(-1, 90000),
|
||||
-90000,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(3, 90000),
|
||||
270000,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(0, 44100),
|
||||
0,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(1, 44100),
|
||||
44100,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(3, 44100),
|
||||
132300,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(-1, 44100),
|
||||
-44100,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.secondsToAudioTs(0.1, 44100),
|
||||
4410,
|
||||
'converts seconds to audio timestamp');
|
||||
});
|
||||
|
||||
QUnit.test('converts from video timestamp to seconds', function(assert) {
|
||||
assert.equal(clock.videoTsToSeconds(0), 0, 'converts video timestamp to seconds');
|
||||
assert.equal(clock.videoTsToSeconds(90000), 1, 'converts video timestamp to seconds');
|
||||
assert.equal(clock.videoTsToSeconds(900000), 10, 'converts video timestamp to seconds');
|
||||
assert.equal(clock.videoTsToSeconds(-90000), -1, 'converts video timestamp to seconds');
|
||||
assert.equal(clock.videoTsToSeconds(270000), 3, 'converts video timestamp to seconds');
|
||||
assert.equal(clock.videoTsToSeconds(9000), 0.1, 'converts video timestamp to seconds');
|
||||
});
|
||||
|
||||
QUnit.test('converts from audio timestamp to seconds', function(assert) {
|
||||
assert.equal(clock.audioTsToSeconds(0, 90000),
|
||||
0,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(90000, 90000),
|
||||
1,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(-90000, 90000),
|
||||
-1,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(270000, 90000),
|
||||
3,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(0, 44100),
|
||||
0,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(44100, 44100),
|
||||
1,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(132300, 44100),
|
||||
3,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(-44100, 44100),
|
||||
-1,
|
||||
'converts seconds to audio timestamp');
|
||||
assert.equal(clock.audioTsToSeconds(4410, 44100),
|
||||
0.1,
|
||||
'converts seconds to audio timestamp');
|
||||
});
|
||||
|
||||
QUnit.test('converts from audio timestamp to video timestamp', function(assert) {
|
||||
assert.equal(clock.audioTsToVideoTs(0, 90000),
|
||||
0,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(90000, 90000),
|
||||
90000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(900000, 90000),
|
||||
900000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(-90000, 90000),
|
||||
-90000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(270000, 90000),
|
||||
270000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(9000, 90000),
|
||||
9000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(0, 44100),
|
||||
0,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(44100, 44100),
|
||||
90000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(441000, 44100),
|
||||
900000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(-44100, 44100),
|
||||
-90000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(132300, 44100),
|
||||
270000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
assert.equal(clock.audioTsToVideoTs(4410, 44100),
|
||||
9000,
|
||||
'converts audio timestamp to video timestamp');
|
||||
});
|
||||
|
||||
QUnit.test('converts from video timestamp to audio timestamp', function(assert) {
|
||||
assert.equal(clock.videoTsToAudioTs(0, 90000),
|
||||
0,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(90000, 90000),
|
||||
90000,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(900000, 90000),
|
||||
900000,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(-90000, 90000),
|
||||
-90000,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(270000, 90000),
|
||||
270000,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(9000, 90000),
|
||||
9000,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(0, 44100),
|
||||
0,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(90000, 44100),
|
||||
44100,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(900000, 44100),
|
||||
441000,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(-90000, 44100),
|
||||
-44100,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(270000, 44100),
|
||||
132300,
|
||||
'converts video timestamp to audio timestamp');
|
||||
assert.equal(clock.videoTsToAudioTs(9000, 44100),
|
||||
4410,
|
||||
'converts video timestamp to audio timestamp');
|
||||
});
|
||||
|
||||
QUnit.test('converts from metadata timestamp to seconds', function(assert) {
|
||||
assert.equal(clock.metadataTsToSeconds(90000, 90000, false),
|
||||
0,
|
||||
'converts metadata timestamp to seconds and adjusts by timelineStartPts');
|
||||
|
||||
assert.equal(clock.metadataTsToSeconds(270000, 90000, false),
|
||||
2,
|
||||
'converts metadata timestamp to seconds and adjusts by timelineStartPts');
|
||||
|
||||
assert.equal(clock.metadataTsToSeconds(90000, 90000, true),
|
||||
1,
|
||||
'converts metadata timestamp to seconds while keeping original timestamps');
|
||||
|
||||
assert.equal(clock.metadataTsToSeconds(180000, 0, true),
|
||||
2,
|
||||
'converts metadata timestamp to seconds while keeping original timestamps');
|
||||
});
|
327
node_modules/mux.js/test/utils.js
generated
vendored
Normal file
327
node_modules/mux.js/test/utils.js
generated
vendored
Normal file
|
@ -0,0 +1,327 @@
|
|||
var
|
||||
mp2t = require('../lib/m2ts'),
|
||||
id3Generator = require('./utils/id3-generator'),
|
||||
MP2T_PACKET_LENGTH = mp2t.MP2T_PACKET_LENGTH,
|
||||
PMT,
|
||||
PAT,
|
||||
generatePMT,
|
||||
pesHeader,
|
||||
packetize,
|
||||
transportPacket,
|
||||
videoPes,
|
||||
adtsFrame,
|
||||
audioPes,
|
||||
timedMetadataPes,
|
||||
binaryStringToArrayOfBytes,
|
||||
leftPad;
|
||||
|
||||
|
||||
PMT = [
|
||||
0x47, // sync byte
|
||||
// tei:0 pusi:1 tp:0 pid:0 0000 0010 0000
|
||||
0x40, 0x10,
|
||||
// tsc:01 afc:01 cc:0000 pointer_field:0000 0000
|
||||
0x50, 0x00,
|
||||
// tid:0000 0010 ssi:0 0:0 r:00 sl:0000 0001 1100
|
||||
0x02, 0x00, 0x1c,
|
||||
// pn:0000 0000 0000 0001
|
||||
0x00, 0x01,
|
||||
// r:00 vn:00 000 cni:1 sn:0000 0000 lsn:0000 0000
|
||||
0x01, 0x00, 0x00,
|
||||
// r:000 ppid:0 0011 1111 1111
|
||||
0x03, 0xff,
|
||||
// r:0000 pil:0000 0000 0000
|
||||
0x00, 0x00,
|
||||
// h264
|
||||
// st:0001 1010 r:000 epid:0 0000 0001 0001
|
||||
0x1b, 0x00, 0x11,
|
||||
// r:0000 esil:0000 0000 0000
|
||||
0x00, 0x00,
|
||||
// adts
|
||||
// st:0000 1111 r:000 epid:0 0000 0001 0010
|
||||
0x0f, 0x00, 0x12,
|
||||
// r:0000 esil:0000 0000 0000
|
||||
0x00, 0x00,
|
||||
|
||||
// timed metadata
|
||||
// st:0001 0111 r:000 epid:0 0000 0001 0011
|
||||
0x15, 0x00, 0x13,
|
||||
// r:0000 esil:0000 0000 0000
|
||||
0x00, 0x00,
|
||||
|
||||
// crc
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
|
||||
/*
|
||||
Packet Header:
|
||||
| sb | tei pusi tp pid:5 | pid | tsc afc cc |
|
||||
with af:
|
||||
| afl | ... | <data> |
|
||||
without af:
|
||||
| <data> |
|
||||
|
||||
PAT:
|
||||
| pf? | ... |
|
||||
| tid | ssi '0' r sl:4 | sl | tsi:8 |
|
||||
| tsi | r vn cni | sn | lsn |
|
||||
|
||||
with program_number == '0':
|
||||
| pn | pn | r np:5 | np |
|
||||
otherwise:
|
||||
| pn | pn | r pmp:5 | pmp |
|
||||
*/
|
||||
|
||||
PAT = [
|
||||
0x47, // sync byte
|
||||
// tei:0 pusi:1 tp:0 pid:0 0000 0000 0000
|
||||
0x40, 0x00,
|
||||
// tsc:01 afc:01 cc:0000 pointer_field:0000 0000
|
||||
0x50, 0x00,
|
||||
// tid:0000 0000 ssi:0 0:0 r:00 sl:0000 0000 0000
|
||||
0x00, 0x00, 0x00,
|
||||
// tsi:0000 0000 0000 0000
|
||||
0x00, 0x00,
|
||||
// r:00 vn:00 000 cni:1 sn:0000 0000 lsn:0000 0000
|
||||
0x01, 0x00, 0x00,
|
||||
// pn:0000 0000 0000 0001
|
||||
0x00, 0x01,
|
||||
// r:000 pmp:0 0000 0010 0000
|
||||
0x00, 0x10,
|
||||
// crc32:0000 0000 0000 0000 0000 0000 0000 0000
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
|
||||
generatePMT = function(options) {
|
||||
var PMT = [
|
||||
0x47, // sync byte
|
||||
// tei:0 pusi:1 tp:0 pid:0 0000 0010 0000
|
||||
0x40, 0x10,
|
||||
// tsc:01 afc:01 cc:0000 pointer_field:0000 0000
|
||||
0x50, 0x00,
|
||||
// tid:0000 0010 ssi:0 0:0 r:00 sl:0000 0001 1100
|
||||
0x02, 0x00, 0x1c,
|
||||
// pn:0000 0000 0000 0001
|
||||
0x00, 0x01,
|
||||
// r:00 vn:00 000 cni:1 sn:0000 0000 lsn:0000 0000
|
||||
0x01, 0x00, 0x00,
|
||||
// r:000 ppid:0 0011 1111 1111
|
||||
0x03, 0xff,
|
||||
// r:0000 pil:0000 0000 0000
|
||||
0x00, 0x00];
|
||||
|
||||
if (options.hasVideo) {
|
||||
// h264
|
||||
PMT = PMT.concat([
|
||||
// st:0001 1010 r:000 epid:0 0000 0001 0001
|
||||
0x1b, 0x00, 0x11,
|
||||
// r:0000 esil:0000 0000 0000
|
||||
0x00, 0x00
|
||||
]);
|
||||
}
|
||||
|
||||
if (options.hasAudio) {
|
||||
// adts
|
||||
PMT = PMT.concat([
|
||||
// st:0000 1111 r:000 epid:0 0000 0001 0010
|
||||
0x0f, 0x00, 0x12,
|
||||
// r:0000 esil:0000 0000 0000
|
||||
0x00, 0x00
|
||||
]);
|
||||
}
|
||||
|
||||
if (options.hasMetadata) {
|
||||
// timed metadata
|
||||
PMT = PMT.concat([
|
||||
// st:0001 0111 r:000 epid:0 0000 0001 0011
|
||||
0x15, 0x00, 0x13,
|
||||
// r:0000 esil:0000 0000 0000
|
||||
0x00, 0x00
|
||||
]);
|
||||
}
|
||||
|
||||
// crc
|
||||
return PMT.concat([0x00, 0x00, 0x00, 0x00]);
|
||||
};
|
||||
|
||||
pesHeader = function(first, pts, dataLength) {
|
||||
if (!dataLength) {
|
||||
dataLength = 0;
|
||||
} else {
|
||||
// Add the pes header length (only the portion after the
|
||||
// pes_packet_length field)
|
||||
dataLength += 3;
|
||||
}
|
||||
|
||||
// PES_packet(), Rec. ITU-T H.222.0, Table 2-21
|
||||
var result = [
|
||||
// pscp:0000 0000 0000 0000 0000 0001
|
||||
0x00, 0x00, 0x01,
|
||||
// sid:0000 0000 ppl:0000 0000 0000 0000
|
||||
0x00, 0x00, 0x00,
|
||||
// 10 psc:00 pp:0 dai:1 c:0 ooc:0
|
||||
0x84,
|
||||
// pdf:?0 ef:1 erf:0 dtmf:0 acif:0 pcf:0 pef:0
|
||||
0x20 | (pts ? 0x80 : 0x00),
|
||||
// phdl:0000 0000
|
||||
(first ? 0x01 : 0x00) + (pts ? 0x05 : 0x00)
|
||||
];
|
||||
|
||||
// Only store 15 bits of the PTS for QUnit.testing purposes
|
||||
if (pts) {
|
||||
var
|
||||
pts32 = Math.floor(pts / 2), // right shift by 1
|
||||
leftMostBit = ((pts32 & 0x80000000) >>> 31) & 0x01,
|
||||
firstThree;
|
||||
|
||||
pts = pts & 0xffffffff; // remove left most bit
|
||||
firstThree = (leftMostBit << 3) | (((pts & 0xc0000000) >>> 29) & 0x06) | 0x01;
|
||||
result.push((0x2 << 4) | firstThree);
|
||||
result.push((pts >>> 22) & 0xff);
|
||||
result.push(((pts >>> 14) | 0x01) & 0xff);
|
||||
result.push((pts >>> 7) & 0xff);
|
||||
result.push(((pts << 1) | 0x01) & 0xff);
|
||||
|
||||
// Add the bytes spent on the pts info
|
||||
dataLength += 5;
|
||||
}
|
||||
if (first) {
|
||||
result.push(0x00);
|
||||
dataLength += 1;
|
||||
}
|
||||
|
||||
// Finally set the pes_packet_length field
|
||||
result[4] = (dataLength & 0x0000FF00) >> 8;
|
||||
result[5] = dataLength & 0x000000FF;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
packetize = function(data) {
|
||||
var packet = new Uint8Array(MP2T_PACKET_LENGTH);
|
||||
packet.set(data);
|
||||
return packet;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to create transport stream PES packets
|
||||
* @param pid {uint8} - the program identifier (PID)
|
||||
* @param data {arraylike} - the payload bytes
|
||||
* @payload first {boolean} - true if this PES should be a payload
|
||||
* unit start
|
||||
*/
|
||||
transportPacket = function(pid, data, first, pts, isVideoData) {
|
||||
var
|
||||
adaptationFieldLength = 188 - data.length - 14 - (first ? 1 : 0) - (pts ? 5 : 0),
|
||||
// transport_packet(), Rec. ITU-T H.222.0, Table 2-2
|
||||
result = [
|
||||
// sync byte
|
||||
0x47,
|
||||
// tei:0 pusi:1 tp:0 pid:0 0000 0001 0001
|
||||
0x40, pid,
|
||||
// tsc:01 afc:11 cc:0000
|
||||
0x70
|
||||
].concat([
|
||||
// afl
|
||||
adaptationFieldLength & 0xff,
|
||||
// di:0 rai:0 espi:0 pf:0 of:0 spf:0 tpdf:0 afef:0
|
||||
0x00
|
||||
]),
|
||||
i;
|
||||
|
||||
i = adaptationFieldLength - 1;
|
||||
while (i--) {
|
||||
// stuffing_bytes
|
||||
result.push(0xff);
|
||||
}
|
||||
|
||||
// PES_packet(), Rec. ITU-T H.222.0, Table 2-21
|
||||
result = result.concat(pesHeader(first, pts, isVideoData ? 0 : data.length));
|
||||
|
||||
return result.concat(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to create video PES packets
|
||||
* @param data {arraylike} - the payload bytes
|
||||
* @payload first {boolean} - true if this PES should be a payload
|
||||
* unit start
|
||||
*/
|
||||
videoPes = function(data, first, pts) {
|
||||
return transportPacket(0x11, [
|
||||
// NAL unit start code
|
||||
0x00, 0x00, 0x01
|
||||
].concat(data), first, pts, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to create audio ADTS frame header
|
||||
* @param dataLength {number} - the payload byte count
|
||||
*/
|
||||
adtsFrame = function(dataLength) {
|
||||
var frameLength = dataLength + 7;
|
||||
return [
|
||||
0xff, 0xf1, // no CRC
|
||||
0x10, // AAC Main, 44.1KHz
|
||||
0xb0 | ((frameLength & 0x1800) >> 11), // 2 channels
|
||||
(frameLength & 0x7f8) >> 3,
|
||||
((frameLength & 0x07) << 5) + 7, // frame length in bytes
|
||||
0x00 // one AAC per ADTS frame
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to create audio PES packets
|
||||
* @param data {arraylike} - the payload bytes
|
||||
* @payload first {boolean} - true if this PES should be a payload
|
||||
* unit start
|
||||
*/
|
||||
audioPes = function(data, first, pts) {
|
||||
return transportPacket(0x12,
|
||||
adtsFrame(data.length).concat(data),
|
||||
first, pts);
|
||||
};
|
||||
|
||||
timedMetadataPes = function(data) {
|
||||
var id3 = id3Generator;
|
||||
return transportPacket(0x13, id3.id3Tag(id3.id3Frame('PRIV', 0x00, 0x01)));
|
||||
};
|
||||
|
||||
binaryStringToArrayOfBytes = function(string) {
|
||||
var
|
||||
array = [],
|
||||
arrayIndex = 0,
|
||||
stringIndex = 0;
|
||||
|
||||
while (stringIndex < string.length) {
|
||||
array[arrayIndex] = parseInt(string.slice(stringIndex, stringIndex + 8), 2);
|
||||
|
||||
arrayIndex++;
|
||||
// next byte
|
||||
stringIndex += 8;
|
||||
}
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
leftPad = function(string, targetLength) {
|
||||
if (string.length >= targetLength) {
|
||||
return string;
|
||||
}
|
||||
return new Array(targetLength - string.length + 1).join('0') + string;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
PMT: PMT,
|
||||
PAT: PAT,
|
||||
generatePMT: generatePMT,
|
||||
pesHeader: pesHeader,
|
||||
packetize: packetize,
|
||||
transportPacket: transportPacket,
|
||||
videoPes: videoPes,
|
||||
adtsFrame: adtsFrame,
|
||||
audioPes: audioPes,
|
||||
timedMetadataPes: timedMetadataPes,
|
||||
binaryStringToArrayOfBytes: binaryStringToArrayOfBytes,
|
||||
leftPad: leftPad
|
||||
};
|
10816
node_modules/mux.js/test/utils/cc708-pink-underscore.js
generated
vendored
Normal file
10816
node_modules/mux.js/test/utils/cc708-pink-underscore.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
74
node_modules/mux.js/test/utils/id3-generator.js
generated
vendored
Normal file
74
node_modules/mux.js/test/utils/id3-generator.js
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Helper functions for creating ID3 metadata.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var stringToInts, stringToCString, id3Tag, id3Frame;
|
||||
|
||||
stringToInts = function(string) {
|
||||
var result = [], i;
|
||||
for (i = 0; i < string.length; i++) {
|
||||
result[i] = string.charCodeAt(i);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
stringToCString = function(string) {
|
||||
return stringToInts(string).concat([0x00]);
|
||||
};
|
||||
|
||||
id3Tag = function() {
|
||||
var
|
||||
frames = Array.prototype.concat.apply([], Array.prototype.slice.call(arguments)),
|
||||
result = 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
|
||||
], frames),
|
||||
size;
|
||||
|
||||
// size is stored as a sequence of four 7-bit integers with the
|
||||
// high bit of each byte set to zero
|
||||
size = result.length - 10;
|
||||
|
||||
result[6] = (size >>> 21) & 0x7f;
|
||||
result[7] = (size >>> 14) & 0x7f;
|
||||
result[8] = (size >>> 7) & 0x7f;
|
||||
result[9] = size & 0x7f;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
id3Frame = function(type) {
|
||||
var result = stringToInts(type).concat([
|
||||
0x00, 0x00, 0x00, 0x00, // size
|
||||
0xe0, 0x00 // flags. tag/file alter preservation, read-only
|
||||
]),
|
||||
size = result.length - 10;
|
||||
|
||||
// append the fields of the ID3 frame
|
||||
result = result.concat.apply(result, Array.prototype.slice.call(arguments, 1));
|
||||
|
||||
// set the size
|
||||
size = result.length - 10;
|
||||
|
||||
result[4] = (size >>> 21) & 0x7f;
|
||||
result[5] = (size >>> 14) & 0x7f;
|
||||
result[6] = (size >>> 7) & 0x7f;
|
||||
result[7] = size & 0x7f;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
stringToInts: stringToInts,
|
||||
stringToCString: stringToCString,
|
||||
id3Tag: id3Tag,
|
||||
id3Frame: id3Frame
|
||||
};
|
996
node_modules/mux.js/test/utils/mixed-608-708-captions.js
generated
vendored
Normal file
996
node_modules/mux.js/test/utils/mixed-608-708-captions.js
generated
vendored
Normal file
|
@ -0,0 +1,996 @@
|
|||
module.exports = [
|
||||
{ type: 1, pts: 7192231956, ccData: 36782 },
|
||||
{ type: 0, pts: 7192231956, ccData: 38062 },
|
||||
{ type: 3, pts: 7192231956, ccData: 17186 },
|
||||
{ type: 2, pts: 7192234926, ccData: 0 },
|
||||
{ type: 1, pts: 7192234926, ccData: 387 },
|
||||
{ type: 2, pts: 7192234926, ccData: 36094 },
|
||||
{ type: 0, pts: 7192234926, ccData: 38062 },
|
||||
{ type: 2, pts: 7192240866, ccData: 16640 },
|
||||
{ type: 2, pts: 7192240866, ccData: 39195 },
|
||||
{ type: 2, pts: 7192240866, ccData: 1283 },
|
||||
{ type: 2, pts: 7192240866, ccData: 37162 },
|
||||
{ type: 2, pts: 7192240866, ccData: 42 },
|
||||
{ type: 2, pts: 7192240866, ccData: 37376 },
|
||||
{ type: 2, pts: 7192240866, ccData: 1024 },
|
||||
{ type: 2, pts: 7192240866, ccData: 31 },
|
||||
{ type: 0, pts: 7192240866, ccData: 37970 },
|
||||
{ type: 1, pts: 7192240866, ccData: 62196 },
|
||||
{ type: 2, pts: 7192240866, ccData: 5264 },
|
||||
{ type: 1, pts: 7192243926, ccData: 26656 },
|
||||
{ type: 3, pts: 7192243926, ccData: 49955 },
|
||||
{ type: 0, pts: 7192243926, ccData: 38817 },
|
||||
{ type: 1, pts: 7192246896, ccData: 22511 },
|
||||
{ type: 0, pts: 7192246896, ccData: 38817 },
|
||||
{ type: 2, pts: 7192246896, ccData: 37376 },
|
||||
{ type: 2, pts: 7192246896, ccData: 1280 },
|
||||
{ type: 1, pts: 7192249956, ccData: 61284 },
|
||||
{ type: 0, pts: 7192249956, ccData: 49877 },
|
||||
{ type: 3, pts: 7192249956, ccData: 802 },
|
||||
{ type: 1, pts: 7192253016, ccData: 29472 },
|
||||
{ type: 2, pts: 7192253016, ccData: 0 },
|
||||
{ type: 0, pts: 7192253016, ccData: 21536 },
|
||||
{ type: 2, pts: 7192253016, ccData: 16981 },
|
||||
{ type: 3, pts: 7192253016, ccData: 17186 },
|
||||
{ type: 3, pts: 7192255986, ccData: 33570 },
|
||||
{ type: 1, pts: 7192255986, ccData: 19553 },
|
||||
{ type: 0, pts: 7192255986, ccData: 18772 },
|
||||
{ type: 2, pts: 7192255986, ccData: 21536 },
|
||||
{ type: 2, pts: 7192255986, ccData: 0 },
|
||||
{ type: 0, pts: 7192258956, ccData: 42963 },
|
||||
{ type: 2, pts: 7192258956, ccData: 18772 },
|
||||
{ type: 2, pts: 7192258956, ccData: 0 },
|
||||
{ type: 3, pts: 7192258956, ccData: 49954 },
|
||||
{ type: 1, pts: 7192258956, ccData: 63418 },
|
||||
{ type: 0, pts: 7192261926, ccData: 8398 },
|
||||
{ type: 1, pts: 7192261926, ccData: 8271 },
|
||||
{ type: 2, pts: 7192261926, ccData: 10067 },
|
||||
{ type: 2, pts: 7192261926, ccData: 0 },
|
||||
{ type: 3, pts: 7192261926, ccData: 802 },
|
||||
{ type: 3, pts: 7192264896, ccData: 17186 },
|
||||
{ type: 2, pts: 7192264896, ccData: 0 },
|
||||
{ type: 2, pts: 7192264896, ccData: 8270 },
|
||||
{ type: 1, pts: 7192264896, ccData: 28192 },
|
||||
{ type: 0, pts: 7192264896, ccData: 20308 },
|
||||
{ type: 2, pts: 7192267956, ccData: 0 },
|
||||
{ type: 2, pts: 7192267956, ccData: 20308 },
|
||||
{ type: 1, pts: 7192267956, ccData: 62568 },
|
||||
{ type: 0, pts: 7192267956, ccData: 8403 },
|
||||
{ type: 3, pts: 7192267956, ccData: 33570 },
|
||||
{ type: 3, pts: 7192270926, ccData: 49954 },
|
||||
{ type: 0, pts: 7192270926, ccData: 54598 },
|
||||
{ type: 2, pts: 7192270926, ccData: 8275 },
|
||||
{ type: 2, pts: 7192270926, ccData: 0 },
|
||||
{ type: 1, pts: 7192270926, ccData: 58656 },
|
||||
{ type: 1, pts: 7192273986, ccData: 51317 },
|
||||
{ type: 0, pts: 7192273986, ccData: 17989 },
|
||||
{ type: 2, pts: 7192273986, ccData: 21830 },
|
||||
{ type: 2, pts: 7192273986, ccData: 0 },
|
||||
{ type: 3, pts: 7192273986, ccData: 802 },
|
||||
{ type: 3, pts: 7192277046, ccData: 17186 },
|
||||
{ type: 2, pts: 7192277046, ccData: 17989 },
|
||||
{ type: 1, pts: 7192277046, ccData: 28404 },
|
||||
{ type: 0, pts: 7192277046, ccData: 21065 },
|
||||
{ type: 2, pts: 7192277046, ccData: 0 },
|
||||
{ type: 1, pts: 7192279926, ccData: 8360 },
|
||||
{ type: 2, pts: 7192279926, ccData: 21065 },
|
||||
{ type: 2, pts: 7192279926, ccData: 0 },
|
||||
{ type: 3, pts: 7192279926, ccData: 33570 },
|
||||
{ type: 0, pts: 7192279926, ccData: 52935 },
|
||||
{ type: 1, pts: 7192282986, ccData: 54245 },
|
||||
{ type: 0, pts: 7192282986, ccData: 38132 },
|
||||
{ type: 2, pts: 7192282986, ccData: 20039 },
|
||||
{ type: 2, pts: 7192282986, ccData: 0 },
|
||||
{ type: 3, pts: 7192282986, ccData: 51761 },
|
||||
{ type: 1, pts: 7192285956, ccData: 36667 },
|
||||
{ type: 2, pts: 7192285956, ccData: 2048 },
|
||||
{ type: 2, pts: 7192285956, ccData: 39195 },
|
||||
{ type: 2, pts: 7192285956, ccData: 16640 },
|
||||
{ type: 2, pts: 7192285956, ccData: 287 },
|
||||
{ type: 2, pts: 7192285956, ccData: 4240 },
|
||||
{ type: 2, pts: 7192285956, ccData: 1283 },
|
||||
{ type: 2, pts: 7192285956, ccData: 37162 },
|
||||
{ type: 2, pts: 7192285956, ccData: 0 },
|
||||
{ type: 0, pts: 7192285956, ccData: 38132 },
|
||||
{ type: 2, pts: 7192285956, ccData: 37377 },
|
||||
{ type: 3, pts: 7192288926, ccData: 803 },
|
||||
{ type: 1, pts: 7192288926, ccData: 258 },
|
||||
{ type: 0, pts: 7192288926, ccData: 38691 },
|
||||
{ type: 1, pts: 7192291986, ccData: 16448 },
|
||||
{ type: 2, pts: 7192291986, ccData: 37377 },
|
||||
{ type: 2, pts: 7192291986, ccData: 2816 },
|
||||
{ type: 0, pts: 7192291986, ccData: 38691 },
|
||||
{ type: 1, pts: 7192294956, ccData: 16448 },
|
||||
{ type: 0, pts: 7192294956, ccData: 21065 },
|
||||
{ type: 3, pts: 7192294956, ccData: 17186 },
|
||||
{ type: 0, pts: 7192298016, ccData: 51144 },
|
||||
{ type: 2, pts: 7192298016, ccData: 21065 },
|
||||
{ type: 2, pts: 7192298016, ccData: 0 },
|
||||
{ type: 3, pts: 7192298016, ccData: 33570 },
|
||||
{ type: 1, pts: 7192298016, ccData: 16512 },
|
||||
{ type: 1, pts: 7192300986, ccData: 36782 },
|
||||
{ type: 2, pts: 7192300986, ccData: 0 },
|
||||
{ type: 2, pts: 7192300986, ccData: 18248 },
|
||||
{ type: 3, pts: 7192309986, ccData: 33828 },
|
||||
{ type: 2, pts: 7192309986, ccData: 0 },
|
||||
{ type: 2, pts: 7192309986, ccData: 22318 },
|
||||
{ type: 0, pts: 7192309986, ccData: 22446 },
|
||||
{ type: 1, pts: 7192309986, ccData: 62196 },
|
||||
{ type: 0, pts: 7192309986, ccData: 37935 },
|
||||
{ type: 3, pts: 7192309986, ccData: 17186 },
|
||||
{ type: 2, pts: 7192313046, ccData: 0 },
|
||||
{ type: 0, pts: 7192313046, ccData: 37935 },
|
||||
{ type: 1, pts: 7192313046, ccData: 26656 },
|
||||
{ type: 2, pts: 7192313046, ccData: 35074 },
|
||||
{ type: 2, pts: 7192313046, ccData: 35841 },
|
||||
{ type: 0, pts: 7192316016, ccData: 32896 },
|
||||
{ type: 1, pts: 7192316016, ccData: 22511 },
|
||||
{ type: 1, pts: 7192318986, ccData: 61284 },
|
||||
{ type: 0, pts: 7192318986, ccData: 32896 },
|
||||
{ type: 1, pts: 7192322046, ccData: 29472 },
|
||||
{ type: 0, pts: 7192322046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192324926, ccData: 389 },
|
||||
{ type: 0, pts: 7192324926, ccData: 32896 },
|
||||
{ type: 0, pts: 7192327986, ccData: 32896 },
|
||||
{ type: 1, pts: 7192327986, ccData: 51396 },
|
||||
{ type: 1, pts: 7192331046, ccData: 36831 },
|
||||
{ type: 0, pts: 7192331046, ccData: 32896 },
|
||||
{ type: 0, pts: 7192334016, ccData: 32896 },
|
||||
{ type: 1, pts: 7192334016, ccData: 258 },
|
||||
{ type: 0, pts: 7192337076, ccData: 32896 },
|
||||
{ type: 1, pts: 7192337076, ccData: 16448 },
|
||||
{ type: 1, pts: 7192340046, ccData: 16448 },
|
||||
{ type: 0, pts: 7192340046, ccData: 32896 },
|
||||
{ type: 0, pts: 7192343016, ccData: 32896 },
|
||||
{ type: 1, pts: 7192343016, ccData: 16512 },
|
||||
{ type: 1, pts: 7192346076, ccData: 36782 },
|
||||
{ type: 0, pts: 7192346076, ccData: 32896 },
|
||||
{ type: 0, pts: 7192348956, ccData: 32896 },
|
||||
{ type: 1, pts: 7192348956, ccData: 387 },
|
||||
{ type: 1, pts: 7192352016, ccData: 52975 },
|
||||
{ type: 0, pts: 7192352016, ccData: 32896 },
|
||||
{ type: 1, pts: 7192355076, ccData: 62196 },
|
||||
{ type: 0, pts: 7192355076, ccData: 32896 },
|
||||
{ type: 0, pts: 7192358046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192358046, ccData: 26656 },
|
||||
{ type: 1, pts: 7192361106, ccData: 22511 },
|
||||
{ type: 0, pts: 7192361106, ccData: 32896 },
|
||||
{ type: 1, pts: 7192364076, ccData: 61284 },
|
||||
{ type: 0, pts: 7192364076, ccData: 32896 },
|
||||
{ type: 1, pts: 7192367046, ccData: 29472 },
|
||||
{ type: 0, pts: 7192367046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192370016, ccData: 19553 },
|
||||
{ type: 0, pts: 7192370016, ccData: 32896 },
|
||||
{ type: 0, pts: 7192372986, ccData: 32896 },
|
||||
{ type: 1, pts: 7192372986, ccData: 63418 },
|
||||
{ type: 0, pts: 7192376046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192376046, ccData: 8271 },
|
||||
{ type: 0, pts: 7192379106, ccData: 32896 },
|
||||
{ type: 1, pts: 7192379106, ccData: 28192 },
|
||||
{ type: 1, pts: 7192382076, ccData: 62568 },
|
||||
{ type: 0, pts: 7192382076, ccData: 32896 },
|
||||
{ type: 1, pts: 7192385136, ccData: 58656 },
|
||||
{ type: 0, pts: 7192385136, ccData: 32896 },
|
||||
{ type: 0, pts: 7192388106, ccData: 32896 },
|
||||
{ type: 1, pts: 7192388106, ccData: 51317 },
|
||||
{ type: 1, pts: 7192391076, ccData: 28404 },
|
||||
{ type: 0, pts: 7192391076, ccData: 32896 },
|
||||
{ type: 0, pts: 7192394046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192394046, ccData: 8360 },
|
||||
{ type: 1, pts: 7192397016, ccData: 54245 },
|
||||
{ type: 0, pts: 7192397016, ccData: 32896 },
|
||||
{ type: 1, pts: 7192400076, ccData: 36667 },
|
||||
{ type: 0, pts: 7192400076, ccData: 32896 },
|
||||
{ type: 1, pts: 7192403046, ccData: 258 },
|
||||
{ type: 0, pts: 7192403046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192406106, ccData: 16448 },
|
||||
{ type: 0, pts: 7192406106, ccData: 32896 },
|
||||
{ type: 1, pts: 7192409166, ccData: 16448 },
|
||||
{ type: 0, pts: 7192409166, ccData: 32896 },
|
||||
{ type: 1, pts: 7192412136, ccData: 16512 },
|
||||
{ type: 0, pts: 7192412136, ccData: 32896 },
|
||||
{ type: 0, pts: 7192415106, ccData: 32896 },
|
||||
{ type: 1, pts: 7192415106, ccData: 36782 },
|
||||
{ type: 1, pts: 7192418076, ccData: 387 },
|
||||
{ type: 0, pts: 7192418076, ccData: 32896 },
|
||||
{ type: 1, pts: 7192421046, ccData: 52975 },
|
||||
{ type: 0, pts: 7192421046, ccData: 32896 },
|
||||
{ type: 1, pts: 7192424106, ccData: 62196 },
|
||||
{ type: 0, pts: 7192424106, ccData: 32896 },
|
||||
{ type: 0, pts: 7192427076, ccData: 32896 },
|
||||
{ type: 1, pts: 7192427076, ccData: 26656 },
|
||||
{ type: 1, pts: 7192430136, ccData: 22511 },
|
||||
{ type: 0, pts: 7192430136, ccData: 32896 },
|
||||
{ type: 1, pts: 7192433196, ccData: 61284 },
|
||||
{ type: 0, pts: 7192433196, ccData: 32896 },
|
||||
{ type: 1, pts: 7192436166, ccData: 29472 },
|
||||
{ type: 0, pts: 7192436166, ccData: 32896 },
|
||||
{ type: 0, pts: 7192439136, ccData: 32896 },
|
||||
{ type: 1, pts: 7192439136, ccData: 19553 },
|
||||
{ type: 1, pts: 7192442106, ccData: 63418 },
|
||||
{ type: 0, pts: 7192442106, ccData: 37920 },
|
||||
{ type: 0, pts: 7192445076, ccData: 37920 },
|
||||
{ type: 1, pts: 7192445076, ccData: 8271 },
|
||||
{ type: 1, pts: 7192448136, ccData: 28192 },
|
||||
{ type: 3, pts: 7192448136, ccData: 49954 },
|
||||
{ type: 0, pts: 7192448136, ccData: 38062 },
|
||||
{ type: 2, pts: 7192451106, ccData: 36093 },
|
||||
{ type: 1, pts: 7192451106, ccData: 62568 },
|
||||
{ type: 0, pts: 7192451106, ccData: 38062 },
|
||||
{ type: 2, pts: 7192451106, ccData: 0 },
|
||||
{ type: 0, pts: 7192454166, ccData: 38000 },
|
||||
{ type: 3, pts: 7192454166, ccData: 2609 },
|
||||
{ type: 1, pts: 7192454166, ccData: 58656 },
|
||||
{ type: 0, pts: 7192457226, ccData: 38000 },
|
||||
{ type: 2, pts: 7192457226, ccData: 38939 },
|
||||
{ type: 2, pts: 7192457226, ccData: 17920 },
|
||||
{ type: 2, pts: 7192457226, ccData: 31 },
|
||||
{ type: 2, pts: 7192457226, ccData: 5264 },
|
||||
{ type: 2, pts: 7192457226, ccData: 1283 },
|
||||
{ type: 2, pts: 7192457226, ccData: 37162 },
|
||||
{ type: 2, pts: 7192457226, ccData: 42 },
|
||||
{ type: 2, pts: 7192457226, ccData: 37376 },
|
||||
{ type: 2, pts: 7192457226, ccData: 0 },
|
||||
{ type: 1, pts: 7192457226, ccData: 51317 },
|
||||
{ type: 1, pts: 7192460106, ccData: 28404 },
|
||||
{ type: 0, pts: 7192460106, ccData: 38818 },
|
||||
{ type: 3, pts: 7192460106, ccData: 17187 },
|
||||
{ type: 2, pts: 7192463166, ccData: 512 },
|
||||
{ type: 1, pts: 7192463166, ccData: 8360 },
|
||||
{ type: 0, pts: 7192463166, ccData: 38818 },
|
||||
{ type: 2, pts: 7192463166, ccData: 37376 },
|
||||
{ type: 0, pts: 7192466136, ccData: 18772 },
|
||||
{ type: 1, pts: 7192466136, ccData: 54245 },
|
||||
{ type: 3, pts: 7192466136, ccData: 33570 },
|
||||
{ type: 3, pts: 7192469106, ccData: 49954 },
|
||||
{ type: 2, pts: 7192469106, ccData: 0 },
|
||||
{ type: 0, pts: 7192469106, ccData: 42963 },
|
||||
{ type: 1, pts: 7192469106, ccData: 36667 },
|
||||
{ type: 2, pts: 7192469106, ccData: 18772 },
|
||||
{ type: 2, pts: 7192472166, ccData: 10067 },
|
||||
{ type: 2, pts: 7192472166, ccData: 0 },
|
||||
{ type: 3, pts: 7192472166, ccData: 802 },
|
||||
{ type: 0, pts: 7192472166, ccData: 8398 },
|
||||
{ type: 1, pts: 7192472166, ccData: 258 },
|
||||
{ type: 2, pts: 7192475136, ccData: 8270 },
|
||||
{ type: 0, pts: 7192475136, ccData: 20308 },
|
||||
{ type: 3, pts: 7192475136, ccData: 17186 },
|
||||
{ type: 2, pts: 7192475136, ccData: 0 },
|
||||
{ type: 1, pts: 7192475136, ccData: 16448 },
|
||||
{ type: 1, pts: 7192478196, ccData: 16448 },
|
||||
{ type: 0, pts: 7192478196, ccData: 8385 },
|
||||
{ type: 2, pts: 7192478196, ccData: 20308 },
|
||||
{ type: 2, pts: 7192478196, ccData: 0 },
|
||||
{ type: 3, pts: 7192478196, ccData: 33570 },
|
||||
{ type: 2, pts: 7192481166, ccData: 8257 },
|
||||
{ type: 0, pts: 7192481166, ccData: 8276 },
|
||||
{ type: 2, pts: 7192481166, ccData: 0 },
|
||||
{ type: 1, pts: 7192481166, ccData: 16512 },
|
||||
{ type: 3, pts: 7192481166, ccData: 49954 },
|
||||
{ type: 3, pts: 7192484136, ccData: 802 },
|
||||
{ type: 2, pts: 7192484136, ccData: 0 },
|
||||
{ type: 1, pts: 7192484136, ccData: 36782 },
|
||||
{ type: 0, pts: 7192484136, ccData: 51282 },
|
||||
{ type: 2, pts: 7192484136, ccData: 8276 },
|
||||
{ type: 3, pts: 7192487196, ccData: 17186 },
|
||||
{ type: 0, pts: 7192487196, ccData: 17857 },
|
||||
{ type: 2, pts: 7192487196, ccData: 18514 },
|
||||
{ type: 2, pts: 7192487196, ccData: 0 },
|
||||
{ type: 1, pts: 7192487196, ccData: 387 },
|
||||
{ type: 3, pts: 7192490166, ccData: 33570 },
|
||||
{ type: 1, pts: 7192490166, ccData: 52975 },
|
||||
{ type: 0, pts: 7192490166, ccData: 21536 },
|
||||
{ type: 2, pts: 7192490166, ccData: 17729 },
|
||||
{ type: 2, pts: 7192490166, ccData: 0 },
|
||||
{ type: 2, pts: 7192493226, ccData: 21536 },
|
||||
{ type: 3, pts: 7192493226, ccData: 49954 },
|
||||
{ type: 2, pts: 7192493226, ccData: 0 },
|
||||
{ type: 0, pts: 7192493226, ccData: 21583 },
|
||||
{ type: 1, pts: 7192493226, ccData: 62196 },
|
||||
{ type: 1, pts: 7192496196, ccData: 26656 },
|
||||
{ type: 0, pts: 7192496196, ccData: 8385 },
|
||||
{ type: 2, pts: 7192496196, ccData: 21583 },
|
||||
{ type: 2, pts: 7192496196, ccData: 0 },
|
||||
{ type: 3, pts: 7192496196, ccData: 802 },
|
||||
{ type: 1, pts: 7192499166, ccData: 22511 },
|
||||
{ type: 0, pts: 7192499166, ccData: 52953 },
|
||||
{ type: 2, pts: 7192499166, ccData: 8257 },
|
||||
{ type: 2, pts: 7192499166, ccData: 0 },
|
||||
{ type: 3, pts: 7192499166, ccData: 17186 },
|
||||
{ type: 2, pts: 7192502226, ccData: 0 },
|
||||
{ type: 2, pts: 7192502226, ccData: 20057 },
|
||||
{ type: 3, pts: 7192502226, ccData: 33570 },
|
||||
{ type: 1, pts: 7192502226, ccData: 61284 },
|
||||
{ type: 0, pts: 7192502226, ccData: 49743 },
|
||||
{ type: 3, pts: 7192505106, ccData: 49954 },
|
||||
{ type: 2, pts: 7192505106, ccData: 0 },
|
||||
{ type: 0, pts: 7192505106, ccData: 50393 },
|
||||
{ type: 1, pts: 7192505106, ccData: 29472 },
|
||||
{ type: 2, pts: 7192505106, ccData: 16975 },
|
||||
{ type: 2, pts: 7192508166, ccData: 17497 },
|
||||
{ type: 3, pts: 7192508166, ccData: 802 },
|
||||
{ type: 0, pts: 7192508166, ccData: 44672 },
|
||||
{ type: 2, pts: 7192508166, ccData: 0 },
|
||||
{ type: 1, pts: 7192508166, ccData: 389 },
|
||||
{ type: 2, pts: 7192511226, ccData: 11776 },
|
||||
{ type: 2, pts: 7192511226, ccData: 0 },
|
||||
{ type: 1, pts: 7192511226, ccData: 51396 },
|
||||
{ type: 0, pts: 7192511226, ccData: 37935 },
|
||||
{ type: 3, pts: 7192511226, ccData: 17444 },
|
||||
{ type: 0, pts: 7192514196, ccData: 37935 },
|
||||
{ type: 2, pts: 7192514196, ccData: 35842 },
|
||||
{ type: 2, pts: 7192514196, ccData: 35073 },
|
||||
{ type: 2, pts: 7192514196, ccData: 0 },
|
||||
{ type: 1, pts: 7192514196, ccData: 36831 },
|
||||
{ type: 0, pts: 7192517256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192517256, ccData: 258 },
|
||||
{ type: 1, pts: 7192520226, ccData: 16448 },
|
||||
{ type: 0, pts: 7192520226, ccData: 32896 },
|
||||
{ type: 1, pts: 7192523196, ccData: 16448 },
|
||||
{ type: 0, pts: 7192523196, ccData: 32896 },
|
||||
{ type: 1, pts: 7192526256, ccData: 16512 },
|
||||
{ type: 0, pts: 7192526256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192529136, ccData: 36782 },
|
||||
{ type: 0, pts: 7192529136, ccData: 32896 },
|
||||
{ type: 1, pts: 7192532196, ccData: 387 },
|
||||
{ type: 0, pts: 7192532196, ccData: 32896 },
|
||||
{ type: 1, pts: 7192535256, ccData: 52975 },
|
||||
{ type: 0, pts: 7192535256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192538226, ccData: 62196 },
|
||||
{ type: 0, pts: 7192538226, ccData: 32896 },
|
||||
{ type: 1, pts: 7192541286, ccData: 26656 },
|
||||
{ type: 0, pts: 7192541286, ccData: 32896 },
|
||||
{ type: 1, pts: 7192544256, ccData: 22511 },
|
||||
{ type: 0, pts: 7192544256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192547226, ccData: 61284 },
|
||||
{ type: 0, pts: 7192547226, ccData: 32896 },
|
||||
{ type: 1, pts: 7192550196, ccData: 29472 },
|
||||
{ type: 0, pts: 7192550196, ccData: 32896 },
|
||||
{ type: 0, pts: 7192553166, ccData: 32896 },
|
||||
{ type: 1, pts: 7192553166, ccData: 19553 },
|
||||
{ type: 0, pts: 7192556226, ccData: 32896 },
|
||||
{ type: 1, pts: 7192556226, ccData: 63418 },
|
||||
{ type: 1, pts: 7192559286, ccData: 8271 },
|
||||
{ type: 0, pts: 7192559286, ccData: 32896 },
|
||||
{ type: 1, pts: 7192562256, ccData: 28192 },
|
||||
{ type: 0, pts: 7192562256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192565316, ccData: 62568 },
|
||||
{ type: 0, pts: 7192565316, ccData: 32896 },
|
||||
{ type: 1, pts: 7192568286, ccData: 58656 },
|
||||
{ type: 0, pts: 7192568286, ccData: 32896 },
|
||||
{ type: 1, pts: 7192571256, ccData: 51317 },
|
||||
{ type: 0, pts: 7192571256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192574226, ccData: 28404 },
|
||||
{ type: 0, pts: 7192574226, ccData: 32896 },
|
||||
{ type: 1, pts: 7192577196, ccData: 8360 },
|
||||
{ type: 0, pts: 7192577196, ccData: 32896 },
|
||||
{ type: 0, pts: 7192580256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192580256, ccData: 54245 },
|
||||
{ type: 1, pts: 7192583226, ccData: 36667 },
|
||||
{ type: 0, pts: 7192583226, ccData: 32896 },
|
||||
{ type: 1, pts: 7192586286, ccData: 258 },
|
||||
{ type: 0, pts: 7192586286, ccData: 32896 },
|
||||
{ type: 0, pts: 7192589346, ccData: 32896 },
|
||||
{ type: 1, pts: 7192589346, ccData: 16448 },
|
||||
{ type: 1, pts: 7192592316, ccData: 16448 },
|
||||
{ type: 0, pts: 7192592316, ccData: 32896 },
|
||||
{ type: 0, pts: 7192595286, ccData: 32896 },
|
||||
{ type: 1, pts: 7192595286, ccData: 16512 },
|
||||
{ type: 0, pts: 7192598256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192598256, ccData: 36782 },
|
||||
{ type: 1, pts: 7192601226, ccData: 387 },
|
||||
{ type: 0, pts: 7192601226, ccData: 32896 },
|
||||
{ type: 0, pts: 7192604286, ccData: 32896 },
|
||||
{ type: 1, pts: 7192604286, ccData: 52975 },
|
||||
{ type: 1, pts: 7192607256, ccData: 62196 },
|
||||
{ type: 0, pts: 7192607256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192610316, ccData: 26656 },
|
||||
{ type: 0, pts: 7192610316, ccData: 32896 },
|
||||
{ type: 0, pts: 7192613376, ccData: 32896 },
|
||||
{ type: 1, pts: 7192613376, ccData: 22511 },
|
||||
{ type: 0, pts: 7192616346, ccData: 32896 },
|
||||
{ type: 1, pts: 7192616346, ccData: 61284 },
|
||||
{ type: 0, pts: 7192619316, ccData: 32896 },
|
||||
{ type: 1, pts: 7192619316, ccData: 29472 },
|
||||
{ type: 0, pts: 7192622286, ccData: 32896 },
|
||||
{ type: 1, pts: 7192622286, ccData: 19553 },
|
||||
{ type: 1, pts: 7192625256, ccData: 63418 },
|
||||
{ type: 0, pts: 7192625256, ccData: 32896 },
|
||||
{ type: 1, pts: 7192628316, ccData: 8271 },
|
||||
{ type: 0, pts: 7192628316, ccData: 32896 },
|
||||
{ type: 0, pts: 7192631286, ccData: 37920 },
|
||||
{ type: 1, pts: 7192631286, ccData: 28192 },
|
||||
{ type: 1, pts: 7192634346, ccData: 62568 },
|
||||
{ type: 0, pts: 7192634346, ccData: 37920 },
|
||||
{ type: 1, pts: 7192637406, ccData: 58656 },
|
||||
{ type: 3, pts: 7192637406, ccData: 33570 },
|
||||
{ type: 0, pts: 7192637406, ccData: 38062 },
|
||||
{ type: 2, pts: 7192640286, ccData: 0 },
|
||||
{ type: 1, pts: 7192640286, ccData: 51317 },
|
||||
{ type: 0, pts: 7192640286, ccData: 38062 },
|
||||
{ type: 2, pts: 7192640286, ccData: 36094 },
|
||||
{ type: 1, pts: 7192643346, ccData: 28404 },
|
||||
{ type: 3, pts: 7192643346, ccData: 51761 },
|
||||
{ type: 0, pts: 7192643346, ccData: 38096 },
|
||||
{ type: 1, pts: 7192646316, ccData: 8360 },
|
||||
{ type: 0, pts: 7192646316, ccData: 38096 },
|
||||
{ type: 2, pts: 7192646316, ccData: 39195 },
|
||||
{ type: 2, pts: 7192646316, ccData: 16640 },
|
||||
{ type: 2, pts: 7192646316, ccData: 31 },
|
||||
{ type: 2, pts: 7192646316, ccData: 5264 },
|
||||
{ type: 2, pts: 7192646316, ccData: 1283 },
|
||||
{ type: 2, pts: 7192646316, ccData: 37162 },
|
||||
{ type: 2, pts: 7192646316, ccData: 42 },
|
||||
{ type: 2, pts: 7192646316, ccData: 37376 },
|
||||
{ type: 2, pts: 7192646316, ccData: 0 },
|
||||
{ type: 3, pts: 7192649286, ccData: 802 },
|
||||
{ type: 0, pts: 7192649286, ccData: 22341 },
|
||||
{ type: 1, pts: 7192649286, ccData: 54245 },
|
||||
{ type: 0, pts: 7192652346, ccData: 8276 },
|
||||
{ type: 1, pts: 7192652346, ccData: 36667 },
|
||||
{ type: 2, pts: 7192652346, ccData: 0 },
|
||||
{ type: 3, pts: 7192652346, ccData: 17186 },
|
||||
{ type: 2, pts: 7192652346, ccData: 22341 },
|
||||
{ type: 0, pts: 7192655316, ccData: 21209 },
|
||||
{ type: 2, pts: 7192655316, ccData: 8276 },
|
||||
{ type: 1, pts: 7192655316, ccData: 258 },
|
||||
{ type: 3, pts: 7192655316, ccData: 33570 },
|
||||
{ type: 2, pts: 7192655316, ccData: 0 },
|
||||
{ type: 1, pts: 7192658376, ccData: 16448 },
|
||||
{ type: 0, pts: 7192658376, ccData: 8398 },
|
||||
{ type: 2, pts: 7192658376, ccData: 21081 },
|
||||
{ type: 2, pts: 7192658376, ccData: 0 },
|
||||
{ type: 3, pts: 7192658376, ccData: 49954 },
|
||||
{ type: 0, pts: 7192661346, ccData: 20308 },
|
||||
{ type: 2, pts: 7192661346, ccData: 8270 },
|
||||
{ type: 2, pts: 7192661346, ccData: 0 },
|
||||
{ type: 3, pts: 7192661346, ccData: 802 },
|
||||
{ type: 1, pts: 7192661346, ccData: 16448 },
|
||||
{ type: 0, pts: 7192664316, ccData: 8276 },
|
||||
{ type: 2, pts: 7192664316, ccData: 20308 },
|
||||
{ type: 2, pts: 7192664316, ccData: 0 },
|
||||
{ type: 3, pts: 7192664316, ccData: 17186 },
|
||||
{ type: 1, pts: 7192664316, ccData: 16512 },
|
||||
{ type: 0, pts: 7192667376, ccData: 20256 },
|
||||
{ type: 1, pts: 7192667376, ccData: 36782 },
|
||||
{ type: 2, pts: 7192667376, ccData: 8276 },
|
||||
{ type: 2, pts: 7192667376, ccData: 0 },
|
||||
{ type: 3, pts: 7192667376, ccData: 33570 },
|
||||
{ type: 3, pts: 7192670346, ccData: 49954 },
|
||||
{ type: 1, pts: 7192670346, ccData: 387 },
|
||||
{ type: 0, pts: 7192670346, ccData: 53461 },
|
||||
{ type: 2, pts: 7192670346, ccData: 20256 },
|
||||
{ type: 2, pts: 7192670346, ccData: 0 },
|
||||
{ type: 0, pts: 7192673406, ccData: 21536 },
|
||||
{ type: 3, pts: 7192673406, ccData: 802 },
|
||||
{ type: 2, pts: 7192673406, ccData: 0 },
|
||||
{ type: 2, pts: 7192673406, ccData: 20565 },
|
||||
{ type: 1, pts: 7192673406, ccData: 52975 },
|
||||
{ type: 1, pts: 7192676376, ccData: 62196 },
|
||||
{ type: 2, pts: 7192676376, ccData: 21536 },
|
||||
{ type: 2, pts: 7192676376, ccData: 0 },
|
||||
{ type: 3, pts: 7192676376, ccData: 17186 },
|
||||
{ type: 0, pts: 7192676376, ccData: 49614 },
|
||||
{ type: 0, pts: 7192679346, ccData: 8385 },
|
||||
{ type: 2, pts: 7192679346, ccData: 16718 },
|
||||
{ type: 1, pts: 7192679346, ccData: 26656 },
|
||||
{ type: 3, pts: 7192679346, ccData: 33570 },
|
||||
{ type: 2, pts: 7192679346, ccData: 0 },
|
||||
{ type: 1, pts: 7192682406, ccData: 22511 },
|
||||
{ type: 0, pts: 7192682406, ccData: 52809 },
|
||||
{ type: 2, pts: 7192682406, ccData: 8257 },
|
||||
{ type: 2, pts: 7192682406, ccData: 0 },
|
||||
{ type: 3, pts: 7192682406, ccData: 49954 },
|
||||
{ type: 0, pts: 7192685286, ccData: 52673 },
|
||||
{ type: 2, pts: 7192685286, ccData: 20041 },
|
||||
{ type: 2, pts: 7192685286, ccData: 0 },
|
||||
{ type: 3, pts: 7192685286, ccData: 802 },
|
||||
{ type: 1, pts: 7192685286, ccData: 61284 },
|
||||
{ type: 1, pts: 7192688346, ccData: 389 },
|
||||
{ type: 0, pts: 7192688346, ccData: 19488 },
|
||||
{ type: 2, pts: 7192688346, ccData: 19777 },
|
||||
{ type: 2, pts: 7192688346, ccData: 0 },
|
||||
{ type: 3, pts: 7192688346, ccData: 17186 },
|
||||
{ type: 3, pts: 7192691406, ccData: 33570 },
|
||||
{ type: 2, pts: 7192691406, ccData: 0 },
|
||||
{ type: 2, pts: 7192691406, ccData: 19488 },
|
||||
{ type: 0, pts: 7192691406, ccData: 50255 },
|
||||
{ type: 1, pts: 7192691406, ccData: 51396 },
|
||||
{ type: 1, pts: 7192694376, ccData: 36831 },
|
||||
{ type: 0, pts: 7192694376, ccData: 22478 },
|
||||
{ type: 2, pts: 7192694376, ccData: 17487 },
|
||||
{ type: 2, pts: 7192694376, ccData: 0 },
|
||||
{ type: 3, pts: 7192694376, ccData: 49954 },
|
||||
{ type: 3, pts: 7192697436, ccData: 2609 },
|
||||
{ type: 1, pts: 7192697436, ccData: 258 },
|
||||
{ type: 2, pts: 7192697436, ccData: 22350 },
|
||||
{ type: 2, pts: 7192697436, ccData: 0 },
|
||||
{ type: 0, pts: 7192697436, ccData: 38130 },
|
||||
{ type: 2, pts: 7192700406, ccData: 1024 },
|
||||
{ type: 0, pts: 7192700406, ccData: 38130 },
|
||||
{ type: 2, pts: 7192700406, ccData: 16640 },
|
||||
{ type: 2, pts: 7192700406, ccData: 287 },
|
||||
{ type: 2, pts: 7192700406, ccData: 4240 },
|
||||
{ type: 2, pts: 7192700406, ccData: 1283 },
|
||||
{ type: 2, pts: 7192700406, ccData: 37162 },
|
||||
{ type: 2, pts: 7192700406, ccData: 0 },
|
||||
{ type: 2, pts: 7192700406, ccData: 37377 },
|
||||
{ type: 2, pts: 7192700406, ccData: 39195 },
|
||||
{ type: 1, pts: 7192700406, ccData: 16448 },
|
||||
{ type: 0, pts: 7192703376, ccData: 38818 },
|
||||
{ type: 3, pts: 7192703376, ccData: 17187 },
|
||||
{ type: 1, pts: 7192703376, ccData: 16448 },
|
||||
{ type: 1, pts: 7192706436, ccData: 16512 },
|
||||
{ type: 0, pts: 7192706436, ccData: 38818 },
|
||||
{ type: 2, pts: 7192706436, ccData: 37377 },
|
||||
{ type: 2, pts: 7192706436, ccData: 1536 },
|
||||
{ type: 3, pts: 7192709316, ccData: 33570 },
|
||||
{ type: 1, pts: 7192709316, ccData: 36782 },
|
||||
{ type: 0, pts: 7192709316, ccData: 18758 },
|
||||
{ type: 1, pts: 7192712376, ccData: 387 },
|
||||
{ type: 0, pts: 7192712376, ccData: 8279 },
|
||||
{ type: 2, pts: 7192712376, ccData: 18758 },
|
||||
{ type: 2, pts: 7192712376, ccData: 0 },
|
||||
{ type: 3, pts: 7192712376, ccData: 49954 },
|
||||
{ type: 1, pts: 7192715436, ccData: 52975 },
|
||||
{ type: 0, pts: 7192715436, ccData: 17696 },
|
||||
{ type: 2, pts: 7192715436, ccData: 8279 },
|
||||
{ type: 2, pts: 7192715436, ccData: 0 },
|
||||
{ type: 3, pts: 7192715436, ccData: 802 },
|
||||
{ type: 3, pts: 7192718406, ccData: 17186 },
|
||||
{ type: 1, pts: 7192718406, ccData: 62196 },
|
||||
{ type: 2, pts: 7192718406, ccData: 0 },
|
||||
{ type: 0, pts: 7192718406, ccData: 50255 },
|
||||
{ type: 2, pts: 7192718406, ccData: 17696 },
|
||||
{ type: 3, pts: 7192721466, ccData: 33570 },
|
||||
{ type: 2, pts: 7192721466, ccData: 17487 },
|
||||
{ type: 0, pts: 7192721466, ccData: 52903 },
|
||||
{ type: 1, pts: 7192721466, ccData: 26656 },
|
||||
{ type: 2, pts: 7192721466, ccData: 0 },
|
||||
{ type: 1, pts: 7192724436, ccData: 22511 },
|
||||
{ type: 0, pts: 7192724436, ccData: 21536 },
|
||||
{ type: 2, pts: 7192724436, ccData: 20007 },
|
||||
{ type: 2, pts: 7192724436, ccData: 0 },
|
||||
{ type: 3, pts: 7192724436, ccData: 49954 },
|
||||
{ type: 2, pts: 7192727406, ccData: 0 },
|
||||
{ type: 2, pts: 7192727406, ccData: 21536 },
|
||||
{ type: 0, pts: 7192727406, ccData: 51393 },
|
||||
{ type: 1, pts: 7192727406, ccData: 61284 },
|
||||
{ type: 3, pts: 7192727406, ccData: 802 },
|
||||
{ type: 0, pts: 7192730376, ccData: 54853 },
|
||||
{ type: 1, pts: 7192730376, ccData: 29472 },
|
||||
{ type: 2, pts: 7192730376, ccData: 18497 },
|
||||
{ type: 2, pts: 7192730376, ccData: 0 },
|
||||
{ type: 3, pts: 7192730376, ccData: 17186 },
|
||||
{ type: 2, pts: 7192733346, ccData: 22085 },
|
||||
{ type: 3, pts: 7192733346, ccData: 33570 },
|
||||
{ type: 0, pts: 7192733346, ccData: 8276 },
|
||||
{ type: 1, pts: 7192733346, ccData: 19553 },
|
||||
{ type: 2, pts: 7192733346, ccData: 0 },
|
||||
{ type: 1, pts: 7192736406, ccData: 63418 },
|
||||
{ type: 2, pts: 7192736406, ccData: 0 },
|
||||
{ type: 3, pts: 7192736406, ccData: 49954 },
|
||||
{ type: 2, pts: 7192736406, ccData: 8276 },
|
||||
{ type: 0, pts: 7192736406, ccData: 20398 },
|
||||
{ type: 1, pts: 7192739466, ccData: 8271 },
|
||||
{ type: 0, pts: 7192739466, ccData: 37935 },
|
||||
{ type: 2, pts: 7192739466, ccData: 20270 },
|
||||
{ type: 2, pts: 7192739466, ccData: 0 },
|
||||
{ type: 3, pts: 7192739466, ccData: 1060 },
|
||||
{ type: 0, pts: 7192742436, ccData: 37935 },
|
||||
{ type: 2, pts: 7192742436, ccData: 35841 },
|
||||
{ type: 2, pts: 7192742436, ccData: 35074 },
|
||||
{ type: 2, pts: 7192742436, ccData: 0 },
|
||||
{ type: 1, pts: 7192742436, ccData: 28192 },
|
||||
{ type: 1, pts: 7192745496, ccData: 62568 },
|
||||
{ type: 0, pts: 7192745496, ccData: 32896 },
|
||||
{ type: 1, pts: 7192748466, ccData: 58656 },
|
||||
{ type: 0, pts: 7192748466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192751436, ccData: 51317 },
|
||||
{ type: 0, pts: 7192751436, ccData: 32896 },
|
||||
{ type: 1, pts: 7192754406, ccData: 28404 },
|
||||
{ type: 0, pts: 7192754406, ccData: 32896 },
|
||||
{ type: 0, pts: 7192757376, ccData: 32896 },
|
||||
{ type: 1, pts: 7192757376, ccData: 8360 },
|
||||
{ type: 1, pts: 7192760436, ccData: 54245 },
|
||||
{ type: 0, pts: 7192760436, ccData: 32896 },
|
||||
{ type: 1, pts: 7192763406, ccData: 36667 },
|
||||
{ type: 0, pts: 7192763406, ccData: 32896 },
|
||||
{ type: 1, pts: 7192766466, ccData: 258 },
|
||||
{ type: 0, pts: 7192766466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192769526, ccData: 16448 },
|
||||
{ type: 0, pts: 7192769526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192772496, ccData: 16448 },
|
||||
{ type: 0, pts: 7192772496, ccData: 32896 },
|
||||
{ type: 1, pts: 7192775466, ccData: 16512 },
|
||||
{ type: 0, pts: 7192775466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192778436, ccData: 36782 },
|
||||
{ type: 0, pts: 7192778436, ccData: 32896 },
|
||||
{ type: 1, pts: 7192781406, ccData: 387 },
|
||||
{ type: 0, pts: 7192781406, ccData: 32896 },
|
||||
{ type: 1, pts: 7192784466, ccData: 52975 },
|
||||
{ type: 0, pts: 7192784466, ccData: 32896 },
|
||||
{ type: 0, pts: 7192787436, ccData: 32896 },
|
||||
{ type: 1, pts: 7192787436, ccData: 62196 },
|
||||
{ type: 1, pts: 7192790496, ccData: 26656 },
|
||||
{ type: 0, pts: 7192790496, ccData: 32896 },
|
||||
{ type: 0, pts: 7192793556, ccData: 32896 },
|
||||
{ type: 1, pts: 7192793556, ccData: 22511 },
|
||||
{ type: 0, pts: 7192796526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192796526, ccData: 61284 },
|
||||
{ type: 1, pts: 7192799496, ccData: 29472 },
|
||||
{ type: 0, pts: 7192799496, ccData: 32896 },
|
||||
{ type: 1, pts: 7192802466, ccData: 19553 },
|
||||
{ type: 0, pts: 7192802466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192805436, ccData: 63418 },
|
||||
{ type: 0, pts: 7192805436, ccData: 32896 },
|
||||
{ type: 1, pts: 7192808496, ccData: 8271 },
|
||||
{ type: 0, pts: 7192808496, ccData: 32896 },
|
||||
{ type: 0, pts: 7192811466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192811466, ccData: 28192 },
|
||||
{ type: 1, pts: 7192814526, ccData: 62568 },
|
||||
{ type: 0, pts: 7192814526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192817586, ccData: 58656 },
|
||||
{ type: 0, pts: 7192817586, ccData: 32896 },
|
||||
{ type: 0, pts: 7192820466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192820466, ccData: 51317 },
|
||||
{ type: 0, pts: 7192823526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192823526, ccData: 28404 },
|
||||
{ type: 1, pts: 7192826496, ccData: 8360 },
|
||||
{ type: 0, pts: 7192826496, ccData: 32896 },
|
||||
{ type: 0, pts: 7192829466, ccData: 32896 },
|
||||
{ type: 1, pts: 7192829466, ccData: 54245 },
|
||||
{ type: 1, pts: 7192832526, ccData: 36667 },
|
||||
{ type: 0, pts: 7192832526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192835496, ccData: 258 },
|
||||
{ type: 0, pts: 7192835496, ccData: 32896 },
|
||||
{ type: 1, pts: 7192838556, ccData: 16448 },
|
||||
{ type: 0, pts: 7192838556, ccData: 32896 },
|
||||
{ type: 0, pts: 7192841526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192841526, ccData: 16448 },
|
||||
{ type: 1, pts: 7192844496, ccData: 16512 },
|
||||
{ type: 0, pts: 7192844496, ccData: 32896 },
|
||||
{ type: 1, pts: 7192847556, ccData: 36782 },
|
||||
{ type: 0, pts: 7192847556, ccData: 32896 },
|
||||
{ type: 1, pts: 7192850526, ccData: 387 },
|
||||
{ type: 0, pts: 7192850526, ccData: 32896 },
|
||||
{ type: 1, pts: 7192853586, ccData: 52975 },
|
||||
{ type: 0, pts: 7192853586, ccData: 37920 },
|
||||
{ type: 0, pts: 7192856556, ccData: 37920 },
|
||||
{ type: 1, pts: 7192856556, ccData: 62196 },
|
||||
{ type: 1, pts: 7192859526, ccData: 26656 },
|
||||
{ type: 0, pts: 7192859526, ccData: 38062 },
|
||||
{ type: 3, pts: 7192859526, ccData: 17186 },
|
||||
{ type: 1, pts: 7192862586, ccData: 22511 },
|
||||
{ type: 0, pts: 7192862586, ccData: 38062 },
|
||||
{ type: 2, pts: 7192862586, ccData: 36093 },
|
||||
{ type: 2, pts: 7192862586, ccData: 0 },
|
||||
{ type: 0, pts: 7192865466, ccData: 4982 },
|
||||
{ type: 1, pts: 7192865466, ccData: 61284 },
|
||||
{ type: 3, pts: 7192865466, ccData: 35377 },
|
||||
{ type: 2, pts: 7192868526, ccData: 3072 },
|
||||
{ type: 2, pts: 7192868526, ccData: 37376 },
|
||||
{ type: 2, pts: 7192868526, ccData: 42 },
|
||||
{ type: 2, pts: 7192868526, ccData: 37162 },
|
||||
{ type: 1, pts: 7192868526, ccData: 29472 },
|
||||
{ type: 0, pts: 7192868526, ccData: 4982 },
|
||||
{ type: 2, pts: 7192868526, ccData: 38939 },
|
||||
{ type: 2, pts: 7192868526, ccData: 15360 },
|
||||
{ type: 2, pts: 7192868526, ccData: 31 },
|
||||
{ type: 2, pts: 7192868526, ccData: 5264 },
|
||||
{ type: 2, pts: 7192868526, ccData: 1283 },
|
||||
{ type: 1, pts: 7192871586, ccData: 389 },
|
||||
{ type: 0, pts: 7192871586, ccData: 52833 },
|
||||
{ type: 3, pts: 7192871586, ccData: 49954 },
|
||||
{ type: 2, pts: 7192874556, ccData: 0 },
|
||||
{ type: 1, pts: 7192874556, ccData: 51396 },
|
||||
{ type: 0, pts: 7192874556, ccData: 62194 },
|
||||
{ type: 2, pts: 7192874556, ccData: 20065 },
|
||||
{ type: 3, pts: 7192874556, ccData: 802 },
|
||||
{ type: 0, pts: 7192877616, ccData: 25076 },
|
||||
{ type: 2, pts: 7192877616, ccData: 29298 },
|
||||
{ type: 3, pts: 7192877616, ccData: 17186 },
|
||||
{ type: 1, pts: 7192877616, ccData: 36831 },
|
||||
{ type: 2, pts: 7192877616, ccData: 0 },
|
||||
{ type: 3, pts: 7192880586, ccData: 33570 },
|
||||
{ type: 2, pts: 7192880586, ccData: 0 },
|
||||
{ type: 2, pts: 7192880586, ccData: 24948 },
|
||||
{ type: 0, pts: 7192880586, ccData: 61426 },
|
||||
{ type: 1, pts: 7192880586, ccData: 258 },
|
||||
{ type: 3, pts: 7192883556, ccData: 49954 },
|
||||
{ type: 2, pts: 7192883556, ccData: 0 },
|
||||
{ type: 2, pts: 7192883556, ccData: 28530 },
|
||||
{ type: 0, pts: 7192883556, ccData: 47744 },
|
||||
{ type: 1, pts: 7192883556, ccData: 16448 },
|
||||
{ type: 3, pts: 7192886616, ccData: 2609 },
|
||||
{ type: 1, pts: 7192886616, ccData: 16448 },
|
||||
{ type: 0, pts: 7192886616, ccData: 38096 },
|
||||
{ type: 2, pts: 7192886616, ccData: 14848 },
|
||||
{ type: 2, pts: 7192886616, ccData: 0 },
|
||||
{ type: 2, pts: 7192889496, ccData: 287 },
|
||||
{ type: 2, pts: 7192889496, ccData: 15360 },
|
||||
{ type: 2, pts: 7192889496, ccData: 38939 },
|
||||
{ type: 0, pts: 7192889496, ccData: 38096 },
|
||||
{ type: 2, pts: 7192889496, ccData: 0 },
|
||||
{ type: 2, pts: 7192889496, ccData: 37162 },
|
||||
{ type: 2, pts: 7192889496, ccData: 1283 },
|
||||
{ type: 2, pts: 7192889496, ccData: 4240 },
|
||||
{ type: 2, pts: 7192889496, ccData: 0 },
|
||||
{ type: 2, pts: 7192889496, ccData: 37377 },
|
||||
{ type: 1, pts: 7192889496, ccData: 16512 },
|
||||
{ type: 1, pts: 7192892556, ccData: 36782 },
|
||||
{ type: 3, pts: 7192892556, ccData: 17187 },
|
||||
{ type: 0, pts: 7192892556, ccData: 38817 },
|
||||
{ type: 0, pts: 7192895616, ccData: 38817 },
|
||||
{ type: 1, pts: 7192895616, ccData: 387 },
|
||||
{ type: 2, pts: 7192895616, ccData: 256 },
|
||||
{ type: 2, pts: 7192895616, ccData: 37377 },
|
||||
{ type: 1, pts: 7192898586, ccData: 52975 },
|
||||
{ type: 0, pts: 7192898586, ccData: 18758 },
|
||||
{ type: 3, pts: 7192898586, ccData: 33570 },
|
||||
{ type: 0, pts: 7192901646, ccData: 8276 },
|
||||
{ type: 2, pts: 7192901646, ccData: 18758 },
|
||||
{ type: 2, pts: 7192901646, ccData: 0 },
|
||||
{ type: 3, pts: 7192901646, ccData: 49954 },
|
||||
{ type: 1, pts: 7192901646, ccData: 62196 },
|
||||
{ type: 1, pts: 7192904616, ccData: 26656 },
|
||||
{ type: 0, pts: 7192904616, ccData: 51269 },
|
||||
{ type: 2, pts: 7192904616, ccData: 8276 },
|
||||
{ type: 2, pts: 7192904616, ccData: 0 },
|
||||
{ type: 3, pts: 7192904616, ccData: 802 },
|
||||
{ type: 3, pts: 7192907586, ccData: 17186 },
|
||||
{ type: 2, pts: 7192907586, ccData: 0 },
|
||||
{ type: 2, pts: 7192907586, ccData: 18501 },
|
||||
{ type: 0, pts: 7192907586, ccData: 8403 },
|
||||
{ type: 1, pts: 7192907586, ccData: 22511 },
|
||||
{ type: 1, pts: 7192910556, ccData: 61284 },
|
||||
{ type: 0, pts: 7192910556, ccData: 18755 },
|
||||
{ type: 2, pts: 7192910556, ccData: 8275 },
|
||||
{ type: 2, pts: 7192910556, ccData: 0 },
|
||||
{ type: 3, pts: 7192910556, ccData: 33570 },
|
||||
{ type: 3, pts: 7192913526, ccData: 49954 },
|
||||
{ type: 1, pts: 7192913526, ccData: 29472 },
|
||||
{ type: 2, pts: 7192913526, ccData: 18755 },
|
||||
{ type: 2, pts: 7192913526, ccData: 0 },
|
||||
{ type: 0, pts: 7192913526, ccData: 52000 },
|
||||
{ type: 0, pts: 7192916586, ccData: 49614 },
|
||||
{ type: 2, pts: 7192916586, ccData: 19232 },
|
||||
{ type: 2, pts: 7192916586, ccData: 0 },
|
||||
{ type: 3, pts: 7192916586, ccData: 802 },
|
||||
{ type: 1, pts: 7192916586, ccData: 19553 },
|
||||
{ type: 0, pts: 7192919646, ccData: 50208 },
|
||||
{ type: 1, pts: 7192919646, ccData: 63418 },
|
||||
{ type: 2, pts: 7192919646, ccData: 16718 },
|
||||
{ type: 2, pts: 7192919646, ccData: 0 },
|
||||
{ type: 3, pts: 7192919646, ccData: 17186 },
|
||||
{ type: 3, pts: 7192922616, ccData: 33570 },
|
||||
{ type: 1, pts: 7192922616, ccData: 8271 },
|
||||
{ type: 0, pts: 7192922616, ccData: 17989 },
|
||||
{ type: 2, pts: 7192922616, ccData: 17440 },
|
||||
{ type: 2, pts: 7192922616, ccData: 0 },
|
||||
{ type: 2, pts: 7192925676, ccData: 17989 },
|
||||
{ type: 3, pts: 7192925676, ccData: 49954 },
|
||||
{ type: 0, pts: 7192925676, ccData: 49490 },
|
||||
{ type: 1, pts: 7192925676, ccData: 28192 },
|
||||
{ type: 2, pts: 7192925676, ccData: 0 },
|
||||
{ type: 0, pts: 7192928646, ccData: 19525 },
|
||||
{ type: 2, pts: 7192928646, ccData: 16722 },
|
||||
{ type: 2, pts: 7192928646, ccData: 0 },
|
||||
{ type: 3, pts: 7192928646, ccData: 802 },
|
||||
{ type: 1, pts: 7192928646, ccData: 62568 },
|
||||
{ type: 0, pts: 7192931616, ccData: 54227 },
|
||||
{ type: 1, pts: 7192931616, ccData: 58656 },
|
||||
{ type: 3, pts: 7192931616, ccData: 17186 },
|
||||
{ type: 2, pts: 7192931616, ccData: 19525 },
|
||||
{ type: 2, pts: 7192931616, ccData: 0 },
|
||||
{ type: 1, pts: 7192934586, ccData: 51317 },
|
||||
{ type: 0, pts: 7192934586, ccData: 8397 },
|
||||
{ type: 2, pts: 7192934586, ccData: 21331 },
|
||||
{ type: 2, pts: 7192934586, ccData: 0 },
|
||||
{ type: 3, pts: 7192934586, ccData: 33570 },
|
||||
{ type: 2, pts: 7192937556, ccData: 0 },
|
||||
{ type: 0, pts: 7192937556, ccData: 20303 },
|
||||
{ type: 2, pts: 7192937556, ccData: 8269 },
|
||||
{ type: 1, pts: 7192937556, ccData: 28404 },
|
||||
{ type: 3, pts: 7192937556, ccData: 49954 },
|
||||
{ type: 1, pts: 7192940616, ccData: 8360 },
|
||||
{ type: 0, pts: 7192940616, ccData: 54085 },
|
||||
{ type: 2, pts: 7192940616, ccData: 20303 },
|
||||
{ type: 2, pts: 7192940616, ccData: 0 },
|
||||
{ type: 3, pts: 7192940616, ccData: 802 },
|
||||
{ type: 0, pts: 7192943586, ccData: 38000 },
|
||||
{ type: 3, pts: 7192943586, ccData: 18993 },
|
||||
{ type: 1, pts: 7192943586, ccData: 54245 },
|
||||
{ type: 2, pts: 7192943586, ccData: 0 },
|
||||
{ type: 2, pts: 7192943586, ccData: 21317 },
|
||||
{ type: 2, pts: 7192946646, ccData: 1283 },
|
||||
{ type: 1, pts: 7192946646, ccData: 36667 },
|
||||
{ type: 2, pts: 7192946646, ccData: 38939 },
|
||||
{ type: 2, pts: 7192946646, ccData: 15360 },
|
||||
{ type: 2, pts: 7192946646, ccData: 543 },
|
||||
{ type: 2, pts: 7192946646, ccData: 4240 },
|
||||
{ type: 0, pts: 7192946646, ccData: 38000 },
|
||||
{ type: 2, pts: 7192946646, ccData: 37162 },
|
||||
{ type: 2, pts: 7192946646, ccData: 0 },
|
||||
{ type: 2, pts: 7192946646, ccData: 37378 },
|
||||
{ type: 2, pts: 7192946646, ccData: 0 },
|
||||
{ type: 3, pts: 7192949706, ccData: 33571 },
|
||||
{ type: 0, pts: 7192949706, ccData: 38817 },
|
||||
{ type: 1, pts: 7192949706, ccData: 258 },
|
||||
{ type: 2, pts: 7192952676, ccData: 256 },
|
||||
{ type: 1, pts: 7192952676, ccData: 16448 },
|
||||
{ type: 0, pts: 7192952676, ccData: 38817 },
|
||||
{ type: 2, pts: 7192952676, ccData: 37378 },
|
||||
{ type: 1, pts: 7192955646, ccData: 16448 },
|
||||
{ type: 0, pts: 7192955646, ccData: 22465 },
|
||||
{ type: 3, pts: 7192955646, ccData: 49954 },
|
||||
{ type: 3, pts: 7192958616, ccData: 802 },
|
||||
{ type: 2, pts: 7192958616, ccData: 22337 },
|
||||
{ type: 2, pts: 7192958616, ccData: 0 },
|
||||
{ type: 1, pts: 7192958616, ccData: 16512 },
|
||||
{ type: 0, pts: 7192958616, ccData: 54048 },
|
||||
{ type: 0, pts: 7192961586, ccData: 17228 },
|
||||
{ type: 2, pts: 7192961586, ccData: 21280 },
|
||||
{ type: 2, pts: 7192961586, ccData: 0 },
|
||||
{ type: 3, pts: 7192961586, ccData: 17186 },
|
||||
{ type: 1, pts: 7192961586, ccData: 36782 },
|
||||
{ type: 0, pts: 7192964646, ccData: 20435 },
|
||||
{ type: 2, pts: 7192964646, ccData: 17228 },
|
||||
{ type: 2, pts: 7192964646, ccData: 0 },
|
||||
{ type: 3, pts: 7192964646, ccData: 33570 },
|
||||
{ type: 1, pts: 7192964646, ccData: 387 },
|
||||
{ type: 0, pts: 7192967616, ccData: 17746 },
|
||||
{ type: 1, pts: 7192967616, ccData: 52975 },
|
||||
{ type: 2, pts: 7192967616, ccData: 0 },
|
||||
{ type: 2, pts: 7192967616, ccData: 20307 },
|
||||
{ type: 3, pts: 7192967616, ccData: 49954 },
|
||||
{ type: 1, pts: 7192970676, ccData: 62196 },
|
||||
{ type: 0, pts: 7192970676, ccData: 8276 },
|
||||
{ type: 2, pts: 7192970676, ccData: 17746 },
|
||||
{ type: 2, pts: 7192970676, ccData: 0 },
|
||||
{ type: 3, pts: 7192970676, ccData: 802 },
|
||||
{ type: 2, pts: 7192973736, ccData: 0 },
|
||||
{ type: 2, pts: 7192973736, ccData: 8276 },
|
||||
{ type: 3, pts: 7192973736, ccData: 17186 },
|
||||
{ type: 0, pts: 7192973736, ccData: 20256 },
|
||||
{ type: 1, pts: 7192973736, ccData: 26656 },
|
||||
{ type: 1, pts: 7192976706, ccData: 22511 },
|
||||
{ type: 0, pts: 7192976706, ccData: 49440 },
|
||||
{ type: 2, pts: 7192976706, ccData: 20256 },
|
||||
{ type: 2, pts: 7192976706, ccData: 0 },
|
||||
{ type: 3, pts: 7192976706, ccData: 33570 },
|
||||
{ type: 3, pts: 7192979676, ccData: 49954 },
|
||||
{ type: 2, pts: 7192979676, ccData: 0 },
|
||||
{ type: 2, pts: 7192979676, ccData: 16672 },
|
||||
{ type: 0, pts: 7192979676, ccData: 53327 },
|
||||
{ type: 1, pts: 7192979676, ccData: 61284 },
|
||||
{ type: 1, pts: 7192982646, ccData: 29472 },
|
||||
{ type: 0, pts: 7192982646, ccData: 53461 },
|
||||
{ type: 2, pts: 7192982646, ccData: 20559 },
|
||||
{ type: 2, pts: 7192982646, ccData: 0 },
|
||||
{ type: 3, pts: 7192982646, ccData: 802 },
|
||||
{ type: 3, pts: 7192985616, ccData: 17186 },
|
||||
{ type: 1, pts: 7192985616, ccData: 19553 },
|
||||
{ type: 2, pts: 7192985616, ccData: 20565 },
|
||||
{ type: 2, pts: 7192985616, ccData: 0 },
|
||||
{ type: 0, pts: 7192985616, ccData: 19649 },
|
||||
{ type: 2, pts: 7192988676, ccData: 19521 },
|
||||
{ type: 1, pts: 7192988676, ccData: 63418 },
|
||||
{ type: 0, pts: 7192988676, ccData: 21573 },
|
||||
{ type: 2, pts: 7192988676, ccData: 0 },
|
||||
{ type: 3, pts: 7192988676, ccData: 33570 },
|
||||
{ type: 2, pts: 7192991646, ccData: 0 },
|
||||
{ type: 2, pts: 7192991646, ccData: 21573 },
|
||||
{ type: 3, pts: 7192991646, ccData: 49954 },
|
||||
{ type: 1, pts: 7192991646, ccData: 8271 },
|
||||
{ type: 0, pts: 7192991646, ccData: 50208 },
|
||||
{ type: 1, pts: 7192994706, ccData: 28192 },
|
||||
{ type: 0, pts: 7192994706, ccData: 49490 },
|
||||
{ type: 2, pts: 7192994706, ccData: 17440 },
|
||||
{ type: 2, pts: 7192994706, ccData: 0 },
|
||||
{ type: 3, pts: 7192994706, ccData: 802 },
|
||||
{ type: 2, pts: 7192997766, ccData: 0 },
|
||||
{ type: 0, pts: 7192997766, ccData: 17857 },
|
||||
{ type: 3, pts: 7192997766, ccData: 17186 },
|
||||
{ type: 1, pts: 7192997766, ccData: 62568 },
|
||||
{ type: 2, pts: 7192997766, ccData: 16722 },
|
||||
{ type: 3, pts: 7193000646, ccData: 33570 },
|
||||
{ type: 1, pts: 7193000646, ccData: 58656 },
|
||||
{ type: 0, pts: 7193000646, ccData: 11392 },
|
||||
{ type: 2, pts: 7193000646, ccData: 17729 },
|
||||
{ type: 2, pts: 7193000646, ccData: 0 },
|
||||
{ type: 1, pts: 7193003706, ccData: 51317 },
|
||||
{ type: 2, pts: 7193003706, ccData: 11264 },
|
||||
{ type: 2, pts: 7193003706, ccData: 0 },
|
||||
{ type: 3, pts: 7193003706, ccData: 50212 },
|
||||
{ type: 0, pts: 7193003706, ccData: 37935 },
|
||||
{ type: 1, pts: 7193006676, ccData: 28404 },
|
||||
{ type: 0, pts: 7193006676, ccData: 37935 },
|
||||
{ type: 2, pts: 7193006676, ccData: 35842 },
|
||||
{ type: 2, pts: 7193006676, ccData: 35073 },
|
||||
{ type: 2, pts: 7193006676, ccData: 0 },
|
||||
{ type: 1, pts: 7193009646, ccData: 8360 },
|
||||
{ type: 0, pts: 7193009646, ccData: 32896 },
|
||||
{ type: 1, pts: 7193012706, ccData: 54245 },
|
||||
{ type: 0, pts: 7193012706, ccData: 32896 },
|
||||
{ type: 1, pts: 7193015676, ccData: 36667 },
|
||||
{ type: 0, pts: 7193015676, ccData: 32896 },
|
||||
{ type: 0, pts: 7193018736, ccData: 32896 },
|
||||
{ type: 1, pts: 7193018736, ccData: 258 },
|
||||
{ type: 0, pts: 7193021706, ccData: 32896 },
|
||||
{ type: 1, pts: 7193021706, ccData: 16448 },
|
||||
{ type: 1, pts: 7193024676, ccData: 16448 },
|
||||
{ type: 0, pts: 7193024676, ccData: 32896 },
|
||||
{ type: 1, pts: 7193027736, ccData: 16512 },
|
||||
{ type: 0, pts: 7193027736, ccData: 32896 },
|
||||
{ type: 0, pts: 7193030706, ccData: 32896 },
|
||||
{ type: 1, pts: 7193030706, ccData: 36782 },
|
||||
{ type: 1, pts: 7193033766, ccData: 387 },
|
||||
{ type: 0, pts: 7193033766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193036736, ccData: 52975 },
|
||||
{ type: 0, pts: 7193036736, ccData: 32896 },
|
||||
{ type: 1, pts: 7193039706, ccData: 62196 },
|
||||
{ type: 0, pts: 7193039706, ccData: 32896 },
|
||||
{ type: 1, pts: 7193042766, ccData: 26656 },
|
||||
{ type: 0, pts: 7193042766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193045646, ccData: 22511 },
|
||||
{ type: 0, pts: 7193045646, ccData: 32896 },
|
||||
{ type: 1, pts: 7193048706, ccData: 61284 },
|
||||
{ type: 0, pts: 7193048706, ccData: 32896 },
|
||||
{ type: 1, pts: 7193051766, ccData: 29472 },
|
||||
{ type: 0, pts: 7193051766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193054736, ccData: 389 },
|
||||
{ type: 0, pts: 7193054736, ccData: 32896 },
|
||||
{ type: 1, pts: 7193057796, ccData: 51396 },
|
||||
{ type: 0, pts: 7193057796, ccData: 32896 },
|
||||
{ type: 1, pts: 7193060766, ccData: 36831 },
|
||||
{ type: 0, pts: 7193060766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193063736, ccData: 258 },
|
||||
{ type: 0, pts: 7193063736, ccData: 32896 },
|
||||
{ type: 0, pts: 7193066796, ccData: 32896 },
|
||||
{ type: 1, pts: 7193066796, ccData: 16448 },
|
||||
{ type: 0, pts: 7193069676, ccData: 32896 },
|
||||
{ type: 1, pts: 7193069676, ccData: 16448 },
|
||||
{ type: 1, pts: 7193072736, ccData: 16512 },
|
||||
{ type: 0, pts: 7193072736, ccData: 32896 },
|
||||
{ type: 0, pts: 7193075796, ccData: 32896 },
|
||||
{ type: 1, pts: 7193075796, ccData: 36782 },
|
||||
{ type: 1, pts: 7193078766, ccData: 387 },
|
||||
{ type: 0, pts: 7193078766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193081826, ccData: 52975 },
|
||||
{ type: 0, pts: 7193081826, ccData: 32896 },
|
||||
{ type: 1, pts: 7193084796, ccData: 62196 },
|
||||
{ type: 0, pts: 7193084796, ccData: 32896 },
|
||||
{ type: 0, pts: 7193087766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193087766, ccData: 26656 },
|
||||
{ type: 0, pts: 7193090736, ccData: 32896 },
|
||||
{ type: 1, pts: 7193090736, ccData: 22511 },
|
||||
{ type: 0, pts: 7193093706, ccData: 32896 },
|
||||
{ type: 1, pts: 7193093706, ccData: 61284 },
|
||||
{ type: 1, pts: 7193096766, ccData: 29472 },
|
||||
{ type: 0, pts: 7193096766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193099826, ccData: 19553 },
|
||||
{ type: 0, pts: 7193099826, ccData: 32896 },
|
||||
{ type: 1, pts: 7193102796, ccData: 63418 },
|
||||
{ type: 0, pts: 7193102796, ccData: 32896 },
|
||||
{ type: 0, pts: 7193105856, ccData: 32896 },
|
||||
{ type: 1, pts: 7193105856, ccData: 8271 },
|
||||
{ type: 0, pts: 7193108826, ccData: 32896 },
|
||||
{ type: 1, pts: 7193108826, ccData: 28192 },
|
||||
{ type: 1, pts: 7193111796, ccData: 62568 },
|
||||
{ type: 0, pts: 7193111796, ccData: 32896 },
|
||||
{ type: 1, pts: 7193114766, ccData: 58656 },
|
||||
{ type: 0, pts: 7193114766, ccData: 32896 },
|
||||
{ type: 0, pts: 7193117736, ccData: 32896 },
|
||||
{ type: 1, pts: 7193117736, ccData: 51317 },
|
||||
{ type: 0, pts: 7193120796, ccData: 32896 },
|
||||
{ type: 1, pts: 7193120796, ccData: 28404 },
|
||||
{ type: 1, pts: 7193123766, ccData: 8360 },
|
||||
{ type: 0, pts: 7193123766, ccData: 32896 },
|
||||
{ type: 1, pts: 7193126826, ccData: 54245 },
|
||||
{ type: 0, pts: 7193126826, ccData: 32896 },
|
||||
{ type: 0, pts: 7193129886, ccData: 32896 },
|
||||
{ type: 1, pts: 7193129886, ccData: 36667 },
|
||||
{ type: 1, pts: 7193138796, ccData: 16448 },
|
||||
{ type: 0, pts: 7193138796, ccData: 32896 }
|
||||
];
|
315
node_modules/mux.js/test/utils/mp4-helpers.js
generated
vendored
Normal file
315
node_modules/mux.js/test/utils/mp4-helpers.js
generated
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
/**
|
||||
* Helper functions for creating test MP4 data.
|
||||
*/
|
||||
'use strict';
|
||||
var box, typeBytes, unityMatrix;
|
||||
|
||||
module.exports = {};
|
||||
|
||||
// ----------------------
|
||||
// Box Generation Helpers
|
||||
// ----------------------
|
||||
|
||||
module.exports.typeBytes = typeBytes = function(type) {
|
||||
return [
|
||||
type.charCodeAt(0),
|
||||
type.charCodeAt(1),
|
||||
type.charCodeAt(2),
|
||||
type.charCodeAt(3)
|
||||
];
|
||||
};
|
||||
|
||||
module.exports.box = box = function(type) {
|
||||
var
|
||||
array = Array.prototype.slice.call(arguments, 1),
|
||||
result = [],
|
||||
size,
|
||||
i;
|
||||
|
||||
// "unwrap" any arrays that were passed as arguments
|
||||
// e.g. box('etc', 1, [2, 3], 4) -> box('etc', 1, 2, 3, 4)
|
||||
for (i = 0; i < array.length; i++) {
|
||||
if (array[i] instanceof Array) {
|
||||
array.splice.apply(array, [i, 1].concat(array[i]));
|
||||
}
|
||||
}
|
||||
|
||||
size = 8 + array.length;
|
||||
|
||||
result[0] = (size & 0xFF000000) >> 24;
|
||||
result[1] = (size & 0x00FF0000) >> 16;
|
||||
result[2] = (size & 0x0000FF00) >> 8;
|
||||
result[3] = size & 0xFF;
|
||||
result = result.concat(typeBytes(type));
|
||||
result = result.concat(array);
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports.unityMatrix = unityMatrix = [
|
||||
0, 0, 0x10, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0x10, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0x40, 0, 0, 0
|
||||
];
|
||||
|
||||
// ------------
|
||||
// Example Data
|
||||
// ------------
|
||||
|
||||
module.exports.sampleMoov =
|
||||
box('moov',
|
||||
box('mvhd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, // modification_time
|
||||
0x00, 0x00, 0x03, 0xe8, // timescale = 1000
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x00, 0x01, 0x00, 0x00, // 1.0 rate
|
||||
0x01, 0x00, // 1.0 volume
|
||||
0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
unityMatrix,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // pre_defined
|
||||
0x00, 0x00, 0x00, 0x02), // next_track_ID
|
||||
box('trak',
|
||||
box('tkhd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x00, 0x00, 0x01, // track_ID
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, // layer
|
||||
0x00, 0x00, // alternate_group
|
||||
0x00, 0x00, // non-audio track volume
|
||||
0x00, 0x00, // reserved
|
||||
unityMatrix,
|
||||
0x01, 0x2c, 0x00, 0x00, // 300 in 16.16 fixed-point
|
||||
0x00, 0x96, 0x00, 0x00), // 150 in 16.16 fixed-point
|
||||
box('edts',
|
||||
box('elst',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x00, // segment_duration
|
||||
0x00, 0x00, 0x04, 0x00, // media_time
|
||||
0x00, 0x01, 0x80, 0x00)), // media_rate
|
||||
box('mdia',
|
||||
box('mdhd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x01, 0x5f, 0x90, // timescale = 90000
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x15, 0xc7, // 'eng' language
|
||||
0x00, 0x00),
|
||||
box('hdlr',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00, // pre_defined
|
||||
typeBytes('vide'), // handler_type
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
typeBytes('one'), 0x00), // name
|
||||
box('minf',
|
||||
box('dinf',
|
||||
box('dref',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
box('url ',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x01))), // flags
|
||||
box('stbl',
|
||||
box('stsd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00, // entry_count
|
||||
box('avc1',
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, // box content
|
||||
typeBytes('avcC'), // codec profile type
|
||||
0x00, 0x4d, 0x40, 0x0d)), // codec parameters
|
||||
box('stts',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01, // sample_count
|
||||
0x00, 0x00, 0x00, 0x01), // sample_delta
|
||||
box('stsc',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x02, // first_chunk
|
||||
0x00, 0x00, 0x00, 0x03, // samples_per_chunk
|
||||
0x00, 0x00, 0x00, 0x01), // sample_description_index
|
||||
box('stco',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01), // chunk_offset
|
||||
box('stss',
|
||||
0x00, // version 0
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01), // sync_sample
|
||||
box('ctts',
|
||||
0x00, // version 0
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01, // sample_count
|
||||
0x00, 0x00, 0x00, 0x01))))), // sample_offset
|
||||
box('trak',
|
||||
box('tkhd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x00, 0x00, 0x02, // track_ID
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, // layer
|
||||
0x00, 0x00, // alternate_group
|
||||
0x00, 0x00, // non-audio track volume
|
||||
0x00, 0x00, // reserved
|
||||
unityMatrix,
|
||||
0x01, 0x2c, 0x00, 0x00, // 300 in 16.16 fixed-point
|
||||
0x00, 0x96, 0x00, 0x00), // 150 in 16.16 fixed-point
|
||||
box('edts',
|
||||
box('elst',
|
||||
0x01, // version
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // segment_duration
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // media_time
|
||||
0x00, 0x01, 0x80, 0x00)), // media_rate
|
||||
box('mdia',
|
||||
box('mdhd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, // creation_time
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, // modification_time
|
||||
0x00, 0x01, 0x5f, 0x90, // timescale = 90000
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x58, // 600 = 0x258 duration
|
||||
0x15, 0xc7, // 'eng' language
|
||||
0x00, 0x00),
|
||||
box('hdlr',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00, // pre_defined
|
||||
typeBytes('soun'), // handler_type
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
0x00, 0x00, 0x00, 0x00, // reserved
|
||||
typeBytes('one'), 0x00), // name
|
||||
box('minf',
|
||||
box('dinf',
|
||||
box('dref',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
box('url ',
|
||||
0x00, // version
|
||||
0x00, 0x00, 0x01))), // flags
|
||||
box('stbl',
|
||||
box('stsd',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x00, // entry_count
|
||||
box('mp4a',
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
typeBytes('esds'), // codec profile type
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, 0x00, // box content
|
||||
0x00, 0x00, 0x00, // box content
|
||||
0x40, 0x0a, // codec params
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00)), // codec params
|
||||
box('stts',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01, // sample_count
|
||||
0x00, 0x00, 0x00, 0x01), // sample_delta
|
||||
box('stsc',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x02, // first_chunk
|
||||
0x00, 0x00, 0x00, 0x03, // samples_per_chunk
|
||||
0x00, 0x00, 0x00, 0x01), // sample_description_index
|
||||
box('ctts',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01, // sample_count
|
||||
0xff, 0xff, 0xff, 0xff), // sample_offset
|
||||
box('stco',
|
||||
0x01, // version 1
|
||||
0x00, 0x00, 0x00, // flags
|
||||
0x00, 0x00, 0x00, 0x01, // entry_count
|
||||
0x00, 0x00, 0x00, 0x01)))))); // chunk_offset
|
137
node_modules/mux.js/test/utils/sei-nal-unit-generator.js
generated
vendored
Normal file
137
node_modules/mux.js/test/utils/sei-nal-unit-generator.js
generated
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* Helper functions for creating 608/708 SEI NAL units
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var box = require('./mp4-helpers').box;
|
||||
|
||||
// Create SEI nal-units from Caption packets
|
||||
var makeSeiFromCaptionPacket = function(caption) {
|
||||
return {
|
||||
pts: caption.pts,
|
||||
dts: caption.dts,
|
||||
nalUnitType: 'sei_rbsp',
|
||||
escapedRBSP: new Uint8Array([
|
||||
0x04, // payload_type === user_data_registered_itu_t_t35
|
||||
|
||||
0x0e, // payload_size
|
||||
|
||||
181, // itu_t_t35_country_code
|
||||
0x00, 0x31, // itu_t_t35_provider_code
|
||||
0x47, 0x41, 0x39, 0x34, // user_identifier, "GA94"
|
||||
0x03, // user_data_type_code, 0x03 is cc_data
|
||||
|
||||
// 110 00001
|
||||
0xc1, // process_cc_data, cc_count
|
||||
0xff, // reserved
|
||||
// 1111 1100
|
||||
(0xfc | caption.type), // cc_valid, cc_type (608, field 1)
|
||||
(caption.ccData & 0xff00) >> 8, // cc_data_1
|
||||
caption.ccData & 0xff, // cc_data_2 without parity bit set
|
||||
|
||||
0xff // marker_bits
|
||||
])
|
||||
};
|
||||
};
|
||||
|
||||
// Create SEI nal-units from Caption packets
|
||||
var makeSeiFromMultipleCaptionPackets = function(captionHash) {
|
||||
var pts = captionHash.pts,
|
||||
dts = captionHash.dts,
|
||||
captions = captionHash.captions;
|
||||
|
||||
var data = [];
|
||||
captions.forEach(function(caption) {
|
||||
data.push(0xfc | caption.type);
|
||||
data.push((caption.ccData & 0xff00) >> 8);
|
||||
data.push(caption.ccData & 0xff);
|
||||
});
|
||||
|
||||
return {
|
||||
pts: pts,
|
||||
dts: dts,
|
||||
nalUnitType: 'sei_rbsp',
|
||||
escapedRBSP: new Uint8Array([
|
||||
0x04, // payload_type === user_data_registered_itu_t_t35
|
||||
|
||||
(0x0b + (captions.length * 3)), // payload_size
|
||||
|
||||
181, // itu_t_t35_country_code
|
||||
0x00, 0x31, // itu_t_t35_provider_code
|
||||
0x47, 0x41, 0x39, 0x34, // user_identifier, "GA94"
|
||||
0x03, // user_data_type_code, 0x03 is cc_data
|
||||
|
||||
// 110 00001
|
||||
(0x6 << 5) | captions.length, // process_cc_data, cc_count
|
||||
0xff // reserved
|
||||
].concat(data).concat([0xff /* marker bits */])
|
||||
)
|
||||
};
|
||||
};
|
||||
|
||||
var makeMdatFromCaptionPackets = function(packets) {
|
||||
var mdat = ['mdat'];
|
||||
var seis = packets.map(makeSeiFromCaptionPacket);
|
||||
|
||||
seis.forEach(function(sei) {
|
||||
mdat.push(0x00);
|
||||
mdat.push(0x00);
|
||||
mdat.push(0x00);
|
||||
mdat.push(sei.escapedRBSP.length + 1); // nal length
|
||||
mdat.push(0x06); // declare nal type as SEI
|
||||
// SEI message
|
||||
for (var i = 0; i < sei.escapedRBSP.length; i++) {
|
||||
var byte = sei.escapedRBSP[i];
|
||||
|
||||
mdat.push(byte);
|
||||
}
|
||||
});
|
||||
|
||||
return box.apply(null, mdat);
|
||||
};
|
||||
|
||||
// Returns a ccData byte-pair for a two character string. That is,
|
||||
// it converts a string like 'hi' into the two-byte number that
|
||||
// would be parsed back as 'hi' when provided as ccData.
|
||||
var characters = function(text) {
|
||||
if (text.length !== 2) {
|
||||
throw new Error('ccdata must be specified two characters at a time');
|
||||
}
|
||||
return (text.charCodeAt(0) << 8) | text.charCodeAt(1);
|
||||
};
|
||||
|
||||
// Returns a ccData byte-pair including
|
||||
// Header for 708 packet
|
||||
// Header for the first service block
|
||||
// seq should increment by 1 for each byte pair mod 3 (0,1,2,0,1,2,...)
|
||||
// sizeCode is the number of byte pairs in the packet (including header)
|
||||
// serviceNum is the service number of the first service block
|
||||
// blockSize is the size of the first service block in bytes (no header)
|
||||
// If there's only one service block, the blockSize should be (sizeCode-1)*2
|
||||
var packetHeader708 = function(seq, sizeCode, serviceNum, blockSize) {
|
||||
var b1 = (seq << 6) | sizeCode;
|
||||
var b2 = (serviceNum << 5) | blockSize;
|
||||
return (b1 << 8) | b2;
|
||||
};
|
||||
|
||||
// Returns a ccData byte-pair to execute a 708 DSW command
|
||||
// Takes an array of window indicies to display
|
||||
var displayWindows708 = function(windows) {
|
||||
var cmd = 0x8900;
|
||||
|
||||
windows.forEach(function(winIdx) {
|
||||
cmd |= (0x01 << winIdx);
|
||||
});
|
||||
|
||||
return cmd;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
makeSeiFromCaptionPacket: makeSeiFromCaptionPacket,
|
||||
makeSeiFromMultipleCaptionPackets: makeSeiFromMultipleCaptionPackets,
|
||||
makeMdatFromCaptionPackets: makeMdatFromCaptionPackets,
|
||||
characters: characters,
|
||||
packetHeader708: packetHeader708,
|
||||
displayWindows708: displayWindows708
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue