Browse Source

fix: always append init segment after trackinfo change (#913)

pull/915/head
Brandon Casey 5 years ago
committed by GitHub
parent
commit
ea3650a08d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      src/segment-loader.js
  2. 57
      test/segment-loader.test.js

28
src/segment-loader.js

@ -1453,11 +1453,31 @@ export default class SegmentLoader extends videojs.EventTarget {
// Guard against cases where we're not getting track info at all until we are
// certain that all streams will provide it.
if (!shallowEqual(this.startingMedia_, trackInfo)) {
this.appendInitSegment_ = {
audio: true,
video: true
};
this.startingMedia_ = trackInfo;
this.logger_('trackinfo update', trackInfo);
this.trigger('trackinfo');
}
// trackinfo may cause an abort if the trackinfo
// causes a codec change to an unsupported codec.
if (this.checkForAbort_(simpleSegment.requestId) ||
this.abortRequestEarly_(simpleSegment.stats)) {
return;
}
// set trackinfo on the pending segment so that
// it can append.
this.pendingSegment_.trackInfo = trackInfo;
// check if any calls were waiting on the track info
if (this.hasEnoughInfoToAppend_()) {
this.processCallQueue_();
}
}
handleTimingInfo_(simpleSegment, mediaType, timeType, time) {
@ -1678,8 +1698,10 @@ export default class SegmentLoader extends videojs.EventTarget {
const segmentInfo = this.pendingSegment_;
if (!segmentInfo || !this.startingMedia_) {
// no segment to append any data for
// no segment to append any data for or
// we do not have information on this specific
// segment yet
if (!segmentInfo || !segmentInfo.trackInfo) {
return false;
}
@ -1895,7 +1917,7 @@ export default class SegmentLoader extends videojs.EventTarget {
this.sourceUpdater_.appendBuffer({segmentInfo, type, bytes}, (error) => {
if (error) {
this.error(`appenderror for ${type} append with ${bytes.length} bytes`);
this.error(`${type} append of ${bytes.length}b failed for segment #${segmentInfo.mediaIndex} in playlist ${segmentInfo.playlist.id}`);
// If an append errors, we can't recover.
// (see https://w3c.github.io/media-source/#sourcebuffer-append-error).
// Trigger a special error so that it can be handled separately from normal,

57
test/segment-loader.test.js

@ -2324,7 +2324,11 @@ QUnit.module('SegmentLoader', function(hooks) {
loader.one('error', reject);
});
}).then(() => {
assert.deepEqual(loader.error_, 'appenderror for video append with 2960 bytes', 'loader triggered and saved the appenderror');
assert.deepEqual(
loader.error_,
'video append of 2960b failed for segment #0 in playlist playlist.m3u8',
'loader triggered and saved the appenderror'
);
});
});
@ -2586,6 +2590,57 @@ QUnit.module('SegmentLoader', function(hooks) {
});
});
QUnit.test('re-appends init segments after different trackinfo', function(assert) {
const appends = [];
const oldTrackInfo = loader.handleTrackInfo_;
return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
const origAppendToSourceBuffer = loader.appendToSourceBuffer_.bind(loader);
loader.appendToSourceBuffer_ = (config) => {
appends.push(config);
origAppendToSourceBuffer(config);
};
loader.playlist(playlistWithDuration(20));
loader.load();
this.clock.tick(1);
standardXHRResponse(this.requests.shift(), muxedSegment());
loader.handleTrackInfo_ = (simpleSegment, trackInfo) => {
trackInfo.foo = true;
return oldTrackInfo.call(loader, simpleSegment, trackInfo);
};
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}).then(() => {
this.clock.tick(1);
assert.equal(appends.length, 2, 'two appends');
assert.equal(appends[0].type, 'video', 'appended to video buffer');
assert.ok(appends[0].initSegment, 'appended video init segment');
assert.equal(appends[1].type, 'audio', 'appended to audio buffer');
assert.ok(appends[1].initSegment, 'appended audio init segment');
standardXHRResponse(this.requests.shift(), muxedSegment());
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}).then(() => {
this.clock.tick(1);
assert.equal(appends.length, 4, 'two more appends');
assert.equal(appends[2].type, 'video', 'appended to video buffer');
assert.ok(appends[2].initSegment, 'appended video init segment');
assert.equal(appends[3].type, 'audio', 'appended to audio buffer');
assert.ok(appends[3].initSegment, 'appended audio init segment');
});
});
QUnit.test('stores and reuses audio init segments from map tag', function(assert) {
loader.dispose();
loader = new SegmentLoader(LoaderCommonSettings.call(this, {

Loading…
Cancel
Save