hls.js icon indicating copy to clipboard operation
hls.js copied to clipboard

No 'ended' event on Safari only by my stream

Open legolaserea opened this issue 1 year ago • 6 comments

What version of Hls.js are you using?

1.4.10

What browser (including version) are you using?

Safari 16.5

What OS (including version) are you using?

Mac OS 12.6

Test stream

https://voddemo-play.volcvod.com/1dd490a910e143de95c1e6a0345e1d81.m3u8?auth_key=1784955407-8c15a1326e1f45929b43f26b1826c6b0-0-8d947d2362115532e3306b9b9c692111

Configuration

{debug: true}

Additional player setup steps

No response

Checklist

  • [X] The issue observed is not already reported by searching on Github under https://github.com/video-dev/hls.js/issues
  • [X] The issue occurs in the stable client (latest release) on https://hlsjs.video-dev.org/demo and not just on my page
  • [X] The issue occurs in the latest client (main branch) on https://hlsjs-dev.video-dev.org/demo and not just on my page
  • [X] The stream has correct Access-Control-Allow-Origin headers (CORS)
  • [X] There are no network errors such as 404s in the browser console when trying to play the stream

Steps to reproduce

  1. use the test stream "https://voddemo-play.volcvod.com/1dd490a910e143de95c1e6a0345e1d81.m3u8?auth_key=1784955407-8c15a1326e1f45929b43f26b1826c6b0-0-8d947d2362115532e3306b9b9c692111"
  2. play the video to the end on mac Safari or iPhone safari, it will not have 'ended' event appear.

Expected behaviour

The 'ended' event will be triggered when the video is played to the end

What actually happened?

The 'ended' event not be triggered when the video is played to the end

Console output

"[buffer-controller]: Could not call mediaSource.endOfStream(). mediaSource.readyState: ended"

Chrome media internals output

No response

legolaserea avatar Jul 26 '23 05:07 legolaserea

If it is browser issue, is there someone can help provide some encoding suggestion to avoid this problem?

legolaserea avatar Aug 07 '23 02:08 legolaserea

@legolaserea On that m3u8 Test Stream, 2 of the streams are 10 seconds, and the 3rd is 2.88 seconds. If you remove that 3rd stream from your m3u8, does it make a difference in the "ended" event for the video?

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:10
#EXTINF:10.000,
75530d3c17e14d0fb962953d903d6df4_0.ts?auth_key=1784955407-8c15a1326e1f45929b43f26b1826c6b0-0-b8904580fcc42c43a1dc893ab7c48325
#EXTINF:10.000,
8e9382dfb65e4166bad9e975964a6c4f_1.ts?auth_key=1784955407-8c15a1326e1f45929b43f26b1826c6b0-0-4ea6f02e0ff4c66af19d17991429b398
#EXTINF:2.880,
09d6c6915c614675988de1c20a5e3abc_2.ts?auth_key=1784955407-8c15a1326e1f45929b43f26b1826c6b0-0-fe96597de902db744c324a92ce34ce46
#EXT-X-ENDLIST

karendolan avatar Sep 12 '23 19:09 karendolan

Experiencing the same problem in Safari 16.5.1 on desktop. I can't reproduce with Big Buck Bunny on https://hlsjs.video-dev.org/demo/, but I can reproduce with my test stream.

I get the following errors in the console when the video ends:

[Info] [info] > – "[buffer-controller]: Cannot flush audio back buffer while SourceBuffer is in ended state" (hls.js, line 19370)
[Info] [info] > – "[buffer-controller]: Cannot flush video back buffer while SourceBuffer is in ended state" (hls.js, line 19370)
[Warning] [warn] > – "Playback stalling at @120.02348805 due to low buffer ({\"len\":0.0004348524943367238,\"start\":117.14322222222222,\"end\":120.02392290249433})" (hls.js, line 15261)
[Warning] Error event: – {type: "mediaError", details: "bufferStalledError", fatal: false, …} (hls-demo.js, line 24772)
{type: "mediaError", details: "bufferStalledError", fatal: false, error: Error: Playback stalling at @120.02348805 due to low buffer ({"len":0.0004348524943367238,"start":11…, buffer: 0.0004348524943367238, …}Object

I have previously had a similar issue with my streams in all browsers in 1.1.2 but I believe it was already resolved in other browsers: https://github.com/video-dev/hls.js/issues/4783. I'm using ffmpeg to encode. I think the underlying issue could be due to that encoding process producing short final segments?

gpoole avatar Oct 10 '23 03:10 gpoole

Testing a bit more I'm noticing that in my case this problem is inconsistent. Sometimes the ended event fires, sometimes it doesn't.

Bit of a hack but I'm trying a temporary workaround by adding a media error handler that calls my ended code manually if a bufferStalledError triggers "near enough" to the end of the video:

hls.on(Hls.Events.ERROR, (event, data) => {
  if (data.type === Hls.ErrorTypes.MEDIA_ERROR && data.details === 'bufferStalledError') {
    if (video.duration - video.currentTime < 0.1) {
      onEndedHandler();
    }
  }
});

video.addEventListener('ended', onEndedHandler);

gpoole avatar Oct 10 '23 03:10 gpoole

Same problem here but on Chrome 120 (dev). When the video reaches ~3 seconds from the end, it triggers bufferStalledError and immediately afterwards bufferNudgeOnStall.

RealAlphabet avatar Nov 04 '23 14:11 RealAlphabet

Hopefully fixes that landed in Safari 17 have improved the reliability of the "ended" event for those of you who have experienced it in the past. We've moved the automated Safari test runs to latest and have seen much better results on tests that include seeking near the end and listening for "ended". There are some edge cases like certain tests with overlapping appends on start not firing the event; presumably, re-appending the first segment before playback begins might interfere with autostart which can fail the test, and I've seen "ended" fire on VOD even when HLS.js has not marked EoS on the MediaSource.

The purpose of #6141 if to give you an event you can rely on even in older use-agents or streams with issues near the end. Please try it out and leave feedback on the PR. Thanks!

robwalch avatar Jan 24 '24 19:01 robwalch