Skip to content

Commit 6ff42f4

Browse files
authored
feat: add firstSequenceNumber option to Transmuxer to start sequence somewhere other than zero (#395)
Adds an option `firstSequenceNumber` to Transmuxer. Can be used like this: new Transmuxer({ firstSequenceNumber: 10 }); This is passed in to VideoSegmentStream and AudioSegmentStream. When mfhd boxes are constructed, the starting sequence number will be taken from that option. The default value is zero. This is useful for generating segmented streams out of order. Out of oder processing allows for restart, parallelism, or random seeking into source material.
1 parent 86cfdca commit 6ff42f4

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

lib/mp4/transmuxer.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,15 @@ var generateSegmentTimingInfo = function(
9292
AudioSegmentStream = function(track, options) {
9393
var
9494
adtsFrames = [],
95-
sequenceNumber = 0,
95+
sequenceNumber,
9696
earliestAllowedDts = 0,
9797
audioAppendStartTs = 0,
9898
videoBaseMediaDecodeTime = Infinity;
9999

100100
options = options || {};
101101

102+
sequenceNumber = options.firstSequenceNumber || 0;
103+
102104
AudioSegmentStream.prototype.init.call(this);
103105

104106
this.push = function(data) {
@@ -227,14 +229,16 @@ AudioSegmentStream.prototype = new Stream();
227229
*/
228230
VideoSegmentStream = function(track, options) {
229231
var
230-
sequenceNumber = 0,
232+
sequenceNumber,
231233
nalUnits = [],
232234
gopsToAlignWith = [],
233235
config,
234236
pps;
235237

236238
options = options || {};
237239

240+
sequenceNumber = options.firstSequenceNumber || 0;
241+
238242
VideoSegmentStream.prototype.init.call(this);
239243

240244
delete track.minPTS;

test/transmuxer.test.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3427,6 +3427,64 @@ QUnit.test('no options creates combined output', function(assert) {
34273427
assert.equal('mdat', boxes[3].type, 'generated a second mdat box');
34283428
});
34293429

3430+
QUnit.test('first sequence number option is used in mfhd box', function(assert) {
3431+
var
3432+
segments = [],
3433+
mfhds = [],
3434+
boxes,
3435+
transmuxer = new Transmuxer({ firstSequenceNumber: 10 });
3436+
3437+
transmuxer.on('data', function(segment) {
3438+
segments.push(segment);
3439+
});
3440+
transmuxer.push(packetize(PAT));
3441+
transmuxer.push(packetize(generatePMT({
3442+
hasVideo: true,
3443+
hasAudio: true
3444+
})));
3445+
3446+
transmuxer.push(packetize(audioPes([
3447+
0x19, 0x47
3448+
], true)));
3449+
transmuxer.push(packetize(videoPes([
3450+
0x09, 0x01 // access_unit_delimiter_rbsp
3451+
], true)));
3452+
transmuxer.push(packetize(videoPes([
3453+
0x08, 0x01 // pic_parameter_set_rbsp
3454+
], true)));
3455+
transmuxer.push(packetize(videoPes([
3456+
0x07, // seq_parameter_set_rbsp
3457+
0x27, 0x42, 0xe0, 0x0b,
3458+
0xa9, 0x18, 0x60, 0x9d,
3459+
0x80, 0x53, 0x06, 0x01,
3460+
0x06, 0xb6, 0xc2, 0xb5,
3461+
0xef, 0x7c, 0x04
3462+
], false)));
3463+
transmuxer.push(packetize(videoPes([
3464+
0x05, 0x01 // slice_layer_without_partitioning_rbsp_idr
3465+
], true)));
3466+
transmuxer.flush();
3467+
3468+
assert.equal(segments.length, 1, 'generated a combined video and audio segment');
3469+
assert.equal(segments[0].type, 'combined', 'combined is the segment type');
3470+
3471+
boxes = mp4.tools.inspect(segments[0].data);
3472+
boxes.forEach(function(box) {
3473+
if (box.type === 'moof') {
3474+
box.boxes.forEach(function(moofBox) {
3475+
if (moofBox.type === 'mfhd') {
3476+
mfhds.push(moofBox);
3477+
}
3478+
});
3479+
}
3480+
});
3481+
3482+
assert.equal(mfhds.length, 2, 'muxed output has two mfhds');
3483+
3484+
assert.equal(mfhds[0].sequenceNumber, 10, 'first mfhd sequence starts at 10');
3485+
assert.equal(mfhds[1].sequenceNumber, 10, 'second mfhd sequence starts at 10');
3486+
});
3487+
34303488
QUnit.test('can specify that we want to generate separate audio and video segments', function(assert) {
34313489
var
34323490
segments = [],

0 commit comments

Comments
 (0)