http-streaming
http-streaming copied to clipboard
Sometimes the player plays segments that have already been played (HLS Live)
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):
For any reason (for example bandwidth update) player decided to switch to a playlist for rendition-2:
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):
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:

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):
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.