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: stutter after fast quality change in IE/Edge #213

Merged
merged 9 commits into from
Sep 21, 2018
17 changes: 13 additions & 4 deletions src/master-playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,21 +523,30 @@ export class MasterPlaylistController extends videojs.EventTarget {
*/
fastQualityChange_() {
const media = this.selectPlaylist();
const isPaused = this.tech_.paused();

if (media === this.masterPlaylistLoader_.media()) {
return;
}

this.tech_.pause();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it necessary for us to pause? I think that may have inadvertent side effects.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rendition switch occurs without a stutter even without pausing/playing, but for some reason timeupdate events continue to fire even while playback has stopped and the loading spinner isn't shown. This only happens in IE/Edge.

Copy link
Contributor

Choose a reason for hiding this comment

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

We may want to look into that further. I'm hesitant for us to initiate a pause, as it could have inadvertent behavior with user integrations. For instance, if someone is listening to paused events to display an overlay or make another action happen, then this will cause that behavior to trigger.

this.masterPlaylistLoader_.media(media);

// delete all buffered data to allow an immediate quality switch, then seek
// in place to give the browser a kick to remove any cached frames from the
// previous rendition
// Delete all buffered data to allow an immediate quality switch, then seek
// forward slightly to give the browser a kick to remove any cached frames from the
// previous rendition (.04 seconds ahead is roughly the minimum that will accomplish this
// across a variety of content in IE and Edge)
// Edge/IE bug: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14600375/
// Chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=651904
this.mainSegmentLoader_.resetEverything(() => {
// Since this is not a typical seek, we avoid the seekTo method which can cause
// segments from the previously enabled rendition to load before the new playlist
// has finished loading
this.tech_.setCurrentTime(this.tech_.currentTime());
this.tech_.setCurrentTime(this.tech_.currentTime() + .04);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be seeking forwards for all browsers, or just those that are problematic?

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 was on the fence about whether it's better to minimize the scope of the forward seeking, or to omit any user agent checks and have uniform quality switch behavior across browsers. I'll defer to your judgement on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be interested to hear others' thoughts as well, but I think minimizing the scope may be better, just to limit potential impact, especially when it's only one set of browsers (IE/Edge).


if (!isPaused) {
this.tech_.play();
}
});

// don't need to reset audio as it is reset when media changes
Expand Down