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

Switching quality leads to infinite buffering #464

Closed
stevendesu opened this issue Apr 11, 2019 · 7 comments
Closed

Switching quality leads to infinite buffering #464

stevendesu opened this issue Apr 11, 2019 · 7 comments
Labels

Comments

@stevendesu
Copy link

@stevendesu stevendesu commented Apr 11, 2019

Please do not delete the template, by filling out the required information we can investigate your issue more quickly.

Before opening an issue see if your problem can be resolved with the troubleshooting guide.

Description

Briefly describe the issue.
Include a reduced test case, we have a starter template on JSBin you can use.

If you change the quality level of the video before the first TS file loads, it puts VHS into a weird state where it continually downloads the first TS file in the playlist but never appends it to the source buffer or plays. Instead it just scraps the bytes and re-download them again, wasting tons of bandwidth.

Screen Shot 2019-04-11 at 1 37 39 PM

The issue only seems to occur with certain video files (perhaps ones with very large first TS files?) -- I'm still investigating the root cause

Reduced test case (consistently reproduces the issue for me):

https://codepen.io/stevendesu/pen/gyWJep

As best as I can tell, the following seems to be what happens internally:

  1. The video begins to load, and detects all qualities. 720p is selected as the default due to screen size.
  2. The playlists load, hasPlayed_() returns false, so newPlaylist.syncInfo is set. syncPoint_ is set using the Playlist strategy (pulling the syncInfo)
  3. hasPlayed_ gets replaced by a function that always returns true
  4. Within my plugin I run a for loop with qualityLevels[i].enabled = false; for any qualities that don't match the desired bitrate (setting enabled to false on the 720p rendition which had been previously selected)
  5. This triggers fastQualityChange_ which calls resetEverything with a callback to perform a seek
  6. Within resetEverything (or some method that it calls) processingAppend_ is checked and, because it's false, the callback to perform the seek is never run - although manually performing the same seek myself does not fix infinite buffering, so I don't think this is the cause of the bug
  7. When we request the first TS file, syncPoint_ is null so isSyncRequest is set to true
  8. Once the TS file loads, because isSyncRequest is true, we trigger syncinfoupdate and then scrap the TS file without appending it to the buffer
  9. Later monitorBufferTick_ runs, notices our buffer is empty, calls fillBuffer_, and re-downloads the same TS file. But because syncPoint_ is null, isSyncRequest is set to true
  10. Because isSyncRequest is true, we trigger syncinfoupdate then scrap the TS file without appending it to the buffer
  11. Repeat steps 9 and 10 infinitely

Sources

Is a certain source or a certain segment affected? please provide a public (accesible over the internet) link to it below.

https://vcloud.blueframetech.com/file/hls/126136.m3u8

Steps to reproduce

Explain in detail the exact steps necessary to reproduce the issue.

  1. Include videojs-contrib-quality-levels
  2. Create a video with autoplay enabled
  3. Bind a listener for addqualitylevel
  4. In this listener, disable all but one quality level. Be sure to disable whichever quality would normally be selected as default by the screen size

Results

Expected

The video should play at the specified resolution

Error output

The player displays a loading spinner and the developer console shows the first TS file being downloaded every half-second infinitely

Additional Information

Please include any additional information necessary here. Including the following:

videojs-http-streaming version

what version of videojs-http-streaming does this occur with?
videojs-http-streaming 1.5.1

videojs version

what version of videojs does this occur with?
video.js 7.4.1

Browsers

what browsers are affected? please include browser and version for each

  • Firefox 66.0.2
  • Chrome 73.0.3683.103

Platforms

what platforms are affected? please include operating system and version or device and version for each

  • Mac OS X 10.14.4
  • Windows 10

Other Plugins

are any other videojs plugins being used on the page? If so, please list them with version below.

  • One custom plugin, as described in the test case linked

Other JavaScript

are you using any other javascript libraries or frameworks on the page? if so please list them below.
None

@welcome
Copy link

@welcome welcome bot commented Apr 11, 2019

👋 Thanks for opening your first issue here! 👋

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
To help make it easier for us to investigate your issue, please follow the contributing guidelines.

@alex-barstow
Copy link
Contributor

@alex-barstow alex-barstow commented May 3, 2019

PR #496 should fix this.

@marceljager
Copy link
Contributor

@marceljager marceljager commented Jun 26, 2019

Same issue here, everything works fine until I switch quality. After few seconds DASH player freeze and displays loading. HLS is ok.

It's really easy to reproduce:

  • checkout my changes #561 (without this changes it freezes even without switching quality)
  • npm start, visit localhost:9999 and use this source http://1425889403.rsc.cdn77.org/ls-45420-1/rewind-60.mpd
  • enter fullscreen mode. Entering fullscreen mode should switch quality to higher and player will freeze

I tried to use #496 + #500 but still same

@gkatsev
Copy link
Member

@gkatsev gkatsev commented Jun 26, 2019

@marceljager your issue is because we don't currently support live dash with $Time$, unfortunately. See https://github.com/videojs/http-streaming#dash-assets-with-time-interpolation-and-segmenttimelines-with-no-t

@stale
Copy link

@stale stale bot commented Aug 25, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the outdated label Aug 25, 2019
@gkatsev
Copy link
Member

@gkatsev gkatsev commented Aug 26, 2019

We have two potential fixes in #496 and #500 for this, but we haven't had a chance to test and verify that those changes don't cause regressions.

@stale stale bot removed the outdated label Aug 26, 2019
@gkatsev gkatsev added the planned label Aug 26, 2019
gkatsev added a commit that referenced this issue Jan 10, 2020
…oaded (#700)

* Fix live startup failures when play happens before playlist is downloaded

When joining a live stream, VHS starts playback at a time of 0,
regardless of how long the stream has been playing. This means that the
playlist will start with sync info of time 0 for the first media index.

However, if the stream "played" (either via API, autoplay, etc.) before
a playlist was downloaded, then after the playlist downloaded the
loader would reset the sync info, erasing the assumed time 0 for first
media index, and the player would request segments ad infinitum, never
able to place them in the timeline and get a new sync point.

This separates the notion of played between play initiation and playback
of content (progress on the timeline), in order to ensure that the
initial sync info is maintained.

* Use segment loader's state to determine when to update sync info

While using hasPlayedContent helped to alleviate most issues around
when to update the sync info in segment loader when updating a live
playlist, there still remained potential issues when a segment was
requested and the sync info was changed for the in-flight segment.

This change uses the segment loader's INIT state to determine if the
sync info should be updated, meaning in-flight segment requests keep
their sync info fixed.

Fixes #464, closes #496, closes #500.
@gkatsev
Copy link
Member

@gkatsev gkatsev commented Jan 10, 2020

Fixed as part of #700. Release soon.

@gkatsev gkatsev closed this Jan 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.