-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Closed
Labels
Milestone
Description
What version of Hls.js are you using?
v1.6.2
What browser (including version) are you using?
Chrome 137.0.7151.41 (Official Build) (arm64)
What OS (including version) are you using?
Apple M1 Pro MacOS 15.5 (24F74)
Test stream
No response
Configuration
{
"debug": true,
"enableWorker": true,
"lowLatencyMode": true,
"backBufferLength": 90
}
Additional player setup steps
No response
Checklist
- The issue observed is not already reported by searching on Github under https://github.com/video-dev/hls.js/issues
- The issue occurs in the stable client (latest release) on https://hlsjs.video-dev.org/demo and not just on my page
- The issue occurs in the latest client (main branch) on https://hlsjs-dev.video-dev.org/demo and not just on my page
- The stream has correct Access-Control-Allow-Origin headers (CORS)
- There are no network errors such as 404s in the browser console when trying to play the stream
Steps to reproduce
- Start the stream.
- Confirm normal playback.
- Stop the stream and then restart it.
- A discontinuity occurs.
- Observe that the full chunklist.m3u8 contains #EXT-X-DISCONTINUITY, but it's missing from the chunklist.m3u8 in the delta playlist update.
- Refresh the browser.
- HLS.js playback stops.
Expected behaviour
Playback should be normal.
What actually happened?
-
Playback did not occur, or it played briefly and then stopped.
-
This issue occurs when the full chunklist contains #EXT-X-DISCONTINUITY, but the delta playlist update chunklist does not.
-
For example:
- Download the initial full chunklist
#EXTM3U #EXT-X-VERSION:10 #EXT-X-INDEPENDENT-SEGMENTS #EXT-X-TARGETDURATION:3 #EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=3.126000,CAN-SKIP-UNTIL=20.0 #EXT-X-PART-INF:PART-TARGET=1.000000 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-DISCONTINUITY-SEQUENCE:0 #EXT-X-DATERANGE:ID="nmss-daterange",START-DATE="2025-05-22T07:59:38.809Z" #EXT-X-MAP:URI="720p_0_0.m4s" #EXTINF:2.500000, 720p_0.m4v #EXTINF:2.500000, 720p_1.m4v #EXTINF:2.500000, 720p_2.m4v #EXTINF:2.184667, #EXT-X-DISCONTINUITY #EXT-X-MAP:URI="720p_0_1.m4s #EXTINF:2.500000, 720p_3.m4v #EXTINF:2.500000, 720p_4.m4v #EXTINF:2.500000, 720p_5.m4v #EXTINF:2.500000, 720p_6.m4v #EXTINF:2.500000, 720p_7.m4v #EXTINF:2.500000, 720p_8.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_9_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_9_1.m4v" #EXT-X-PART:DURATION=0.500000,URI="720p_9_2.m4v" #EXTINF:2.500000, 720p_9.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_10_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_10_1.m4v" #EXT-X-PART:DURATION=0.500000,URI="720p_10_2.m4v" #EXTINF:2.500000, 720p_10.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_11_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_11_1.m4v" #EXT-X-PART:DURATION=0.500000,URI="720p_11_2.m4v" #EXTINF:2.500000, 720p_11.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_12_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_12_0.m4v" #EXT-X-PRELOAD-HINT:TYPE=PART,URI="720p_12_2.m4v"
- Download the subsequent delta playlist update chunklist
#EXTM3U #EXT-X-VERSION:10 #EXT-X-INDEPENDENT-SEGMENTS #EXT-X-TARGETDURATION:3 #EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=3.126000,CAN-SKIP-UNTIL=20.0 #EXT-X-PART-INF:PART-TARGET=1.000000 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-DISCONTINUITY-SEQUENCE:0 #EXT-X-DATERANGE:ID="nmss-daterange",START-DATE="2025-05-22T07:59:38.809Z" #EXT-X-SKIP:SKIPPED-SEGMENTS=4 #EXT-X-MAP:URI="720p_0_1.m4s" 720p_4.m4v #EXTINF:2.500000, 720p_5.m4v #EXTINF:2.500000, 720p_6.m4v #EXTINF:2.500000, 720p_7.m4v #EXTINF:2.500000, 720p_8.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_9_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_9_1.m4v" #EXT-X-PART:DURATION=0.500000,URI="720p_9_2.m4v" #EXTINF:2.500000, 720p_9.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_10_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_10_1.m4v" #EXT-X-PART:DURATION=0.500000,URI="720p_10_2.m4v" #EXTINF:2.500000, 720p_10.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_11_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_11_1.m4v" #EXT-X-PART:DURATION=0.500000,URI="720p_11_2.m4v" #EXTINF:2.500000, 720p_11.m4v #EXT-X-PART:DURATION=1.000000,URI="720p_12_0.m4v",INDEPENDENT=YES #EXT-X-PART:DURATION=1.000000,URI="720p_12_0.m4v" #EXT-X-PART:DURATION=1.000000,URI="720p_12_0.m4v" #EXTINF:2.500000, 720p_12.m4v #EXT-X-PRELOAD-HINT:TYPE=PART,URI="720p_13_0.m4
- Until #EXT-X-DISCONTINUITY is removed from the full chunklist.m3u8, errors will continue to occur when loading the delta playlist update chunklist.m3u8.
-
For reference, If you modify
newFragments[0].cc;
tonewFragments[newFragIndex].cc;
at the following location, playback works, but I'm unsure if this is the correct solution:
hls.js/src/utils/level-helper.ts
Lines 176 to 179 in 1d88220
newDetails.startCC = getFragmentWithSN(oldDetails, newDetails.startSN - 1)?.cc ?? newFragments[0].cc; newDetails.endCC = newFragments[newFragments.length - 1].cc;
Console output
Using Hls.js config: {debug: true, enableWorker: true, lowLatencyMode: true, backBufferLength: 90}
logger.ts:102 [log] > Debug logs enabled for "Hls instance" in hls.js version 1.6.3-0.canary.11238
hls.ts:579 [log] > stopLoad
hls.ts:513 [log] > loadSource:https://mydomain.com/test/720p_playlist.m3u8
stream-controller.ts:611 [log] > [stream-controller]: Trigger BUFFER_RESET
hls.ts:466 [log] > attachMedia
buffer-controller.ts:320 [log] > [buffer-controller]: created media source: MediaSource
buffer-controller.ts:1513 [log] > [buffer-controller]: Media source opened
buffer-controller.ts:1342 [log] > [buffer-controller]: checkPendingTracks (pending: 0 codec events expected: 0) {}
level-controller.ts:370 [log] > [level-controller]: manifest loaded, 1 level(s) found, first bitrate: 3192000
abr-controller.ts:62 [log] > [abr]: setting initial bwe to 3192000
buffer-controller.ts:266 [log] > [buffer-controller]: 1 bufferCodec event(s) expected.
playlist-loader.ts:405 [log] > auto startLoad with configured startPosition -1
hls.ts:556 [log] > startLoad(-1)
level-controller.ts:468 [log] > [level-controller]: Switching to level 0 (720p SDR avc1,mp4a @3192000) from level -1
level-controller.ts:673 [log] > [level-controller]: Loading level index 0 https://mydomain.com/test/720p/chunklist.m3u8
base-stream-controller.ts:2106 [log] > [stream-controller]: STOPPED->IDLE
base-stream-controller.ts:2106 [log] > [subtitle-stream-controller]: STOPPED->IDLE
10Unchecked runtime.lastError: The message port closed before a response was received.
content.js:9 Current exchange rate: 1379.01
base-playlist-controller.ts:216 [log] > [level-controller]: live playlist 0 REFRESHED 594-1
level-controller.ts:673 [log] > [level-controller]: Loading level index 0 at sn 594 part 2 https://mydomain.com/test/720p/chunklist.m3u8?_HLS_msn=594&_HLS_part=2&_HLS_skip=YES
base-stream-controller.ts:2106 [log] > [stream-controller]: IDLE->WAITING_LEVEL
stream-controller.ts:671 [log] > [stream-controller]: Level 0 loaded [0,593][part-594-1], cc [0, 5] duration:1481.4523330000002
base-stream-controller.ts:1678 [log] > [stream-controller]: Live playlist sliding: 0.00 start-sn: na->0 fragments: 594
base-stream-controller.ts:1733 [log] > [stream-controller]: Setting startPosition to -1 to start at live edge 1478.330333
interstitials-controller.ts:1058 [log] > [interstitials]: setSchedulePosition 0, undefined
interstitials-controller.ts:1883 [log] > [interstitials]: buffered to boundary [primary: 0.00-Infinity]
interstitials-controller.ts:1296 [log] > [interstitials]: resuming [primary: 0.00-Infinity]
buffer-controller.ts:1319 [log] > [buffer-controller]: Updating MediaSource duration to 1481.452
base-stream-controller.ts:2106 [log] > [stream-controller]: WAITING_LEVEL->IDLE
base-stream-controller.ts:1298 [log] > [stream-controller]: LL-Part loading ON for initial live fragment
base-stream-controller.ts:1309 [log] > [stream-controller]: Setting startPosition to 1478.330333 to match start frag at live edge. mainStart: 1478.330333 liveSyncPosition: 1478.3373330000002 frag.start: 1476.9523330000002
base-stream-controller.ts:912 [log] > [stream-controller]: Loading main sn: initSegment of level 0 (frag:[251.619-251.619]) cc: 5 [0-593], target: 251.619
base-stream-controller.ts:2106 [log] > [stream-controller]: IDLE->FRAG_LOADING
timeline-chart.ts:754 Canvas2D: Multiple readback operations using getImageData are faster with the willReadFrequently attribute set to true. See: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently
drawLineX @ timeline-chart.ts:754
drawCurrentTime @ timeline-chart.ts:728
afterRender @ timeline-chart.ts:73
notify @ Chart.js:8032
onComplete @ Chart.js:9785
render @ Chart.js:9811
update @ Chart.js:9681
update @ timeline-chart.ts:252
(anonymous) @ timeline-chart.ts:263
requestAnimationFrame
updateOnRepaint @ timeline-chart.ts:263
updateLevelOrTrack @ timeline-chart.ts:464
(anonymous) @ main.js:1682
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
onLevelLoaded @ stream-controller.ts:711
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
handlePlaylistLoaded @ playlist-loader.ts:747
handleTrackOrLevelPlaylist @ playlist-loader.ts:563
onSuccess @ playlist-loader.ts:360
readystatechange @ xhr-loader.ts:232
XMLHttpRequest.send
openAndSendXhr @ xhr-loader.ts:166
loadInternal @ xhr-loader.ts:125
load @ xhr-loader.ts:83
load @ playlist-loader.ts:393
onLevelLoading @ playlist-loader.ts:171
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
loadingPlaylist @ level-controller.ts:681
scheduleLoading @ base-playlist-controller.ts:335
loadPlaylist @ level-controller.ts:659
set @ level-controller.ts:517
set @ level-controller.ts:700
set @ hls.ts:776
startLoad @ stream-controller.ts:161
startLoad @ hls.ts:565
checkAutostartLoad @ playlist-loader.ts:408
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
handleMasterPlaylist @ playlist-loader.ts:486
onSuccess @ playlist-loader.ts:368
readystatechange @ xhr-loader.ts:232
XMLHttpRequest.send
openAndSendXhr @ xhr-loader.ts:166
loadInternal @ xhr-loader.ts:125
load @ xhr-loader.ts:83
load @ playlist-loader.ts:393
onManifestLoading @ playlist-loader.ts:158
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
loadSource @ hls.ts:524
loadSelectedStream @ main.js:383
(anonymous) @ main.js:225
j @ jquery.min.js:2
fireWith @ jquery.min.js:2
ready @ jquery.min.js:2
I @ jquery.min.js:2
base-stream-controller.ts:2106 [log] > [stream-controller]: FRAG_LOADING->IDLE
base-stream-controller.ts:842 [log] > [stream-controller]: Loading main sn: 593 part: 0 (6/10) of level 0 (part:[1476.952-1477.952]INDEPENDENT=YES) cc: 5 [0-593], target: 1478.33
base-stream-controller.ts:2106 [log] > [stream-controller]: IDLE->FRAG_LOADING
[NEW] Explain Console errors by using Copilot in Edge: click
to explain an error.
Learn more
Don't show again
transmuxer-interface.ts:88 [log] > injecting Web Worker for "main"
transmuxer-interface.ts:238 [log] > [transmuxer-interface]: Starting new transmux session for main sn: 593 part: 0 level: 0 id: 1
discontinuity: true
trackSwitch: true
contiguous: false
accurateTimeOffset: false
timeOffset: 1476.9523330000002
initSegmentChange: true
d47bde4a-d81a-4259-9cf5-321a3992f85b:1168 [log] > Debug logs enabled for "main" in hls.js version 1.6.3-0.canary.11238
base-stream-controller.ts:2106 [log] > [stream-controller]: FRAG_LOADING->PARSING
stream-controller.ts:1505 [log] > [stream-controller]: Init audiovideo buffer, container:video/mp4, codecs[level/parsed]=[avc1.640028,mp4a.40.2/mp4a.40.2,avc1.640028]
buffer-controller.ts:590 [log] > [buffer-controller]: BUFFER_CODECS: "audiovideo" (current SB count 0)
buffer-controller.ts:1342 [log] > [buffer-controller]: checkPendingTracks (pending: 1 codec events expected: 1) {"audiovideo":{"listeners":[],"codec":"mp4a.40.2,avc1.640028","container":"video/mp4","id":"main"}}
buffer-controller.ts:1411 [log] > [buffer-controller]: creating sourceBuffer(video/mp4;codecs=mp4a.40.2,avc1.640028) {"listeners":[],"codec":"mp4a.40.2,avc1.640028","container":"video/mp4","id":"main"}
buffer-controller.ts:1380 [log] > [buffer-controller]: SourceBuffers created. Running queue:
video: (none)
audio: (none)
audiovideo: (SourceBuffer) }
audio-stream-controller.ts:153 [log] > [audio-stream-controller]: InitPTS for cc: 5 found from main: 2879.0159999877214/48000
transmuxer-interface.ts:396 [log] > [transmuxer.ts]: Flushed main sn: 593 part: 2 of level 0
base-stream-controller.ts:2106 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:2053 [log] > [stream-controller]: Parsed main sn: 593 part: 2 of level 0 (part:[1478.952-1479.452]INDEPENDENT=NO)
base-stream-controller.ts:721 [log] > [stream-controller]: Buffered main sn: 593 part: 2 of level 0 (part:[1478.952-1479.452]INDEPENDENT=NO > buffer:[1476.952-1479.448])
base-stream-controller.ts:2106 [log] > [stream-controller]: PARSED->IDLE
stream-controller.ts:1162 [log] > [stream-controller]: seek to target start position 1478.330333 from current time 0 buffer start 1476.952312
base-stream-controller.ts:842 [log] > [stream-controller]: Loading main sn: 594 part: 0 (9/10) of level 0 (part:[1479.452-1480.452]INDEPENDENT=YES) cc: 5 [0-593], target: 1479.452
base-stream-controller.ts:2106 [log] > [stream-controller]: IDLE->FRAG_LOADING
base-stream-controller.ts:348 [log] > [stream-controller]: media seeking to 1478.330, state: FRAG_LOADING
base-stream-controller.ts:348 [log] > [audio-stream-controller]: media seeking to 1478.330, state: STOPPED
base-stream-controller.ts:348 [log] > [subtitle-stream-controller]: media seeking to 1478.330, state: IDLE
stream-controller.ts:583 [log] > [stream-controller]: Media seeked to 1478.330
base-stream-controller.ts:2106 [log] > [stream-controller]: FRAG_LOADING->PARSING
transmuxer-interface.ts:396 [log] > [transmuxer.ts]: Flushed main sn: 594 part: 1 of level 0
base-stream-controller.ts:2106 [log] > [stream-controller]: PARSING->PARSED
base-stream-controller.ts:2053 [log] > [stream-controller]: Parsed main sn: 594 part: 1 of level 0 (part:[1480.452-1481.452]INDEPENDENT=NO)
base-stream-controller.ts:721 [log] > [stream-controller]: Buffered main sn: 594 part: 1 of level 0 (part:[1480.452-1481.452]INDEPENDENT=NO > buffer:[1476.952-1481.475])
base-stream-controller.ts:2106 [log] > [stream-controller]: PARSED->IDLE
level-helper.ts:178 Uncaught TypeError: Cannot read properties of null (reading 'cc')
at level-helper.ts:178:27
at mapFragmentIntersection (level-helper.ts:414:7)
at mergeDetails (level-helper.ts:167:3)
at LevelController.playlistLoaded (base-playlist-controller.ts:177:9)
at LevelController.onLevelLoaded (level-controller.ts:649:12)
at EventEmitter.emit (index.js:203:33)
at Hls.emit (hls.ts:386:26)
at Hls.trigger (hls.ts:394:19)
at PlaylistLoader.handlePlaylistLoaded (playlist-loader.ts:747:13)
at PlaylistLoader.handleTrackOrLevelPlaylist (playlist-loader.ts:563:10)
(anonymous) @ level-helper.ts:178
mapFragmentIntersection @ level-helper.ts:414
mergeDetails @ level-helper.ts:167
playlistLoaded @ base-playlist-controller.ts:177
onLevelLoaded @ level-controller.ts:649
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
handlePlaylistLoaded @ playlist-loader.ts:747
handleTrackOrLevelPlaylist @ playlist-loader.ts:563
onSuccess @ playlist-loader.ts:360
readystatechange @ xhr-loader.ts:232
XMLHttpRequest.send
openAndSendXhr @ xhr-loader.ts:166
loadInternal @ xhr-loader.ts:125
load @ xhr-loader.ts:83
load @ playlist-loader.ts:393
onLevelLoading @ playlist-loader.ts:171
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
loadingPlaylist @ level-controller.ts:681
playlistLoaded @ base-playlist-controller.ts:306
onLevelLoaded @ level-controller.ts:649
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
handlePlaylistLoaded @ playlist-loader.ts:747
handleTrackOrLevelPlaylist @ playlist-loader.ts:563
onSuccess @ playlist-loader.ts:360
readystatechange @ xhr-loader.ts:232
XMLHttpRequest.send
openAndSendXhr @ xhr-loader.ts:166
loadInternal @ xhr-loader.ts:125
load @ xhr-loader.ts:83
load @ playlist-loader.ts:393
onLevelLoading @ playlist-loader.ts:171
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
loadingPlaylist @ level-controller.ts:681
scheduleLoading @ base-playlist-controller.ts:335
loadPlaylist @ level-controller.ts:659
set @ level-controller.ts:517
set @ level-controller.ts:700
set @ hls.ts:776
startLoad @ stream-controller.ts:161
startLoad @ hls.ts:565
checkAutostartLoad @ playlist-loader.ts:408
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
handleMasterPlaylist @ playlist-loader.ts:486
onSuccess @ playlist-loader.ts:368
readystatechange @ xhr-loader.ts:232
XMLHttpRequest.send
openAndSendXhr @ xhr-loader.ts:166
loadInternal @ xhr-loader.ts:125
load @ xhr-loader.ts:83
load @ playlist-loader.ts:393
onManifestLoading @ playlist-loader.ts:158
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
loadSource @ hls.ts:524
loadSelectedStream @ main.js:383
(anonymous) @ main.js:225
j @ jquery.min.js:2
fireWith @ jquery.min.js:2
ready @ jquery.min.js:2
I @ jquery.min.js:2
gap-controller.ts:514 [warn] > [gap-controller]: Playback stalling at @1481.406521 due to low buffer ({"len":0.068456999999853,"start":1476.952312,"end":1481.474978,"buffered":[{"start":1476.952312,"end":1481.474978}],"bufferedIndex":0})
_reportStall @ gap-controller.ts:514
poll @ gap-controller.ts:316
tick @ gap-controller.ts:146
setInterval
setInterval @ task-loop.ts:71
onMediaAttached @ gap-controller.ts:83
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
BufferController._this2._onMediaSourceOpen @ buffer-controller.ts:1522
latency-controller.ts:205 [warn] > [latency-controller]: Stall detected, adjusting target latency
onError @ latency-controller.ts:205
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
_reportStall @ gap-controller.ts:515
poll @ gap-controller.ts:316
tick @ gap-controller.ts:146
setInterval
setInterval @ task-loop.ts:71
onMediaAttached @ gap-controller.ts:83
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
BufferController._this2._onMediaSourceOpen @ buffer-controller.ts:1522
main.js:745 Error event: {type: 'mediaError', details: 'bufferStalledError', fatal: false, error: Error: Playback stalling at @1481.406521 due to low buffer ({"len":0.068456999999853,"start":1476.9…, buffer: 0.068456999999853, …}
(anonymous) @ main.js:745
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
_reportStall @ gap-controller.ts:515
poll @ gap-controller.ts:316
tick @ gap-controller.ts:146
setInterval
setInterval @ task-loop.ts:71
onMediaAttached @ gap-controller.ts:83
emit @ index.js:203
emit @ hls.ts:386
trigger @ hls.ts:394
BufferController._this2._onMediaSourceOpen @ buffer-controller.ts:1522
Chrome media internals output
jeongki-kim
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
To do
Status
Top priorities