video-dev / hls.js

HLS.js is a JavaScript library that plays HLS in browsers with support for MSE.
https://hlsjs.video-dev.org/demo
Other
14.81k stars 2.57k forks source link

How to cause a graceful / nature end to a live stream #5341

Closed ddurham2 closed 1 year ago

ddurham2 commented 1 year ago

What do you want to do with Hls.js?

My service produces a live stream, i.e. with the playlist file showing a different window in the chunks as time progresses.

When the listener starts, they request a duration. And so my service, at the end of the listener's duration, needs to present a playlist that indicates the stream is done, and I'd expect hls.js to behave as if the stream came to an end naturally (even though it might continue on for others who initially requested a longer duration).

I'm having the service present this playlist after their duration is expired:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-ENDLIST

Which I thought would indicate end of the stream, but hls.js issues a manifestParsingError followed later by and understandible buferStalledError.

You can correctly surmise that on the server the playlist requests are handled by a script, which may server either the live playlist, or static content, marking the end.

I could detect this particular manifestParsingError and treat that as a stop in my client, but I wanted first to ask if there is a more correct playlist content I could present (preferably a static one like above) that will cause a graceful end to the stream?

Thanks

What have you tried so far?

described above

robwalch commented 1 year ago

You can add end list when the stream ends, but it must still contain segments.

ddurham2 commented 1 year ago

Ok. I'm now trying the following, but ran into a strange situation...

I changed the "finished" playlist have the following content:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:5
#EXTINF:0.000000,
empty.m4s
#EXT-X-ENDLIST

where empty.m4s is just a static, empty file.

But now when Hls.js encounters this playlist, it fetches empty.m4s which has a content length of 0, but then repeatedly fetches it over and over, about every half second. And no errors are being reported from what I can tell.

Is that expected? I'd be concerned if some final m4s file just happened to be empty, then it causes clients to DoS the server unintentionally.. though, I'm not sure a m4s could or would every be exactly zero bytes. I'm definitely in "it's a hack" territory now. I may need to create a proper .m4s file that just has an empty content (looking at that now).

Expected?

EDIT - making the empty.m4s have 1 random byte results in the same behavior. So it's not just some issue with a length of exactly 0.

EDIT - more success making empty.m4s the result of an actual final segment (i.e. running ffmpeg in hls mode for a input truncated to 5 seconds with a 5 second segment length, and taking the produced segment 2 of 2), but at the end of the stream, the HTMLMediaElement goes into a "waiting" state.. definitely into ill-advised land, but looking for a way to induce the client to naturally think the stream is ended. I do have the work-around, though it's not ideal.

EDIT - it works pretty well if I just append #EXT-X-ENDLIST to the playlist of the listener who should end.