-
Notifications
You must be signed in to change notification settings - Fork 793
Clear the blacklist for other playlists if final rendition errors #1083
Conversation
3fabb71
to
cbffa84
Compare
src/master-playlist-controller.js
Outdated
@@ -1064,14 +1064,22 @@ export class MasterPlaylistController extends videojs.EventTarget { | |||
} | |||
|
|||
let isFinalRendition = this.masterPlaylistLoader_.isFinalRendition_(); | |||
let playlists = this.tech_.hls.playlists.master.playlists; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can just be this.masterPlaylistLoader_.master.playlists
b384f69
to
f81badf
Compare
src/playlist-loader.js
Outdated
mediaUpdateTimeout = window.setTimeout(loader.media.bind(loader, playlist, false), refreshDelay); | ||
return; | ||
} | ||
|
||
// setter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be moved up
test/videojs-contrib-hls.test.js
Outdated
'log specific error message for final playlist'); | ||
assert.equal(retryplaylist, 1, 'retried final playlist for once'); | ||
assert.equal(blacklistplaylist, 1, 'there is one blacklisted playlist'); | ||
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media1.m3u8 Switching to another playlist.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also just realized that there is no period between media1.m3u8 Switching
(from before, but might be nice to fix.
test/videojs-contrib-hls.test.js
Outdated
@@ -1153,9 +1152,11 @@ QUnit.test('playlist 404 should blacklist media', function(assert) { | |||
this.clock.tick(3 * 1000); | |||
// continue loading the final remaining playlist after it wasn't blacklisted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, I think this comment might need to change
test/videojs-contrib-hls.test.js
Outdated
@@ -1531,13 +1532,14 @@ QUnit.test('playlist blacklisting duration is set through options', function(ass | |||
assert.equal(this.env.log.warn.args[0], | |||
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8 Switching to another playlist.', | |||
'log generic error message'); | |||
// this takes one millisecond |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this new response need to be added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the new response didn't be added here, it will error for the second(final) rendition. Since we clear blacklist duration for the first rendition when final rendition errors, we can't test if the blacklist duration is set through option successfully.
src/master-playlist-controller.js
Outdated
playlists.forEach((playlist) => { | ||
// clear the blacklist duration for the other playlists when | ||
// the final playlist errors | ||
playlist.excludeUntil = Date.now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be clearer to delete playlist.excludeUntil
for each.
test/videojs-contrib-hls.test.js
Outdated
@@ -1529,15 +1532,16 @@ QUnit.test('playlist blacklisting duration is set through options', function(ass | |||
assert.ok(media.excludeUntil > 0, 'original media blacklisted for some time'); | |||
assert.equal(this.env.log.warn.calls, 1, 'warning logged for blacklist'); | |||
assert.equal(this.env.log.warn.args[0], | |||
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8 Switching to another playlist.', | |||
'Problem encountered with the current HLS playlist. HLS playlist request error at URL: media.m3u8. Switching to another playlist.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long line.
test/videojs-contrib-hls.test.js
Outdated
'Switching to another playlist.', | ||
'log generic error message'); | ||
assert.equal(retryplaylist, 0, 'haven\'t retried any playlist'); | ||
assert.equal(blacklistplaylist, 2, 'media1 is blacklisted'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although this may be true, since it's only testing that it got a blacklist event, maybe it is worth having two different checks, one for getting the blacklist event, the other checking for the excludeUntil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have that excludeUntil check in line 1141?
test/videojs-contrib-hls.test.js
Outdated
|
||
this.clock.tick(2 * 1000); | ||
// no new request was made since it hasn't been half the segment duration | ||
assert.strictEqual(3, this.requests.length, 'no new request was made'); | ||
|
||
this.clock.tick(3 * 1000); | ||
// continue loading the final remaining playlist after it wasn't blacklisted | ||
// loading the first playlist since the blacklist duration is cleared |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was
test/videojs-contrib-hls.test.js
Outdated
assert.strictEqual(4, this.requests.length, 'one more request was made'); | ||
// the first media was unblacklisted after a refresh delay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to check excludeUntil was deleted
src/master-playlist-controller.js
Outdated
|
||
this.tech_.trigger('retryplaylist'); | ||
return this.masterPlaylistLoader_.load(isFinalRendition); | ||
} | ||
if (isFinalRendition) { | ||
playlists.forEach((playlist) => { | ||
// clear the blacklist duration for the other playlists when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than describing what the code is doing, it might make more sense to have a comment about the reason we are doing it. Something like Since we're on the final non-blacklisted playlist, and we're about to blacklist it, instead of erring the player or retrying this playlist, we clear out the current blacklist so the other playlists may be attempted in case any have been fixed.
test/videojs-contrib-hls.test.js
Outdated
media = this.player.tech_.hls.playlists.master.playlists[url]; | ||
|
||
// the first media was unblacklisted after a refresh delay | ||
assert.ok(!media.excludeUntil, 'excludeUntil was deleted after cleared the blacklist duration for the first media'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can just be removed first media from blacklist
|
||
this.tech_.trigger('retryplaylist'); | ||
return this.masterPlaylistLoader_.load(isFinalRendition); | ||
} | ||
if (isFinalRendition) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth adding a warning log here with something like Clearing blacklist because last rendition is about to be blacklisted.
src/master-playlist-controller.js
Outdated
// Since we're on the final non-blacklisted playlist, and we're about to blacklist it, | ||
// instead of erring the player or retrying this playlist, we clear out the current blacklist | ||
// so the other playlists may be attempted in case any have been fixed. | ||
videojs.log.warn('Clearing blacklist because last rendition is about to be blacklisted.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will get logged for every playlist. May just want to log it once.
src/master-playlist-controller.js
Outdated
|
||
this.tech_.trigger('retryplaylist'); | ||
return this.masterPlaylistLoader_.load(isFinalRendition); | ||
} | ||
if (isFinalRendition) { | ||
playlists.forEach((playlist) => { | ||
// Since we're on the final non-blacklisted playlist, and we're about to blacklist it, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want this comment outside of the loop as well.
fd5548f
to
f6a5b61
Compare
src/master-playlist-controller.js
Outdated
playlists.forEach((playlist) => { | ||
delete playlist.excludeUntil; | ||
}); | ||
videojs.log.warn('Clearing blacklist for every playlist because last rendition ' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but putting it just before the loop might be better for a couple reasons: (1) if something breaks (throws an exception) during the loop, we know the last warning log and it can help us determine what broke and (2) we already cleared everything, so Clearing
might be more accurate before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense! Changed as suggested
5a70507
to
b1443be
Compare
Any updates on this PR? The blacklisting is actively affecting a project I'm working on, would love to see this fixed :) |
window.clearTimeout(this.mediaUpdateTimeout); | ||
|
||
if (isFinalRendition) { | ||
const delay = (playlist.targetDuration / 2) * 1000 || 5 * 1000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we will encounter this because of when this is called with isFinalRendition === true
, playlist
is an object, but we support playlist
being a string as you can see just below this, so it may be better to move this block below the string
check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 updated
Let's open this against VHS |
Closing and opening against VHS in the future |
Description
Before the behavior is we never blacklist the final request and wait up to 5 minutes for other playlists' blacklist duration to be cleared. Change the behavior as follow: