-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Labels
BugConfirmedBug report confirmed or reproduced.Bug report confirmed or reproduced.LiveLow-LatencyStream Issue
Milestone
Description
What version of Hls.js are you using?
v1.6.6
What browser (including version) are you using?
Chrome 138.0.7204.158
What OS (including version) are you using?
Mac 15.1 24B2083
Test stream
I would like to forward the stream via email. Where would you like me to send it?
Configuration
{
"autoStartLoad": true,
"startPosition": -1,
"debug": true,
"capLevelOnFPSDrop": false,
"capLevelToPlayerSize": false,
"ignoreDevicePixelRatio": false,
"maxDevicePixelRatio": null,
"preferManagedMediaSource": true,
"initialLiveManifestSize": 1,
"maxBufferLength": 30,
"backBufferLength": 90,
"frontBufferFlushThreshold": null,
"startOnSegmentBoundary": false,
"maxBufferSize": 60000000,
"maxFragLookUpTolerance": 0.25,
"maxBufferHole": 1,
"detectStallWithCurrentTimeMs": 1250,
"highBufferWatchdogPeriod": 5,
"nudgeOffset": 0.1,
"nudgeMaxRetry": 3,
"nudgeOnVideoHole": true,
"liveSyncMode": "edge",
"liveSyncDurationCount": 3,
"liveSyncOnStallIncrease": 1,
"liveMaxLatencyDurationCount": null,
"maxLiveSyncPlaybackRate": 1,
"liveDurationInfinity": true,
"liveBackBufferLength": null,
"maxMaxBufferLength": 60,
"enableWorker": false,
"workerPath": null,
"enableSoftwareAES": true,
"startFragPrefetch": true,
"fpsDroppedMonitoringPeriod": 5000,
"fpsDroppedMonitoringThreshold": 0.2,
"appendErrorMaxRetry": 3,
"ignorePlaylistParsingErrors": false,
"stretchShortVideoTrack": false,
"maxAudioFramesDrift": 1,
"forceKeyFrameOnDiscontinuity": true,
"abrEwmaFastLive": 3,
"abrEwmaSlowLive": 9,
"abrEwmaFastVoD": 3,
"abrEwmaSlowVoD": 9,
"abrEwmaDefaultEstimate": 3192000,
"abrEwmaDefaultEstimateMax": 5000000,
"abrBandWidthFactor": 0.95,
"abrBandWidthUpFactor": 0.7,
"abrMaxWithRealBitrate": false,
"maxStarvationDelay": 4,
"maxLoadingDelay": 4,
"minAutoBitrate": 0,
"emeEnabled": false,
"drmSystems": {},
"drmSystemOptions": {},
"requireKeySystemAccessOnStart": false,
"testBandwidth": true,
"progressive": false,
"lowLatencyMode": true,
"enableDateRangeMetadataCues": true,
"enableEmsgMetadataCues": true,
"enableEmsgKLVMetadata": false,
"enableID3MetadataCues": true,
"enableInterstitialPlayback": true,
"interstitialAppendInPlace": true,
"interstitialLiveLookAhead": 10,
"useMediaCapabilities": true,
"preserveManualLevelOnError": false,
"certLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": 8000,
"maxLoadTimeMs": 20000,
"timeoutRetry": null,
"errorRetry": null
}
},
"keyLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": 8000,
"maxLoadTimeMs": 20000,
"timeoutRetry": {
"maxNumRetry": 1,
"retryDelayMs": 1000,
"maxRetryDelayMs": 20000,
"backoff": "linear"
},
"errorRetry": {
"maxNumRetry": 8,
"retryDelayMs": 1000,
"maxRetryDelayMs": 20000,
"backoff": "linear"
}
}
},
"manifestLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": null,
"maxLoadTimeMs": 20000,
"timeoutRetry": {
"maxNumRetry": 3,
"retryDelayMs": 0,
"maxRetryDelayMs": 0
},
"errorRetry": {
"maxNumRetry": 3,
"retryDelayMs": 1000,
"maxRetryDelayMs": 8000
}
}
},
"playlistLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": 10000,
"maxLoadTimeMs": 20000,
"timeoutRetry": {
"maxNumRetry": 0,
"retryDelayMs": 0,
"maxRetryDelayMs": 0
},
"errorRetry": {
"maxNumRetry": 0,
"retryDelayMs": 1000,
"maxRetryDelayMs": 8000
}
}
},
"fragLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": 10000,
"maxLoadTimeMs": 120000,
"timeoutRetry": {
"maxNumRetry": 3,
"retryDelayMs": 0,
"maxRetryDelayMs": 0
},
"errorRetry": {
"maxNumRetry": 3,
"retryDelayMs": 1000,
"maxRetryDelayMs": 8000
}
}
},
"steeringManifestLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": 10000,
"maxLoadTimeMs": 20000,
"timeoutRetry": {
"maxNumRetry": 2,
"retryDelayMs": 0,
"maxRetryDelayMs": 0
},
"errorRetry": {
"maxNumRetry": 1,
"retryDelayMs": 1000,
"maxRetryDelayMs": 8000
}
}
},
"interstitialAssetListLoadPolicy": {
"default": {
"maxTimeToFirstByteMs": 10000,
"maxLoadTimeMs": 30000,
"timeoutRetry": {
"maxNumRetry": 0,
"retryDelayMs": 0,
"maxRetryDelayMs": 0
},
"errorRetry": {
"maxNumRetry": 0,
"retryDelayMs": 1000,
"maxRetryDelayMs": 8000
}
}
},
"manifestLoadingTimeOut": 10000,
"manifestLoadingMaxRetry": 3,
"manifestLoadingRetryDelay": 1000,
"manifestLoadingMaxRetryTimeout": 64000,
"levelLoadingTimeOut": 10000,
"levelLoadingMaxRetry": 5,
"levelLoadingRetryDelay": 1000,
"levelLoadingMaxRetryTimeout": 10000,
"fragLoadingTimeOut": 20000,
"fragLoadingMaxRetry": 5,
"fragLoadingRetryDelay": 1000,
"fragLoadingMaxRetryTimeout": 64000,
"cueHandler": {},
"enableWebVTT": true,
"enableIMSC1": true,
"enableCEA708Captions": true,
"captionsTextTrack1Label": "English",
"captionsTextTrack1LanguageCode": "en",
"captionsTextTrack2Label": "Spanish",
"captionsTextTrack2LanguageCode": "es",
"captionsTextTrack3Label": "Unknown CC",
"captionsTextTrack3LanguageCode": "",
"captionsTextTrack4Label": "Unknown CC",
"captionsTextTrack4LanguageCode": "",
"renderTextTracksNatively": true,
"toggleTextTrackModeNatively": false
}
Additional player setup steps
- Using hls.js v1.6.6 with LL-HLS live stream
- Stream contains Part lists with INDEPENDENT=YES/NO segments
- Player is set to live edge with low latency mode enabled
- No custom fragment or playlist loaders configured
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
- Load an LL-HLS live stream with Part segments
- Let the player buffer and start playback at live edge
- Observe logs during normal playback (no seeking or user interaction)
- Notice frequent "LL-Part loading ON/OFF" messages in console
- Experience video stuttering/freezing during these transitions
Expected behaviour
- LL-Part loading should remain stable during continuous live playback
- Buffer should maintain continuity without frequent transmuxer session restarts
- Playback should be smooth without stuttering, similar to hls.js v1.4.10
- Buffer gaps should be handled gracefully without unnecessary seeking
What actually happened?
- Frequent LL-Part loading ON/OFF switching every 1-2 seconds
- Transmuxer sessions restart with contiguous: false during part-to-segment transitions
- Buffer discontinuities cause playback stuttering and brief freezes
- Gap controller triggers unnecessary seeking due to small buffer gaps
- Same stream plays smoothly in hls.js v1.4.10 (important)
Console output
[stream-controller]: LL-Part loading OFF after next part miss @3615.53
[stream-controller]: Loading main sn: 323232 of level 4 (frag:[3614.000-3616.000]) cc: 0
[transmuxer-interface]: Starting new transmux session for main sn: 323232 level: 4 id: 1
discontinuity: false
trackSwitch: false
contiguous: false
accurateTimeOffset: true
timeOffset: 3614.0000208333367
initSegmentChange: false
[buffer-controller]: Updating audiovideo SourceBuffer timestampOffset to -642851.9822916667 (sn:
323232 cc: 0)
[stream-controller]: LL-Part loading ON after parsing segment ending @3616.00
[stream-controller]: Loading main sn: 323233 part: 0 (6/6) of level 4
(part:[3615.989-3616.989]INDEPENDENT=YES)
[buffer-controller]: Updating audiovideo SourceBuffer timestampOffset to -642851.9983125 (sn:
323233 cc: 0)
[stream-controller]: LL-Part loading OFF after next part miss @3617.43
[transmuxer-interface]: Starting new transmux session for main sn: 323233 level: 4 id: 1
discontinuity: false
trackSwitch: false
contiguous: false
accurateTimeOffset: true
Key Issues Identified:
1. Frequent LL-Part switching: ON/OFF every 1-2 seconds causing loading method changes
2. Transmuxer session restarts: contiguous: false breaks buffer continuity
3. TimestampOffset fluctuations: Slight variations in same segments cause alignment issues
4. Buffer gap sensitivity: Small gaps (~1s) trigger unnecessary gap controller intervention
Chrome media internals output
{
"properties": {
"render_id": 16657,
"player_id": 4,
"created": "2025-07-28 12:27:07.629194 UTC",
"origin_url": "http://localhost:8080/",
"kFrameUrl": "http://localhost:8080/",
"kFrameTitle": "test",
"url": "blob:http://localhost:8080/aae24e95-8efc-4a98-a8a6-303877924c9a",
"info": "Selected VideoToolboxVideoDecoder for video decoding, config: codec: h264, profile: h264 main, level: not available, alpha_mode: is_opaque, coded size: [1920,1080], visible rect: [0,0,1920,1080], natural size: [1920,1080], has extra data: false, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}",
"kRendererName": "RendererImpl",
"pipeline_state": "kStopped",
"kVideoTracks": [
{
"alpha mode": "is_opaque",
"codec": "h264",
"coded size": "1280x720",
"color space": {
"matrix": "BT709",
"primaries": "BT709",
"range": "LIMITED",
"transfer": "BT709"
},
"encryption scheme": "Unencrypted",
"has extra data": false,
"hdr metadata": "unset",
"natural size": "1280x720",
"orientation": "0°",
"profile": "h264 high",
"visible rect": "0,0 1280x720"
}
],
"kAudioTracks": [
{
"bytes per channel": 2,
"bytes per frame": 4,
"channel layout": "STEREO",
"channels": 2,
"codec": "aac",
"codec delay": 0,
"discard decoder delay": false,
"encryption scheme": "Unencrypted",
"has extra data": true,
"profile": "unknown",
"sample format": "Signed 16-bit",
"samples per second": 48000,
"seek preroll": "0us"
}
],
"kIsAudioDecryptingDemuxerStream": false,
"kAudioDecoderName": "FFmpegAudioDecoder",
"kIsPlatformAudioDecoder": false,
"debug": "Skipping audio splice trimming at PTS=3605982312us. Found only 21us of overlap, need at least 1000us. Multiple occurrences may result in loss of A/V sync.",
"seek_target": 3594.005399,
"kIsVideoDecryptingDemuxerStream": false,
"kVideoDecoderName": "VideoToolboxVideoDecoder",
"kIsPlatformVideoDecoder": true,
"dimensions": "1920x1080",
"kResolution": "1920x1080",
"duration": "unknown",
"pipeline_buffering_state": {
"for_suspended_start": false,
"state": "BUFFERING_HAVE_ENOUGH"
},
"event": "kWebMediaPlayerDestroyed"
},
"events": [
{
"time": 0,
"key": "created",
"value": "2025-07-28 12:27:07.629194 UTC"
},
{
"time": 0.06999999284744263,
"key": "origin_url",
"value": "http://localhost:8080/"
},
{
"time": 0.07200002670288086,
"key": "kFrameUrl",
"value": "http://localhost:8080/"
},
{
"time": 0.07300001382827759,
"key": "kFrameTitle",
"value": "test"
},
{
"time": 0.1040000319480896,
"key": "url",
"value": "blob:http://localhost:8080/aae24e95-8efc-4a98-a8a6-303877924c9a"
},
{
"time": 0.11500000953674316,
"key": "info",
"value": "ChunkDemuxer"
},
{
"time": 0.12000000476837158,
"key": "kRendererName",
"value": "RendererImpl"
},
{
"time": 0.13099998235702515,
"key": "pipeline_state",
"value": "kStarting"
},
{
"time": 193.64600002765656,
"key": "kVideoTracks",
"value": [
{
"alpha mode": "is_opaque",
"codec": "h264",
"coded size": "1280x720",
"color space": {
"matrix": "BT709",
"primaries": "BT709",
"range": "LIMITED",
"transfer": "BT709"
},
"encryption scheme": "Unencrypted",
"has extra data": false,
"hdr metadata": "unset",
"natural size": "1280x720",
"orientation": "0°",
"profile": "h264 high",
"visible rect": "0,0 1280x720"
}
]
},
{
"time": 193.66000002622604,
"key": "kAudioTracks",
"value": [
{
"bytes per channel": 2,
"bytes per frame": 4,
"channel layout": "STEREO",
"channels": 2,
"codec": "aac",
"codec delay": 0,
"discard decoder delay": false,
"encryption scheme": "Unencrypted",
"has extra data": true,
"profile": "unknown",
"sample format": "Signed 16-bit",
"samples per second": 48000,
"seek preroll": "0us"
}
]
},
{
"time": 195.78799998760223,
"key": "kIsAudioDecryptingDemuxerStream",
"value": false
},
{
"time": 195.78900003433228,
"key": "kAudioDecoderName",
"value": "FFmpegAudioDecoder"
},
{
"time": 195.79000002145767,
"key": "kIsPlatformAudioDecoder",
"value": false
},
{
"time": 195.7940000295639,
"key": "info",
"value": "Selected FFmpegAudioDecoder for audio decoding, config: codec: aac, profile: unknown, bytes_per_channel: 2, channel_layout: STEREO, channels: 2, samples_per_second: 48000, sample_format: Signed 16-bit, bytes_per_frame: 4, seek_preroll: 0us, codec_delay: 0, has extra data: true, encryption scheme: Unencrypted, discard decoder delay: false, target_output_channel_layout: STEREO, target_output_sample_format: Unknown sample format"
},
{
"time": 195.79900002479553,
"key": "debug",
"value": "Video rendering in low delay mode."
},
{
"time": 195.80699998140335,
"key": "info",
"value": "Cannot select DecryptingVideoDecoder for video decoding"
},
{
"time": 195.89700001478195,
"key": "seek_target",
"value": 3594.005399
},
{
"time": 197.32300001382828,
"key": "kIsVideoDecryptingDemuxerStream",
"value": false
},
{
"time": 197.32400000095367,
"key": "kVideoDecoderName",
"value": "VideoToolboxVideoDecoder"
},
{
"time": 197.32400000095367,
"key": "kIsPlatformVideoDecoder",
"value": true
},
{
"time": 197.3289999961853,
"key": "info",
"value": "Selected VideoToolboxVideoDecoder for video decoding, config: codec: h264, profile: h264 high, level: not available, alpha_mode: is_opaque, coded size: [1280,720], visible rect: [0,0,1280,720], natural size: [1280,720], has extra data: false, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}"
},
{
"time": 197.33700001239777,
"key": "pipeline_state",
"value": "kPlaying"
},
{
"time": 197.54900002479553,
"key": "pipeline_state",
"value": "kSeeking"
},
{
"time": 197.60900002717972,
"key": "pipeline_state",
"value": "kPlaying"
},
{
"time": 204.52799999713898,
"key": "dimensions",
"value": "1280x720"
},
{
"time": 204.53000003099442,
"key": "kResolution",
"value": "1280x720"
},
{
"time": 208.74300003051758,
"key": "info",
"value": "Effective playback rate changed from 0 to 1"
},
{
"time": 326.994000017643,
"key": "debug",
"value": "Audio buffer splice at PTS=3596000000us. Trimmed tail of overlapped buffer (PTS=3595984000us) by 5333us."
},
{
"time": 659.4670000076294,
"key": "debug",
"value": "Audio buffer splice at PTS=3597982312us. Trimmed tail of overlapped buffer (PTS=3597962667us) by 1688us."
},
{
"time": 251.5799999833107,
"key": "duration",
"value": "unknown"
},
{
"time": 204.5590000152588,
"key": "pipeline_buffering_state",
"value": {
"for_suspended_start": false,
"state": "BUFFERING_HAVE_ENOUGH"
}
},
{
"time": 208.76600003242493,
"key": "event",
"value": "kPlay"
},
{
"time": 207.91799998283386,
"key": "event",
"value": "kPause"
},
{
"time": 2106.4200000166893,
"key": "info",
"value": "video decoder config changed midstream, new config: codec: h264, profile: h264 main, level: not available, alpha_mode: is_opaque, coded size: [852,480], visible rect: [0,0,852,480], natural size: [853,480], has extra data: false, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}"
},
{
"time": 2106.6349999904633,
"key": "kIsVideoDecryptingDemuxerStream",
"value": false
},
{
"time": 2106.651000022888,
"key": "kVideoDecoderName",
"value": "VideoToolboxVideoDecoder"
},
{
"time": 2106.6520000100136,
"key": "kIsPlatformVideoDecoder",
"value": true
},
{
"time": 2106.6590000391006,
"key": "info",
"value": "Selected VideoToolboxVideoDecoder for video decoding, config: codec: h264, profile: h264 main, level: not available, alpha_mode: is_opaque, coded size: [852,480], visible rect: [0,0,852,480], natural size: [853,480], has extra data: false, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}"
},
{
"time": 2277.570999979973,
"key": "dimensions",
"value": "853x480"
},
{
"time": 2277.5740000009537,
"key": "kResolution",
"value": "853x480"
},
{
"time": 3944.888000011444,
"key": "info",
"value": "video decoder config changed midstream, new config: codec: h264, profile: h264 main, level: not available, alpha_mode: is_opaque, coded size: [1920,1080], visible rect: [0,0,1920,1080], natural size: [1920,1080], has extra data: false, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}"
},
{
"time": 3945.1700000166893,
"key": "kIsVideoDecryptingDemuxerStream",
"value": false
},
{
"time": 3945.1710000038147,
"key": "kVideoDecoderName",
"value": "VideoToolboxVideoDecoder"
},
{
"time": 3945.1710000038147,
"key": "kIsPlatformVideoDecoder",
"value": true
},
{
"time": 3945.1759999990463,
"key": "info",
"value": "Selected VideoToolboxVideoDecoder for video decoding, config: codec: h264, profile: h264 main, level: not available, alpha_mode: is_opaque, coded size: [1920,1080], visible rect: [0,0,1920,1080], natural size: [1920,1080], has extra data: false, encryption scheme: Unencrypted, rotation: 0°, flipped: 0, color space: {primaries:BT709, transfer:BT709, matrix:BT709, range:LIMITED}"
},
{
"time": 4277.572000026703,
"key": "dimensions",
"value": "1920x1080"
},
{
"time": 4277.582000017166,
"key": "kResolution",
"value": "1920x1080"
},
{
"time": 4694.290000021458,
"key": "debug",
"value": "Skipping audio splice trimming at PTS=3603998312us. Found only 21us of overlap, need at least 1000us. Multiple occurrences may result in loss of A/V sync."
},
{
"time": 6683.586000025272,
"key": "debug",
"value": "Skipping audio splice trimming at PTS=3605982312us. Found only 21us of overlap, need at least 1000us. Multiple occurrences may result in loss of A/V sync."
},
{
"time": 10880.791000008583,
"key": "event",
"value": "kWebMediaPlayerDestroyed"
},
{
"time": 10880.791000008583,
"key": "pipeline_state",
"value": "kStopping"
},
{
"time": 10881.12300002575,
"key": "pipeline_state",
"value": "kStopped"
}
]
}
Metadata
Metadata
Assignees
Labels
BugConfirmedBug report confirmed or reproduced.Bug report confirmed or reproduced.LiveLow-LatencyStream Issue