Closed squarebracket closed 5 years ago
I think I've managed to nail down all the fiddly bits here.
I had some trouble with the tests, like mediachange
not firing for some reason, so it'll probably take me a bit to get through making the tests, but the code itself should be feature-complete.
Added browser workarounds for old vjs versions
Thank you for your PR but we will not be accepting new changes for this repo and will be archived very soon. I would advise you to open your PR against the next iteration of this project at https://github.com/videojs/http-streaming.
For anyone who lands here, I opened PR videojs/http-streaming#370.
Description
This change requires videojs/video.js#5024, which takes care of the UI and API aspects of buffering.
SourceHandlers that use MSE have a problem: if they push a segment into a
SourceBuffer
and then seek close to the end, playback will stall and/or there will be a massive downswitch in quality. The general approach to fixing this that was discussed on slack was by setting the playback rate of the player to zero, buffering all that was required, and then restoring the previous playback rate. In my implementation, I've done this in the source handler.Additionally, there is a new
seekDeadline
option for the source handler which controls how long a seek should take to resume. When seeking, the master playlist controller calculates the maximum bandwidth playlist for all requests needed to complete a full seek. The calculations are done usingminRebufferMaxBandwidthSelector
(renamed tomaxBandwidthForDeadlineSelector
).Besides being a generally good change, this was somewhat needed for backwards compatibility with older video.js versions. Because of this, if you cause playback to stall after seek by seeking too close to the end of a segment, the second segment will have its spinner disappear (since you'll get a
timeupdate
after thewaiting
). This error is currently masked because seek quality is trashed when seeking, so you'll always be able to buffer the second segment before the spinner disappears from thetimeupdate
.With the seek deadline enforcement, although not a real fix, it is significantly mitigated since you'll be kicked down to a lower rate for seeks which require downloading two segments. So you probably won't end up with any noticeable delay between spinner disappearing and playback resuming. For that reason, I think the "buffer appropriate number of segments" and the "seek deadline enforcement" should be considered a single PR.
When combined with #1239, this makes the seeking behavior vastly improved:
player.seeking()
is now trueplayer.seeking()
is now falsevideojs/videojs-contrib-hls#1239 has been reviewed, but I don't believe it's been tested. Let me know if you want me to stage the changes here so it can all be considered as part of a single PR.
Specific Changes proposed
seekDeadline
option for controlling how long a seek should take to resumeseeking()
is deferred from the tech to the SourceHandlersetCurrentTime
stores the current playback rate and set the tech's playback rate to zeroSegmentLoader#handleUpdateEnd_
, if we have enough buffer that we can make another request in that time, firebuffered
onthis
MasterPlaylistController
receives thebuffered
event and restores the previous playback rateminRebufferMaxBandwidthSelector
has been renamed tomaxBandwidthForDeadlineSelector
, and made more genericextraRequests
parameter which is added to thenumRequests
for the segmentrebufferingImpact
, it now just returnsrequestTimeEstimate
maxBandwidthForDeadlineSelector
,abortRequestEarly_
uses either the current calculation (when not seeking) or the time elapsed since seeking startedabortRequestEarly_
is now a bit simpler because it's now using therequestTimeEstimate
instead ofrebufferingImpact
fastQualityChange_
now accepts anextPlaylist
option which will be used instead ofthis.selectPlaylist()
when givenRequirements Checklist
Notes
This is implemented assuming that the video segment loader will always finish after the other segment loaders. I also made an implementation that guarantees all segment loaders have enough data, if you want to compare what that would be like. I found this to be much more concise which is why it gets the PR.
Figuring out some of the testing stuff was becoming troublesome. It'll probably take me a while to get through adding all the tests.