Skip to content

Commit

Permalink
do not test vtt-segment-loader
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey committed Feb 22, 2021
1 parent 2bf49d4 commit 55ad96c
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 151 deletions.
37 changes: 20 additions & 17 deletions src/segment-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -977,29 +977,21 @@ export default class SegmentLoader extends videojs.EventTarget {
if (this.mediaIndex !== null) {
this.mediaIndex -= mediaSequenceDiff;

/*
// mediaIndex is invalid, set it to null
if (this.mediaIndex < 0) {
this.resyncLoader();
this.mediaIndex = null;
this.partIndex = null;
} else {
const segment = this.playlist_.segments[this.mediaIndex];

// partIndex should remain the same for the same segment
// unless parts fell off of the playlist for this segment.
// In that case we need to reset partIndex and resync
if (this.partIndex && (!segment.parts || !segment.parts.length || !segment.parts[this.partIndex])) {
console.log(`part fell off on part ${this.partIndex}`);
this.partIndex = null;
this.remove(0, Infinity);
// clears fmp4 captions
if (this.transmuxer_) {
this.transmuxer_.postMessage({
action: 'clearAllMp4Captions'
});
}
this.logger_(`part fell off on part ${this.partIndex}`);
this.resetLoader();
}
}*/
}
}

// update the mediaIndex on the SegmentInfo object
Expand Down Expand Up @@ -1276,18 +1268,25 @@ export default class SegmentLoader extends videojs.EventTarget {
* @param {Object} [playlist] a media playlist object
* @return {boolean} do we need to call endOfStream on the MediaSource
*/
isEndOfStream_(mediaIndex = this.mediaIndex, playlist = this.playlist_) {
isEndOfStream_(mediaIndex = this.mediaIndex, playlist = this.playlist_, partIndex = this.partIndex) {
if (!playlist || !this.mediaSource_) {
return false;
}

const segment = typeof mediaIndex === 'number' && playlist.segments[mediaIndex];

// mediaIndex is zero based but length is 1 based
const appendedLastSegment = (mediaIndex + 1) === playlist.segments.length;
// true if there are no parts, or this is the last part.
const appendedLastPart = !segment || !segment.parts || (partIndex + 1) === segment.parts.length;

// if we've buffered to the end of the video, we need to call endOfStream
// so that MediaSources can trigger the `ended` event when it runs out of
// buffered data instead of waiting for me
return playlist.endList && this.mediaSource_.readyState === 'open' && appendedLastSegment;
return playlist.endList &&
this.mediaSource_.readyState === 'open' &&
appendedLastSegment &&
appendedLastPart;
}

/**
Expand Down Expand Up @@ -2252,7 +2251,11 @@ export default class SegmentLoader extends videojs.EventTarget {
}

const simpleSegment = this.createSimplifiedSegmentObj_(segmentInfo);
const isEndOfStream = this.isEndOfStream_(segmentInfo.mediaIndex, segmentInfo.playlist);
const isEndOfStream = this.isEndOfStream_(
segmentInfo.mediaIndex,
segmentInfo.playlist,
segmentInfo.partIndex
);
const isWalkingForward = this.mediaIndex !== null;
const isDiscontinuity = segmentInfo.timeline !== this.currentTimeline_ &&
// currentTimeline starts at -1, so we shouldn't end the timeline switching to 0,
Expand Down Expand Up @@ -2845,7 +2848,7 @@ export default class SegmentLoader extends videojs.EventTarget {
// any time an update finishes and the last segment is in the
// buffer, end the stream. this ensures the "ended" event will
// fire if playback reaches that point.
if (this.isEndOfStream_(segmentInfo.mediaIndex, segmentInfo.playlist)) {
if (this.isEndOfStream_(segmentInfo.mediaIndex, segmentInfo.playlist, segmentInfo.partIndex)) {
this.endOfStream();
}

Expand Down
233 changes: 118 additions & 115 deletions test/loader-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,147 +802,150 @@ export const LoaderCommonFactory = ({
});
});

QUnit.test('mediaIndex and partIndex are used', function(assert) {
const appendPart = (segmentIndex, partIndex) => {
this.clock.tick(1);

assert.equal(
this.requests[0].url,
`segment${segmentIndex}.part${partIndex}.ts`,
`requested mediaIndex #${segmentIndex} partIndex #${partIndex}`
);
standardXHRResponse(this.requests.shift(), testData());

if (usesAsyncAppends) {
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}
// only main/fmp4 segment loaders use parts/partIndex
if (usesAsyncAppends) {
QUnit.test('mediaIndex and partIndex are used', function(assert) {
const appendPart = (segmentIndex, partIndex) => {
this.clock.tick(1);

return Promise.resolve();
};
assert.equal(
this.requests[0].url,
`segment${segmentIndex}.part${partIndex}.ts`,
`requested mediaIndex #${segmentIndex} partIndex #${partIndex}`
);
standardXHRResponse(this.requests.shift(), testData());

return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
loader.playlist(playlistWithDuration(50, {
mediaSequence: 0,
endList: false,
llhls: true
}));
if (usesAsyncAppends) {
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}

loader.load();
loader.mediaIndex = 2;
return Promise.resolve();
}).then(() => appendPart(2, 0))
.then(() => appendPart(2, 1))
.then(() => appendPart(2, 2))
.then(() => appendPart(2, 3))
.then(() => appendPart(2, 4))
.then(() => appendPart(3, 0));
});
return Promise.resolve();
};

QUnit.test('mediaIndex and partIndex survive playlist change', function(assert) {
const appendPart = (segmentIndex, partIndex) => {
this.clock.tick(1);
return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
loader.playlist(playlistWithDuration(50, {
mediaSequence: 0,
endList: false,
llhls: true
}));

assert.equal(
this.requests[0].url,
`segment${segmentIndex}.part${partIndex}.ts`,
`requested mediaIndex #${segmentIndex} partIndex #${partIndex}`
);
standardXHRResponse(this.requests.shift(), testData());
loader.load();
loader.mediaIndex = 2;
return Promise.resolve();
}).then(() => appendPart(2, 0))
.then(() => appendPart(2, 1))
.then(() => appendPart(2, 2))
.then(() => appendPart(2, 3))
.then(() => appendPart(2, 4))
.then(() => appendPart(3, 0));
});

if (usesAsyncAppends) {
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}
QUnit.test('mediaIndex and partIndex survive playlist change', function(assert) {
const appendPart = (segmentIndex, partIndex) => {
this.clock.tick(1);

return Promise.resolve();
};
assert.equal(
this.requests[0].url,
`segment${segmentIndex}.part${partIndex}.ts`,
`requested mediaIndex #${segmentIndex} partIndex #${partIndex}`
);
standardXHRResponse(this.requests.shift(), testData());

return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
loader.playlist(playlistWithDuration(50, {
mediaSequence: 0,
endList: false,
llhls: true
}));
if (usesAsyncAppends) {
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}

loader.load();
loader.mediaIndex = 4;
return Promise.resolve();
}).then(() => appendPart(4, 0))
.then(() => appendPart(4, 1))
.then(() => appendPart(4, 2))
.then(() => {
return Promise.resolve();
};

// Update the playlist shifting the mediaSequence by 2 which will result
// in a decrement of the mediaIndex by 2 to 1
return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
loader.playlist(playlistWithDuration(50, {
mediaSequence: 2,
mediaSequence: 0,
endList: false,
llhls: true
}));
// verify that we still try to append the next part for that segment.
return appendPart(2, 3);
}).then(() => appendPart(2, 4));
});

QUnit.test('drops partIndex if playlist update drops parts', function(assert) {
const appendPart = (segmentIndex, partIndex) => {
this.clock.tick(1);

assert.equal(
this.requests[0].url,
`segment${segmentIndex}.part${partIndex}.ts`,
`requested mediaIndex #${segmentIndex} partIndex #${partIndex}`
);
standardXHRResponse(this.requests.shift(), testData());
loader.load();
loader.mediaIndex = 4;
return Promise.resolve();
}).then(() => appendPart(4, 0))
.then(() => appendPart(4, 1))
.then(() => appendPart(4, 2))
.then(() => {

// Update the playlist shifting the mediaSequence by 2 which will result
// in a decrement of the mediaIndex by 2 to 1
loader.playlist(playlistWithDuration(50, {
mediaSequence: 2,
endList: false,
llhls: true
}));
// verify that we still try to append the next part for that segment.
return appendPart(2, 3);
}).then(() => appendPart(2, 4));
});

if (usesAsyncAppends) {
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}
QUnit.test('drops partIndex if playlist update drops parts', function(assert) {
const appendPart = (segmentIndex, partIndex) => {
this.clock.tick(1);

return Promise.resolve();
};
assert.equal(
this.requests[0].url,
`segment${segmentIndex}.part${partIndex}.ts`,
`requested mediaIndex #${segmentIndex} partIndex #${partIndex}`
);
standardXHRResponse(this.requests.shift(), testData());

return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
loader.playlist(playlistWithDuration(50, {
mediaSequence: 0,
endList: false,
llhls: true
}));
if (usesAsyncAppends) {
return new Promise((resolve, reject) => {
loader.one('appended', resolve);
loader.one('error', reject);
});
}

loader.load();
loader.mediaIndex = 4;
return Promise.resolve();
}).then(() => appendPart(4, 0))
.then(() => appendPart(4, 1))
.then(() => appendPart(4, 2))
.then(() => {
return Promise.resolve();
};

// Update the playlist shifting the mediaSequence by 2 which will result
// in a decrement of the mediaIndex by 2 to 1
return setupMediaSource(loader.mediaSource_, loader.sourceUpdater_).then(() => {
loader.playlist(playlistWithDuration(50, {
mediaSequence: 4,
mediaSequence: 0,
endList: false,
llhls: true
}));

assert.equal(loader.partIndex, null, 'partIndex was dropped');
this.clock.tick(1);
loader.load();
loader.mediaIndex = 4;
return Promise.resolve();
}).then(() => appendPart(4, 0))
.then(() => appendPart(4, 1))
.then(() => appendPart(4, 2))
.then(() => {

// Update the playlist shifting the mediaSequence by 2 which will result
// in a decrement of the mediaIndex by 2 to 1
loader.playlist(playlistWithDuration(50, {
mediaSequence: 4,
endList: false,
llhls: true
}));

assert.equal(loader.partIndex, null, 'partIndex was dropped');
this.clock.tick(1);

assert.equal(
this.requests[0].url,
'1.ts',
'requested mediaIndex 1 only'
);
});
});
assert.equal(
this.requests[0].url,
'1.ts',
'requested mediaIndex 1 only'
);
});
});
}

QUnit.test('segment 404s should trigger an error', function(assert) {
const errors = [];
Expand Down
Loading

0 comments on commit 55ad96c

Please sign in to comment.