Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1426,8 +1426,10 @@ export class PlaylistController extends videojs.EventTarget {
const isFinalRendition = enabledPlaylists.length === 1 && enabledPlaylists[0] === playlistToExclude;

// Don't exclude the only playlist unless it was excluded
// forever
if (playlists.length === 1 && playlistExclusionDuration !== Infinity) {
// forever, or retries have been exhausted.
if (playlists.length === 1 &&
playlistExclusionDuration !== Infinity &&
playlistToExclude.playlistErrors_ <= this.maxPlaylistRetries) {
videojs.log.warn(`Problem encountered with playlist ${playlistToExclude.id}. ` +
'Trying again since it is the only playlist.');

Expand Down
53 changes: 53 additions & 0 deletions test/playlist-controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6689,6 +6689,59 @@ QUnit.test('Playlist is excluded indefinitely if number of playlistErrors_ excee
this.env.log.warn.callCount = 0;
});

QUnit.test('single media playlist is excluded indefinitely once playlistErrors_ exceeds maxPlaylistRetries', function(assert) {
this.requests.length = 0;
this.player.dispose();
this.player = createPlayer({ html5: { vhs: { maxPlaylistRetries: 1 } } });
this.player.src({
src: 'manifest/media.m3u8',
type: 'application/vnd.apple.mpegurl'
});

this.clock.tick(1);

this.playlistController = this.player.tech_.vhs.playlistController_;

// media playlist with no master
this.standardXHRResponse(this.requests.shift());

const pc = this.playlistController;
const mpl = pc.mainPlaylistLoader_;
const playlist = mpl.main.playlists[0];
let loadCalled = false;
let errorTriggered = false;

mpl.load = () => {
loadCalled = true;
};
pc.on('error', () => {
errorTriggered = true;
});

assert.equal(mpl.main.playlists.length, 1, 'source is a single media playlist');
assert.equal(playlist.playlistErrors_, 0, 'playlistErrors_ starts at zero');

pc.excludePlaylist({});

assert.notOk('excludeUntil' in playlist, 'playlist was not excluded on first error');
assert.equal(playlist.playlistErrors_, 1, 'we incremented playlistErrors_');
assert.ok(loadCalled, 'retried the only playlist');
assert.notOk(errorTriggered, 'did not error before retries were exceeded');
assert.equal(this.env.log.warn.callCount, 1, 'logged a warning');

loadCalled = false;
pc.excludePlaylist({});

assert.equal(playlist.playlistErrors_, 2, 'we incremented playlistErrors_');
assert.equal(playlist.excludeUntil, Infinity, 'The playlist was excluded indefinitely');
assert.ok(errorTriggered, 'we triggered a playback error');
assert.notOk(loadCalled, 'did not retry after exceeding maxPlaylistRetries');
assert.equal(this.env.log.error.callCount, 1, 'logged an error');

this.env.log.warn.callCount = 0;
this.env.log.error.callCount = 0;
});

QUnit.test('should delay loading of new playlist if lastRequest was less than half target duration', function(assert) {
this.requests.length = 0;
this.player.dispose();
Expand Down