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

Stops Requesting TS Files After m3u8 Reset

Open lastpeony opened this issue 1 month ago • 12 comments

Description In the context of a media server cluster setup, a peculiar behavior was observed in VideoJS HLS playback. When the M3U8 playlist file is updated to start TS file indexes from 0, the playback stalls until it reaches the last succesfull TS file number. This anomaly was discovered during the operation of a cluster comprising two origin nodes, one edge node, and an Nginx server.

Consider the following scenario:

User streams content to Nginx, which then forwards the stream to ORIGIN1. Viewers access the content through EDGE1. If ORIGIN1 crashes, the stream reconnects to ORIGIN2. TS files on ORIGIN2 start generating from index 0. Viewers receive a new M3U8 playlist pointing to 0.ts. Playback halts until the TS file indice reaches the previous highest number, even though the new M3U8 contains 0.ts. This behavior is exhibited because VideoJS stops requesting TS files once it encounters a discrepancy in the M3U8 file, waiting until the M3U8 file catches up to the previous TS file indice.

videojs hls bug In above screenshot i crash the ORIGIN1 when ts 229 is received. Afterwards stream starts to be generated on ORIGIN2 and viewer gets the new m3u8 file with ts starting from 0. From this point videoJS stops retrieving TS files and stalls until ts number 230 is reached.

videojs hls bug2

To reproduce the issue:

Initiate HLS stream playback and wait until the last requested TS file number reaches 100. Update the M3U8 source, ensuring that the TS files start from 0. Despite the existence of TS files in the new source, VideoJS does not request 0.ts and waits until the M3U8 contains the TS file numbered 100. Playback resumes after reaching this point.

Expected Outcome Upon receiving a new M3U8 with reset TS indices, Video.js should promptly request and retrieve 0.ts and subsequent TS files.

Observed Behavior Below screenshot error printed on console. VideoJS fails to retrieve 0.ts until the M3U8 playlist aligns with the previous TS file count. playback stalls

It appears that Video.js retains the last received ts number, and if the updated new M3U8 file doesn't contain it, Video.js simply holds until an M3U8 with that ts number is retrieved. Is there a method to reset this number?

Some update: I played with some HLS settings to check if it will fix this problem. Changed HLS playlist type to event and removed end playlist tag. After manifest update(indice reset) videojs starts to print this log to console:

video.es-d9c0c083-DCAKdAZJ.js:18167 Uncaught TypeError: Cannot read properties of undefined (reading 'end')
    at SegmentLoader.chooseNextRequest_ (video.es-d9c0c083-DCAKdAZJ.js:18167:732)
    at SegmentLoader.fillBuffer_ (video.es-d9c0c083-DCAKdAZJ.js:18146:24)
    at SegmentLoader.monitorBufferTick_ (video.es-d9c0c083-DCAKdAZJ.js:18135:57)

Videojs version: 8.12

image

Keeps printing this until indice catches up with last success one, as always.

Video demonstration of the issue:

https://streamable.com/vhjsac At the 1:50 mark, you'll see that I stop one origin and make the switch, new manifest has ts starting from 0, causing the playback to stall until ts indice catch ups

lastpeony avatar May 14 '24 12:05 lastpeony