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

Unexpected Error: #EXT-X-DISCONTINUITY-SEQUENCE must appear before the first Media Segment

Open dchan-harmonicinc opened this issue 5 months ago • 6 comments

What version of Hls.js are you using?

v1.6.13

What browser (including version) are you using?

Microsoft Edge Version 140.0.3485.81 (Official build) (64-bit)

What OS (including version) are you using?

Ubuntu 20.04.6 LTS

Test stream

No response

Configuration

{
  "debug": true,
  "enableWorker": true,
  "backBufferLength": 90
}

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. Prepare a live stream that supports HLS delta update
  2. Live stream contains non-zero #EXT-X-DISCONTINUITY-SEQUENCE tag
  3. Playback the stream by first requesting the full playlist
  4. Then request the delta update playlist (_HLS_skip=YES)
  5. Example of the first few tags in the delta playlist
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=36.0
#EXT-X-MEDIA-SEQUENCE:661
#EXT-X-SKIP:SKIPPED-SEGMENTS=5054
#EXT-X-DISCONTINUITY-SEQUENCE:99
#EXT-X-VERSION:9
#EXT-X-KEY:METHOD=NONE
#EXT-X-MAP:URI="https://sample-host/init.m4i"
#EXT-X-PROGRAM-DATE-TIME:2025-09-23T23:10:56.316Z
#EXTINF:4.0110,
https://sample-host/segment1.m4a

Expected behaviour

Stream should be played smoothly without any parsing error.

What actually happened?

  1. Console log shows "levelParsingError" when requesting the first delta update playlist
  2. Playback stalled

Console output

Error: #EXT-X-DISCONTINUITY-SEQUENCE must appear before the first Media Segment (#EXT-X-DISCONTINUITY-SEQUENCE:99)
    at assignMustAppearBeforeSegmentsError (https://hlsjs.video-dev.org/dist/hls.js:8733:34)
    at M3U8Parser.parseLevelPlaylist (https://hlsjs.video-dev.org/dist/hls.js:8398:17)
    at PlaylistLoader.handleTrackOrLevelPlaylist (https://hlsjs.video-dev.org/dist/hls.js:36279:37)
    at Object.onSuccess (https://hlsjs.video-dev.org/dist/hls.js:36153:19)
    at XhrLoader.readystatechange (https://hlsjs.video-dev.org/dist/hls.js:31995:79)

Chrome media internals output


dchan-harmonicinc avatar Sep 23 '25 23:09 dchan-harmonicinc

The HLS.js playlist parser treats the #EXT-X-SKIP:SKIPPED-SEGMENTS tag as skipped media segments, so #EXT-X-DISCONTINUITY-SEQUENCE and #EXT-X-MEDIA-SEQUENCE must appear before #EXT-X-SKIP.

In a delta playlist, #EXT-X-SKIP should appear in the place of the segments being replaced, not above. That is why you are seeing this parsing error.

robwalch avatar Sep 23 '25 23:09 robwalch

The delta playlist example would benefit from reordering the tags as follows:

#EXTM3U
#EXT-X-VERSION:9
#EXT-X-TARGETDURATION:6
#EXT-X-DISCONTINUITY-SEQUENCE:99
#EXT-X-MEDIA-SEQUENCE:661
#EXT-X-SERVER-CONTROL:CAN-SKIP-UNTIL=36.0
#EXT-X-SKIP:SKIPPED-SEGMENTS=5054

If you don't get a similar error in mediastreamvalidator or Apple HLS clients, please let me know, and I'll look into whether or not this playlist validation needs fixing.

Currently there is no workaround for this issue. The sequence numbers are required before #EXT-X-SKIP is parsed which increments sequence values (and adds null entries to the fragments array, where fragment.length > 0 is the condition that produces this parsing error when EXT-X-SKIP is encountered).

robwalch avatar Sep 24 '25 00:09 robwalch

@robwalch , thanks for the clear explanations and suggestions.

I have tested moving the #EXT-X-SKIP tag to the bottom as suggested, and the stream can be played back smoothly on v1.6.13 without errors.

If you don't get a similar error in mediastreamvalidator or Apple HLS clients, please let me know, and I'll look into whether or not this playlist validation needs fixing.

I have tested on Safari Version 18.4 (20621.1.15.11.10) on MacBook Pro (M2 Pro) and Safari on iOS 26.0 The stream can be played without issue.

mediastreamvalidator (1.24.5 (686.23b-241115)) also showed no must-fix / should-fix issues related to the #EXT-X-SKIP and #EXT-X-DISCONTINUITY-SEQUENCE tags.

dchan-harmonicinc avatar Sep 24 '25 00:09 dchan-harmonicinc

If we schedule another patch, I'll look into loosening the rule for #EXT-X-DISCONTINUITY-SEQUENCE, otherwise a fix will land in the next minor.

robwalch avatar Sep 24 '25 00:09 robwalch

@robwalch I have the same issue. would be great to have a fix for this. thanks!

enricovittorini avatar Sep 25 '25 15:09 enricovittorini

There's a large number of unit tests for EXT-X-SKIP in delta playlist updates in these files:

https://github.com/video-dev/hls.js/blob/master/tests/unit/controller/level-helper.ts https://github.com/video-dev/hls.js/blob/master/tests/unit/loader/m3u8-parser.ts

as well as a test for this error (not a delta update) in the latter: https://github.com/video-dev/hls.js/blob/3f67c531c38a4fd9535f78d19a6ab535bbd97bb8/tests/unit/loader/m3u8-parser.ts#L3211-L3236

First step would be to add a test for this scenario. Then update the parser to look more strictly at parsed segments before producing this error, and make sure that the disco sequence is applied properly (shouldn't require any action that I can think of, but the test should include coverage).

robwalch avatar Sep 25 '25 20:09 robwalch