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

Sometimes the player plays segments that have already been played (HLS Live)

Open dzianis-dashkevich opened this issue 1 year ago • 0 comments

Description

Hello, Video.Js and VHS Teams!

I noticed that sometimes the player switches to the segments that were played N seconds before and starts playing them again (for HLS Live).

I collected logs and dived into the source code.

Let's review the following situation:

Assume we have a playlist for rendition-1 (I replaced actual segments and added several comments for simplicity): rendition-1-with-comments

For any reason (for example bandwidth update) player decided to switch to a playlist for rendition-2:

rendition-2-with-comments

Since we just switched to another rendition segment-loader will call resetLoader and will choose the closest segment to the current time. Now we need to calculate the timestamp offset. Let's stop here and take a look closely...

Current timestamp offset calculation from the source code (i removed all comments for simplicity): timestampOffsetCalculation

Since currentTimeline is 16 and segmentTimeline is 15, timestamp offset will be startOfSegment. So Browser's media pipeline will place this segment in the proper place in the buffer.

On the next fillBuffer tick player will proceed with the next segment for the current rendition. Since the next segment is discontinuity (currentTimeline is 15 and segmentTimeline is 16). Timestamp offset will be buffered end. So Browser's media pipeline will place this segment at the buffer's end.

Here is the actual root cause. This segment is already in the buffer, but from rendition-1 and it is even not played yet. So it will be played twice. Moreover, further segments will be placed at the buffer end too, since both currentTimeline and segmentTimeline will be 16, so there will be multiple duplicate segments at the end of the buffer.

It seems to me as a bad user experience since it can be a pretty long duplication playback (depending on how many segments were already buffered before) In the example above it will be 3 segments = 15 seconds.

I prepared a visualization of the example above:

image

I don't have a fast solution for this particular issue right now (in terms of the video.js codebase), but currently, I have a custom video.js patch that addresses the following issue: https://github.com/videojs/http-streaming/issues/1255

I just added the option for fast-quality-switch and disabled it (it should also be used with caution in case of low-latency enabled as well):

fast-quality-switch-option

So, in this case: fetchAtBuffer_ will not be set to false after each rendition switch and there will be no segment downloads close to the currentTime, So there will be no duplicate loads. While disabling fast quality. switching solves a different problem for us - by induction, it solves this issue as well. You may consider providing this option for the library users as a fast solution with several comments about usage...

Steps to reproduce

  • You need any stream with multiple discontinuities
  • start playing, emulate bandwidth throttle
  • try to catch the case described above

Browsers

LTS Chrome

Platforms

Linux, macOS, Windows

Other Plugins

No.

dzianis-dashkevich avatar Jul 30 '22 23:07 dzianis-dashkevich