-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
What version of Hls.js are you using?
1.6.13
What browser (including version) are you using?
Chrome 142.0.7444.162 (arm64)
What OS (including version) are you using?
Mac 26.0.1 Tahoe
Test stream
I have sent it via DM.
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
- Plays an LL-HLS subtitle stream with parts.
Expected behaviour
Fragment state management prevents loading remaining parts of an incomplete segment.
The subtitle-stream-controller's loadFragment method blocks part loading once a fragment state becomes OK
protected loadFragment(frag: Fragment, level: Level, targetBufferTime: number) {
const fragState = this.fragmentTracker.getState(frag);
if (
fragState === FragmentState.NOT_LOADED ||
fragState === FragmentState.PARTIAL
) {
if (!isMediaFragment(frag)) {
this._loadInitSegment(frag, level);
} else {
super.loadFragment(frag, level, targetBufferTime);
}
}
// ❌ If fragState === OK, nothing happens!
}What actually happened?
The doTick method in subtitle-stream-controller doesn't advance to the next incomplete segment.
14:29:16.166 @@ doTick: currentTime=50.044, targetBufferTime=54.001, bufferLen=3.957
14:29:16.166 @@ getNextFragment: loadingParts=true, using end=54.001
14:29:16.166 @@ doTick: selected frag sn=68476, start=50.001, end=54.001
❌ Keeps selecting sn=68476 even though it has fragState=OK
Expected behavior: Should select fragment with higher sn or later parts
Actual behavior: Repeatedly selects same fragment that's already partially loaded
Additional Evidence
Part index calculation shows misalignment:
14:29:15.972 [warn] Need buffer at 50.000666 but next unloaded part starts at 40.30066600000001
14:29:15.973 [warn] Need buffer at 50.000666 but next unloaded part starts at 45.633999
14:29:15.973 @@ loadFragment: partIndex=36 for targetBufferTime=50.001
The getNextPart function struggles to find the correct part initially, suggesting the part
selection logic has issues with incomplete segments.
The revision direction I have in mind.
- Allow re-entering fragments with fragState=OK when loading parts?
- Modify getNextFragment to skip incomplete segments and move to the next one?
- Update fragmentTracker to use PARTIAL state for fragments with incomplete parts?
The main video works because it has different buffer management logic, but subtitles get stuck due
to this state check.
Console output
Initial successful part loading (parts 0-3):
14:29:15.972 @@ [subtitle-stream-controller] loadFragment: sn=68476, fragState=NOT_LOADED,
isMediaFragment=true
14:29:15.972 @@ [subtitle-stream-controller] loadFragment: calling super.loadFragment for sn=68476
14:29:15.972 @@ shouldLoadParts: ✅ ENABLING part loading
14:29:15.973 @@ loadFragment: partIndex=36 for targetBufferTime=50.001
14:29:15.973 [log] Loading subtitle sn: 68476 part: 0 (36/39) of track 0 (part:[50.001-51.001])
14:29:16.166 [log] Buffered subtitle sn: 68476 part: 3 of track 0 (part:[53.001-54.001] >
buffer:[50.001-54.001])
Subsequent failures (parts 4+ never load):
14:29:16.166 @@ [subtitle-stream-controller] doTick: selected frag sn=68476, start=50.001,
end=54.001
14:29:16.166 @@ [subtitle-stream-controller] loadFragment: sn=68476, fragState=OK,
isMediaFragment=true
❌ loadFragment returns early - super.loadFragment never called!
14:29:16.472 @@ [subtitle-stream-controller] doTick: selected frag sn=68476, start=50.001,
end=54.001
14:29:16.472 @@ [subtitle-stream-controller] loadFragment: sn=68476, fragState=OK,
isMediaFragment=true
❌ Same fragment selected, but fragState=OK blocks loading
14:29:16.817 @@ [subtitle-stream-controller] doTick: partList=41 parts, loadingParts=true
14:29:16.817 @@ [subtitle-stream-controller] doTick: selected frag sn=68476, start=50.001,
end=55.001
14:29:16.817 @@ [subtitle-stream-controller] loadFragment: sn=68476, fragState=OK,
isMediaFragment=true
❌ Playlist updated (40→41 parts), still stuck on same fragment
(repeats indefinitely with 42, 43 parts...)
Why Main Video Works But Subtitles Don't
Main video advances correctly:
14:29:16.803 @@ loadFragment: partIndex=40 for targetBufferTime=53.994
14:29:16.803 [log] Loading main sn: 68475 part: 4 (40/40)
14:29:16.861 [log] Buffered main sn: 68475 part: 4 (buffer:[41.708-54.996])
14:29:17.789 @@ loadFragment: partIndex=41 for targetBufferTime=54.996
14:29:17.789 [log] Loading main sn: 68475 part: 5 (41/41)
14:29:17.850 [log] Buffered main sn: 68475 part: 5 (buffer:[41.708-55.999])
Key differences:
- Main: targetBufferTime continuously advances (53.994 → 54.996 → 55.999)
- Main: Finds new parts and keeps loading
- Subtitles: targetBufferTime stuck at 54.001
- Subtitles: Same fragment selected repeatedly