videojs / video.js

Video.js - open source HTML5 video player
https://videojs.com
Other
38.02k stars 7.45k forks source link

Fullscreen toggle leads to "Excessive main segment downloading detected" #8452

Open max-arnold opened 1 year ago

max-arnold commented 1 year ago

Description

Playback watcher seems to be buggy: switching to full screen mode in and out a couple of times results in all HLS streams being blacklisted. Seems to happen when the video quality switching occurs.

Reduced test case

https://videojs-http-streaming.netlify.app/?url=https%3A%2F%2Ffullscreen-bug.storage.yandexcloud.net%2Fmaster.m3u8

Steps to reproduce

  1. The test case shows exact steps on how to reproduce the problem

Errors

VIDEOJS: WARN: Problem encountered with playlist 0-540p.m3u8. Excessive main segment downloading detected. Switching to playlist 1-720p.m3u8. VIDEOJS: WARN: Problem encountered with playlist 2-1080p.m3u8. Excessive main segment downloading detected. Switching to playlist 1-720p.m3u8. VIDEOJS: ERROR: (CODE:3 MEDIA_ERR_DECODE) Playback cannot continue. No available working or supported playlists. Object { code: 3, message: "Playback cannot continue. No available working or supported playlists." }

What version of Video.js are you using?

8.5.2

Video.js plugins used.

No response

What browser(s) including version(s) does this occur with?

Firefox, Chrome

What OS(es) and version(s) does this occur with?

macOS

video-archivist-bot commented 1 year ago

Hey! We've detected some video files in a comment on this issue. If you'd like to permanently archive these videos and tie them to this project, a maintainer of the project can reply to this issue with the following commands:

welcome[bot] commented 1 year ago

👋 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.

max-arnold commented 1 year ago

Related issues: https://github.com/videojs/http-streaming/pull/829 https://github.com/videojs/http-streaming/issues/1356 https://github.com/videojs/video.js/issues/7842 https://github.com/videojs/http-streaming/issues/1130 https://github.com/videojs/video.js/issues/8054 https://github.com/videojs/http-streaming/issues/1064 https://github.com/videojs/video.js/issues/7992 https://github.com/videojs/http-streaming/issues/1285 https://github.com/videojs/video.js/issues/8026

Cc: @brandonocasey

max-arnold commented 1 year ago

A really really dirty workaround:

  1. Make a local copy of https://vjs.zencdn.net/8.5.2/video.min.js
  2. Delete the following code:
    ,"subtitle"!==e&&t.excludePlaylist({error:{message:`Excessive ${e} segment downloading detected.`},playlistExclusionDuration:1/0})
  3. Use the patched version instead of the one from CDN

Unfortunately this is all I can do given my limited JS knowledge

brandonocasey commented 1 year ago

seems like playback watcher might to reset itself when we switch quality using fastQualityChange_ should be easy enough to fix I think.

adrums86 commented 1 year ago

We did a little refactoring of fastQualityChange_ in VHS v3.5.3, however it looks like it still needs a bit more work. I agree @brandonocasey I think resetting the watcher on quality changes is likely the correct solution. Going to link this to a new issue in VHS.

gsimko commented 12 months ago

I've debugged this issue and the problem is that after the media switch the result of sourceBuffer.buffered() remains intact. Based on the specification I think this is the correct behavior in the web browser. Hence, if after the media change we reload segments that were already buffered before, watcher will think that we are not making any progress.

I'd happily fix the issue but I'm somewhat uncertain of what the desired behavior is. @adrums86 @brandonocasey can you please comment what you think?

AFAIK there are two cases when we need to switch media:

  1. (automatic) when the segment selector decides that the current source is not a good fit. Let's say it decides that instead of 720p we should stream 1080p. In this case, should we keep the already buffered 720p segments around and only use 1080p for the newly fetched segments? Or should we remove these segments and strictly play 1080p going forward so that the user doesn't see the worse quality video?
  2. (manual) IIUC this is handled by fastQualityChange. The idea is that we need to change the resolution right away, hence throwing away the buffered segments seems like the right thing to do. Instead of that currently we reload the segments and use replaceSegmentsUntil to track when we are done. What is the motivation behind this?

Going forward I see a few potential ways:

  1. call pc.sourceUpdater_.removeVideo/removeAudio to actively reset sourceBuffer.buffered but lose all the already downloaded segments. Is this ok for the automatic/manual cases above?
  2. instead of relying on mediaSource.buffered() implement our own version in watcher that resets on media change. I'm not sure if this is feasible but if MSE exposes the right events we might be able to deduce this.
  3. instead of reusing the same video SourceBuffer for all playlists and calling changeType() we could have a separate sourceBuffer for each playlist. In this case sourceBuffer.buffered() would work as intended. However, as I don't have any experience with ABR I'm not sure if it can be supported with this setup.

What's your preference? Do you have any other ideas?

scottie commented 11 months ago

Related https://github.com/videojs/video.js/issues/7842

dygy commented 11 months ago

Hey @scottie , i see you are active for 6 hours ago. Do you had luck to CATCH this warning? i guess we could handle it somehome mannualy but i don't understand how i can try-catch it or get via event listners

dygy commented 11 months ago

videojs.log.warn = (message: string) => { if ( message.includes("Excessive main segment downloading detected") ) { console.log("catch", message); // go do some magick } };

ajaymiyyapuram commented 11 months ago

Our customers also encountered same error during a large live event, several users saw these errors within a 15 min period during a 2 hour long event. We looked at the upstream CDN and the packaging service and didn't notice any errors. Can this error also be thrown for a reason other than full-screen toggle? Player version: 7.20.3 , stackoverflow question

dygy commented 11 months ago

@ajaymiyyapuram for me its just a matter of time in LLHLS stream. And the solution for bow for me was only to catch warning and make denounced rebuild of player, that will make user possible to select quality again.