Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add exclude reason and skip duplicate playlist-unchanged #1082

Merged
merged 9 commits into from
Mar 5, 2021
Merged
8 changes: 6 additions & 2 deletions src/dash-playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,9 @@ export default class DashPlaylistLoader extends EventTarget {
}

updateMinimumUpdatePeriodTimeout_() {
if (!this.isMaster_) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only add a minimum update period timer on the master playlist object.

return;
}
// Clear existing timeout
window.clearTimeout(this.minimumUpdatePeriodTimeout_);

Expand All @@ -728,7 +731,7 @@ export default class DashPlaylistLoader extends EventTarget {
// If we haven't yet selected a playlist, wait until then so we know the
// target duration
if (!this.media()) {
this.one('loadedplaylist', () => {
this.one('loadedmetadata', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When media loads on the master playlist for the first time it's called loadedmetadata. loadedplaylist signifies the load of the master playlist.

createMUPTimeout(this.media().targetDuration * 1000);
});
} else {
Expand Down Expand Up @@ -791,9 +794,10 @@ export default class DashPlaylistLoader extends EventTarget {
this.trigger('playlistunchanged');
}

if (!this.media().endList) {
if (!this.media().endList && !this.mediaUpdateTimeout) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only have one mediaupdatetimeout running at a time for an object. Mutex's ftw

this.mediaUpdateTimeout = window.setTimeout(() => {
this.trigger('mediaupdatetimeout');
this.mediaUpdateTimeout = null;
brandonocasey marked this conversation as resolved.
Show resolved Hide resolved
}, refreshDelay(this.media(), Boolean(mediaChanged)));
}

Expand Down
14 changes: 13 additions & 1 deletion src/master-playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ export class MasterPlaylistController extends videojs.EventTarget {

this.masterPlaylistLoader_.on('playlistunchanged', () => {
const updatedPlaylist = this.masterPlaylistLoader_.media();

// ignore unchanged playlists that have already been
// excluded for not-changing. We likely just have a really slowly updating
// playlist.
if (updatedPlaylist.lastExcludeReason === 'playlist-unchanged') {
return;
}

const playlistOutdated = this.stuckAtPlaylistEnd_(updatedPlaylist);

if (playlistOutdated) {
Expand All @@ -480,7 +488,8 @@ export class MasterPlaylistController extends videojs.EventTarget {
// one is updating (and give the player a chance to re-adjust to the
// safe live point).
this.blacklistCurrentPlaylist({
message: 'Playlist no longer updating.'
message: 'Playlist no longer updating.',
reason: 'playlist-unchanged'
});
// useful for monitoring QoS
this.tech_.trigger('playliststuck');
Expand Down Expand Up @@ -1066,6 +1075,9 @@ export class MasterPlaylistController extends videojs.EventTarget {

// Blacklist this playlist
currentPlaylist.excludeUntil = Date.now() + (blacklistDuration * 1000);
if (error.reason) {
currentPlaylist.lastExcludeReason = error.reason;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the short term, do you think we should add this as lastExcludeReason_ to prevent others from using it? Or maybe we should decide if it would make sense to have an array of reasons/what we want a public API on playlists should be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think making it an underscore works as I think our whole exclusion mechanism needs a rework and I don't want anyone to rely on it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, let's keep it private for now. We should think about this more formally for the longer term.

}
this.tech_.trigger('blacklistplaylist');
this.tech_.trigger({type: 'usage', name: 'vhs-rendition-blacklisted'});
this.tech_.trigger({type: 'usage', name: 'hls-rendition-blacklisted'});
Expand Down