http-streaming icon indicating copy to clipboard operation
http-streaming copied to clipboard

HLS video is not resuming after network issues

Open nicklive opened this issue 5 years ago β€’ 64 comments

Description

Hello, I have an issue with video.js+http-streaming, that I can consistently reproduce on basicly all hls streams. Video.js is not resuming live stream after network issues (slow connection and resuming to normal).

Here reduced test case but for reproducing you need to throttle your connection with chrome devtools (please see Steps to reproduce).

Steps to reproduce

  1. Open link
  2. Wait for loading example and video start
  3. Open chrome devtools set throttling for 100 kb/s
  4. Wait about 50 seconds (or a bit more)
  5. After set throttling to online

Results

Expected

Logically after Steps to reproduce video should resume back to live

Actual

video.js+http-streaming try to load infinity times one segment and aborting it, video is not resuming

Error output

Error output contains a lot of

video.js:142 VIDEOJS: ERROR: DOMException: Failed to set the 'duration' property on 'MediaSource': The 'updating' attribute is true on one or more of this MediaSource's SourceBuffers.
    at HtmlMediaSource.addSeekableRange_ (https://unpkg.com/[email protected]/dist/video.js:49141:44)
    at addSeekableRange (https://unpkg.com/[email protected]/dist/video.js:55039:36)
    at PlaylistLoader.<anonymous> (https://unpkg.com/[email protected]/dist/video.js:55054:15)
    at PlaylistLoader.data.dispatcher (https://unpkg.com/[email protected]/dist/video.js:1818:33)
    at trigger (https://unpkg.com/[email protected]/dist/video.js:1954:27)
    at PlaylistLoader.EventTarget.trigger (https://unpkg.com/[email protected]/dist/video.js:2432:5)
    at PlaylistLoader.haveMetadata (https://unpkg.com/[email protected]/dist/video.js:39151:14)
    at https://unpkg.com/[email protected]/dist/video.js:39089:17
    at Object.callback (https://unpkg.com/[email protected]/dist/video.js:40086:9)
    at cbOnce (https://unpkg.com/[email protected]/dist/video.js:7220:17)

Additional Information

There are 3 segments in samlpe hls playlist, but I tried 30 segments in playlist and problem repeats but after more delay (2 min) in 4 step.

videojs-http-streaming version

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

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 Chrome 71.0

Platforms

Windows 10 64-bit

Other Plugins

none

Other JavaScript

none

nicklive avatar Jan 16 '19 13:01 nicklive

πŸ‘‹ 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.

welcome[bot] avatar Jan 16 '19 13:01 welcome[bot]

I get the exact same behavior. My videojs session recursively displays:

VIDEOJS: ERROR: DOMException: Failed to set the 'duration' property on 'MediaSource': The 'updating' attribute is true on one or more of this MediaSource's SourceBuffers. at HtmlMediaSource.addSeekableRange_ (http://localhost:4300/vendor.js:269446:44) at addSeekableRange (http://localhost:4300/vendor.js:275344:36) at PlaylistLoader. (http://localhost:4300/vendor.js:275359:15) at PlaylistLoader.data.dispatcher (http://localhost:4300/vendor.js:221309:33) at trigger (http://localhost:4300/vendor.js:221445:27) at PlaylistLoader.EventTarget.trigger (http://localhost:4300/vendor.js:221923:5) at PlaylistLoader.haveMetadata (http://localhost:4300/vendor.js:259445:14) at http://localhost:4300/vendor.js:259375:17 at Object.callback (http://localhost:4300/vendor.js:260390:9) at cbOnce (http://localhost:4300/vendor.js:226932:17)

lewma avatar Feb 09 '19 01:02 lewma

i have same issue

when connection speed drops player can't recover after connection is recovered

thecotne avatar Mar 20 '19 11:03 thecotne

Same issue here, to reproduce simply set "Slow 3G" in network tab in Google Chrome DevTools... after the connection is restored to "Online" the problem persist. Someone have found a temporary solution?

UPDATE: the error is not detected by the " .on('error' ... " event. So i have no way to refresh in case this error occurs.

Error Detail:

VM37369 video.js:142 VIDEOJS: ERROR: DOMException: Failed to set the 'duration' property on 'MediaSource': The 'updating' attribute is true on one or more of this MediaSource's SourceBuffers. at HtmlMediaSource.addSeekableRange_ (http://localhost:3000/vendor/videojs/video.js:49956:44) at addSeekableRange (http://localhost:3000/vendor/videojs/video.js:55855:36) at PlaylistLoader.<anonymous> (http://localhost:3000/vendor/videojs/video.js:55870:15) at PlaylistLoader.data.dispatcher (http://localhost:3000/vendor/videojs/video.js:1818:33) at trigger (http://localhost:3000/vendor/videojs/video.js:1954:27) at PlaylistLoader.EventTarget.trigger (http://localhost:3000/vendor/videojs/video.js:2432:5) at PlaylistLoader.haveMetadata (http://localhost:3000/vendor/videojs/video.js:39954:14) at http://localhost:3000/vendor/videojs/video.js:39884:17 at Object.callback (http://localhost:3000/vendor/videojs/video.js:40899:9) at cbOnce (http://localhost:3000/vendor/videojs/video.js:7441:17)

alessandro-bottamedi avatar Mar 22 '19 18:03 alessandro-bottamedi

I got this problem too. how to fix it?

coolicer avatar Apr 15 '19 03:04 coolicer

I'm trying to find a solution to try and play if a hls live stream isn't available. Once it goes to an error , you can't click to play again. Any ideas ?

danrossi avatar Apr 15 '19 04:04 danrossi

This causes a stack issue, as the player tries to autoload instead of after clicking. Can't turn off autoloading

player.on("error", () => {

        	player.pause();
        	player.trigger("ended");
        
        	player.reset();
        
        	player.src(player.currentSrc());

        });

danrossi avatar Apr 15 '19 04:04 danrossi

@danrossi It may not catch on error event

coolicer avatar Apr 15 '19 10:04 coolicer

The error must be catched at the line 50294 (ver 7.5.1):

this.nativeMediaSource_.duration = end;

I modified it in this way:

  try {
    this.nativeMediaSource_.duration = end;
  } catch (e) {
    if (typeof streamCustomError === "function") { 
      streamCustomError(e);
    }
    return this.trigger('error');
  } 

Where streamCustomError(e) is my custom function to handle this specific error....

However I noticed that after about 5 minutes the video streaming starts again correctly.

alessandro-bottamedi avatar Apr 15 '19 10:04 alessandro-bottamedi

An offline stream will go to error but no way to click to try and play again. Setting the src will try and start loading again.

danrossi avatar Apr 15 '19 10:04 danrossi

An example fiddle I found. With a non existent manifest, you cant click to try and load again

https://jsfiddle.net/m3sf8nav/

danrossi avatar Apr 15 '19 10:04 danrossi

@alessandro-bottamedi What did you do in streamCustomError function

coolicer avatar Apr 15 '19 11:04 coolicer

@alessandro-bottamedi What did you do in streamCustomError function

I reset and reload the video streaming after a timeout...

alessandro-bottamedi avatar Apr 15 '19 12:04 alessandro-bottamedi

@alessandro-bottamedi Thank you, I'll try it later.

coolicer avatar Apr 15 '19 12:04 coolicer

this could wind up being a billing issue for those using cdns to deliver hls. i discovered this bug watching metrics in my own cdn account after flipping the switch in my player for users that are very distant from my hls relay server to help with buffering.

using a single client to test (2.5Mbps~ video), set browser throttle speed to about 200kbps. after a while it requests the same ts chunk hundreds of times (300+ if i just let it go forever)

balloons up to quite a bit of bandwidth (17x !!)

eventually the bandwidth dips off at the end there as it starts abandoning requests. the player stops abandoning requests after a bit which just starts this cycle over again.

since the player is still trying to dl all of these segments it is requesting, the player is presumably making the flakey connectivity problem severely worse for the end user since they are now trying to download the same segment hundreds of times.

i tested this on the latest firefox and chrome at the time of writing and you can see the videojs version in the screenshot (7.5.4).

json-m avatar May 06 '19 18:05 json-m

When the connection drops completely, videojs tries all lower quality settings and keeps the lowest. When the connection is re-established, it resumes playback at lowest quality and does not return to a better quality stream. Is there a way to circumvent this behaviour? Especially in cases where videojs is used in applications that are not controlled by any user and complete reloads should be avoided, this is critical.

image

I've also noticed that the waiting event is sometimes followed immediately by a timeupdate event which makes the waiting event almost useless because there's a contradiction that can not be tackled by logic.

Also, re-initialising the same stream in the same div after a call to dispose() almost always leads to long waiting time (~20s) where the poster is already removed but only the progress event fires, no timeupdate event. Only after ~50MB of downloaded data, the video finally gets displayed. When its loaded at the very beginning (fresh page load), it starts almost immediately (<1s).

movAX13h avatar Jun 03 '19 16:06 movAX13h

Firefox is doing this as well.

Videojs version video.js 7.4.3 and 7.5.5

Browsers Firefox 68.0b7

Platforms Windows 10 64-bit

pacepace avatar Jun 05 '19 05:06 pacepace

any update?

vksbansal avatar Sep 24 '19 10:09 vksbansal

I'm facing the same issue as outlined above - tested in the latest version of http-streaming (v1.11.1) and also on the latest version of video.js (v7.6.5)

arjitsachdeva avatar Oct 14 '19 10:10 arjitsachdeva

any update?

snowdream avatar Oct 20 '19 00:10 snowdream

I got this problem too. Any update?

bruinxs avatar Oct 28 '19 08:10 bruinxs

I've built an offline reconnect feature. Tested with HLS and Wowza.

https://videojs.electroteque.org/offline

danrossi avatar Oct 28 '19 09:10 danrossi

Can I prevent this error through plug-ins or other methods?

lusase avatar Nov 13 '19 06:11 lusase

@alessandro-bottamedi Thank you, I'll try it later. Have you solved it?

flexmodule avatar Nov 29 '19 09:11 flexmodule

any update?

flexmodule avatar Nov 29 '19 09:11 flexmodule

any update? I got the same issue

dkirilenko avatar Dec 12 '19 13:12 dkirilenko

I've notice that this bug was introduced on version 7.2.1, downgrading to version 7.2.0 solves this problem (at least till someone comes up with more stable solution)

picheli20 avatar Mar 10 '20 13:03 picheli20

in [email protected] videojs/http-streaming has been updated from 1.2.1 to 1.2.3 here is merge request https://github.com/videojs/video.js/pull/5368/files

i have checked latest videojs [email protected] with videojs/[email protected] it works

and [email protected] with videojs/[email protected] has this bug

so regression is somewhere here https://github.com/videojs/http-streaming/compare/v1.2.1...v1.2.2

there is total of 3 commits that can possibly cause any issue (others are tests or docs modifications)

  • https://github.com/videojs/http-streaming/commit/6c68761b5d06d951d7ed20cbd5bb63f324ad2c47
  • https://github.com/videojs/http-streaming/commit/7c683354ec21e60fbd4d90f8a82e37586fef9f87
  • https://github.com/videojs/http-streaming/commit/960ee797e1665b5176f66490897c2f548f88f4e0

from this commits one is mux.js update i have checked old mux.js version and it has same bug

from remaining two one is typeofs minification related (less likely to cause any problem)

and second is updates of seeking behavior and i think this commit is a problem https://github.com/videojs/http-streaming/commit/6c68761b5d06d951d7ed20cbd5bb63f324ad2c47 (committed by @gesinger and merged by @forbesjo)

thecotne avatar Mar 11 '20 15:03 thecotne

Thanks for the deeper dive, it was helpful. We're looking into this and should have a better answer on this some time today.

gkatsev avatar Mar 11 '20 15:03 gkatsev

Thanks to everyone for narrowing it down. We were actually just looking into this, and narrowed down the issue to the same commits pointed out by @thecotne, as per @picheli20 's finding of what version first started the issue.

The commit which causes the issue is, as @thecotne identified, https://github.com/videojs/http-streaming/pull/161 , a change where we updated how we perform seeks in VHS.

We looked a little further into it, and found that this change may have uncovered a deeper issue in VHS related to duration updates.

When the network connection is throttled for live streams, a couple of things happen:

  1. Manifest refreshes continue, and are generally successful due to the small number of bytes downloaded
  2. Segment requests continue, but often fail due to the larger number of bytes required and a slow connection

Since the manifest refreshes continue to happen, the seekable range (live window) continues to move forwards, while, due to the segment request failures, the current time stays behind, and eventually, the current time is before the start of the seekable range. In this case, where we "fall off" the live window, we seek to the end of the seekable range (this is performed by playback wacher).

The seek goes through the middleware, and tries to update the tech's current time (as per the PR noted). We placed a debugger in the seekTo function, and noted that the currentTime on the native video element does not update. Instead of seeking to the end of the seekable range, the native video element's current time remains unchanged.

Checking back in the console log (and as noted in the issue), we saw that we tried to update the duration of the native media source at one point, but the duration update failed because the media source was in the updating state (it was busy). This happened because we don't queue the duration change as we should, and do for other operations in source updater.

This chain of events leads to a loop of the playback watcher attempting to correct the current time to the end of the seekable range and the media element adjusting the seek position back to the old duration value which hasn't been updated.

So the source of the issue may be the duration update not being queued, and the PR brought with it a case that surfaced the issue. But it's also possible that the seeks themselves pose a problem. We're currently investigating both.

On a side note, we are in the process of working on the master branch of VHS (rather than the 1.x branch), which includes many changes to the segment loading process (primarily, transmuxes happen before appends, rather than during appends). The branch does not present such problems. Duration changes on the native media source are queued there, so that leads us to the belief that the root of the problem lies there. We don't have an expected release yet of the switchover to the master branch, but this is provided mainly as evidence of our theory, and if anyone wants to test the behavior there, we are happy to hear your own results.

We'll continue our investigation and updates. Thanks again for everyone helping provide samples and findings!

gesinger avatar Mar 11 '20 15:03 gesinger