v1.7.1
HLS.js v1.7.1 includes bug fixes and improvements over the previous release.
https://github.com/video-dev/hls.js/compare/v1.7.0...v1.7.1
- Fix Interstitial snap-out at live edge and
BUFFER_APPEND_NO_PROGRESSfalse positives (#7979) @robwalch - Workaround issue where
ManagedMediaSourcedoes not emit "startstreaming" when seeking (#7984) - Fix permanent stall loading fragment-hint parts of encrypted low-latency streams (#7976) @zaki699-blip
- Document decode timebase change in MIGRATING (#7986) @robwalch
https://26ea065a.hls-js-dev.pages.dev/demo/
No public exports were removed and no runtime behavior changes are required to upgrade from v1.6 to v1.7. TypeScript consumers might see new compile errors where previously loose types have been narrowed. Each is listed with upgrade guidance in the migration guide: https://github.com/video-dev/hls.js/blob/v1.7.0/MIGRATING.md#migrating-from-hlsjs-16-to-17
Some exported type dependencies ("eventemitter3", "@svta/cml-cmcd", "@svta/cml-utils", "@svta/cml-structured-field-values") have not been bundled with hls.d.ts. Please file an issue if this is blocking you from upgrading.
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.6.19
HLS.js v1.6.19 includes bug fixes and improvements over the last release.
https://github.com/video-dev/hls.js/compare/v1.6.18...v1.6.19
- Fix permanent stall in encrypted low-latency streams (#7976) @zaki699-blip
- Workaround for macOS and iOS 27 beta regression in ManagedMediaSource "startstreaming" (cherry-pick of #7984) @robwalch
https://392c003f.hls-js-dev.pages.dev/demo/
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.7.0
HLS.js v1.7.0 adds I-frame playlist support, improved playback of protected content, and CMCD v2 for standardized streaming analytics. It also delivers smoother audio-track switching, faster startup through parallel init-segment loading, and fixes across Low-Latency HLS, subtitles, interstitials, and live streaming.
Highlights to try in this release:
- I-frame playback — call
hls.createIFramePlayer()andloadMediaAt(time)to render frames from a stream's#EXT-X-I-FRAME-STREAM-INFvariants in a video element, or load an#EXT-X-I-FRAMES-ONLYmedia playlist directly. - Smoother audio switching — set
hls.nextAudioTrack(or pass{ flushImmediate: true }tosetAudioOptionfor an immediate one) to schedule a seamless audio-rendition change that avoids stalls and added live latency. - CMCD v2 — set
cmcd.version: 2to enable it, and configurecmcd.eventTargetsto send standardized event reports to an external analytics endpoint. Not all CMCD v2 events, fields, and HLS.js features are supported as of this release. - Faster startup — alternate audio and video init segments now load in parallel; try a stream with separate audio/video renditions.
- Improved support for looped video — a new
loopBackBufferFlushconfig option flushes the lower-quality back buffer on looped streams. - Tune level selection —
abrSwitchIntervalthrottles automatic quality switches, anderrorPenaltyExpireMslets a level penalized by a load error be re-elected instead of being avoided for the rest of the session. - Stop loading stale live streams — set
liveMaxUnchangedPlaylistRefreshto error out withPLAYLIST_UNCHANGED_ERRORafter a set number of unchanged playlist reloads instead of polling a dead playlist indefinitely. - Recover from broken appends — on live and VOD alike,
appendTimeoutbounds aSourceBufferappend that never completes, whileMEDIA_SOURCE_REQUIRES_RESETandBUFFER_APPEND_NO_PROGRESSreport a MediaSource that has to be reset and fragments that append without ever buffering.
https://073606d7.hls-js-dev.pages.dev/demo/
No public exports were removed and no runtime behavior changes are required to upgrade from v1.6 to v1.7. TypeScript consumers might see new compile errors where previously loose types have been narrowed. Each is listed with upgrade guidance in the migration guide: https://github.com/video-dev/hls.js/blob/v1.7.0/MIGRATING.md#migrating-from-hlsjs-16-to-17
Some exported type dependencies ("eventemitter3", "@svta/cml-cmcd", "@svta/cml-utils", "@svta/cml-structured-field-values") have not been bundled with hls.d.ts. This will be addressed in an upcoming patch.
https://github.com/video-dev/hls.js/compare/v1.6.18...v1.7.0, https://github.com/video-dev/hls.js/compare/v1.7.0-rc.3...v1.7.0
- HLS I-frame playlist support
#EXT-X-I-FRAME-STREAM-INFand#EXT-X-I-FRAMES-ONLY(#7757, #7791) @robwalch- Optimize I-frame parsing (#7794)
- "mjpg" image I-frame support (#7862)
- Parse I-frame multivariant tags that end at EOF without a trailing newline (#7851) @rudemateo
- Play single-keyframe fMP4 segments and parse
tfhddefault_sample_sizecorrectly (#7884) @rudemateo - Support remuxing of encrypted I-frame segments, including AES decryption of byte-range requests (#7896, #7892) @robwalch
- Force rendering of requested I-frames (#7934) @robwalch
- Fix I-frame trick-play rendering of stretched and backward-loaded frames (#7930) @rudemateo
- Support muxed audio+video fMP4 and multi-trun I-frame fragments (#7940) @rudemateo
- Consolidate the I-frame remux code into one function (#7945) @robwalch
- CMCD v2
- Upgrade Common Media Client Data reporting to the CMCD v2 specification (#7725) @littlespex
- Custom events, custom keys, and
ec(#7887) @cotid-qualabs - Implement rtp, lb, dl, pb, tpb, ttfb, and ttlb (#7895) @cotid-qualabs
- Smooth audio track switching
- Introduce
hls.nextAudioTrackAPI (#7575) @krseager - Optional
flushImmediateaudio switch option (#7795) @krseager
- Introduce
Nothing below is required to upgrade. Every addition is opt-in. Each entry links to its v1.7.0 API documentation.
abrSwitchInterval(0) minimum seconds between automatic ABR switchesappendTimeout(Infinity) milliseconds before anappendBuffer()operation is treated as timed outemsgKLVSchemaUri(undefined) URN matched when extracting MISB KLV metadata from CMAFemsgboxes, defaulting tourn:misb:KLV:bin:1910.1errorPenaltyExpireMs(0) milliseconds after which a level penalized for a load error can be re-electedhandleMpegTsVideoIntegrityErrors('process'or'skip') how corrupt MPEG-TS video is handlediframeCacheLimit(2 * 1024 * 1024) bytes of I-frame data retained by I-frame player instancesliveMaxUnchangedPlaylistRefresh(Infinity, minimum2) unchanged live reloads beforePLAYLIST_UNCHANGED_ERRORloopBackBufferFlush(undefined) flush the lower-quality back buffer on an upswitch whenmedia.loopistruenextAudioTrackBufferFlushForwardOffset(0.25) forward audio buffer retained on a scheduled audio switchskipBufferHolePadding(0.1) padding added to the buffer-hole skip targetloggerId(undefined) prefixes debug logs for anHlsinstance (assetPlayerIdstill fills in for it)cmcdsub-options for CMCD v2:version(1or2),eventTargets(v2 event report endpoints),rtpSafetyFactor(5),loader, andreporterCallback(receives aCmcdCustomReporterforupdateCustomData()andrecordCustomEvent()).includeKeysis retyped fromstring[]toCmcdKey[]- Controller overrides that can be replaced or disabled:
streamController,gapController,latencyController,id3TrackController, andiframeController
drmSystems[KEY-SYSTEM].generateRequestreceiveskeyContext & { decryptdata: LevelKey, reason: LicenseRequestReason }and returnsGenerateRequestFilterResultlicenseXhrSetupandlicenseResponseCallbackreceivekeyContext & { decryptdata: LevelKey }, andlicenseXhrSetupcan now return or resolve astringas well as aUint8Array
hls.createIFramePlayer(configOverride?)returnsHlsIFramesOnly | null, a player that renders#EXT-X-I-FRAME-STREAM-INFvariants in a video elementhls.createImageIFramePlayer(configOverride?)returnsHlsImageIFramesOnly | null, a player for"mjpg"image I-frame variantsiframePlayer.loadMediaAt(time, options?)loads, appends, and seeks to the I-frame attime(optionsisPartial<LoadMediaAtOptions>)imagePlayer.attachImage(image)andimagePlayer.detachImage()attach or detach theHTMLImageElementused for renderinghls.setAudioOption(option, flushImmediate?)takes an optional second argument to switch immediately rather than on schedule
hls.iframeVariantsgetLevelParsed[]of the multivariant playlist's I-frame variantshls.audioForwardBufferInfogetBufferInfo | nullfor the alternate audio bufferhls.nextAudioTrackget and set thenumberindex of the audio track scheduled for a seamless switch
This release adds three Hls.ErrorDetails members and no new Hls.Events members.
PLAYLIST_UNCHANGED_ERROR(NETWORK_ERROR, non-fatal) a live playlist hitliveMaxUnchangedPlaylistRefreshconsecutive unchanged reloadsBUFFER_APPEND_NO_PROGRESS(MEDIA_ERROR, non-fatal) an append cycle completed without increasing the fragment's buffered coverage, and addsappendsWithoutProgresstoErrorDataMEDIA_SOURCE_REQUIRES_RESET(MEDIA_ERROR) the MediaSource closed while attached or ended on an append error, withResetMediaSourceinerrorAction.flags
iframeVariantsadded toMANIFEST_LOADEDandMANIFEST_PARSEDchunkMeta: ChunkMetadataadded toFRAG_PARSEDandFRAG_BUFFEREDsubtitleTrackandclosedCaptionsadded toCUES_PARSEDflushImmediateadded toAudioSelectionOptionandAUDIO_TRACK_SWITCHINGpreviousFragadded toFRAG_CHANGED,parttoSUBTITLE_FRAG_PROCESSEDandFRAG_DECRYPTED,timestampOffsetstoINIT_PTS_FOUND,start,end, anderrortoBUFFER_FLUSHED, andcontexttoLEVEL_LOADED,AUDIO_TRACK_LOADED, andSUBTITLE_TRACK_LOADEDnetworkDetailson playlist, fragment, asset-list, and error events is narrowed fromanytoNullableNetworkDetailsFRAG_PARSING_USERDATAis only emitted when text samples are foundMEDIA_DETACHEDis now triggered synchronously bydetachMedia()andtransferMedia()hls.loadingEnabledisfalseonce the stream controller has stopped, not just afterstopLoad()
Content protection (DRM)
- DRM and multi-key handling improvements for improved protected playback (#7517) @robwalch
- Resolve usable keys from the latest key session before requesting another, and resolve
setMediaKeysonce attached (#7879, #7615) @robwalch - Parse the Widevine key id from the
EXT-X-KEYPSSH (andencryptedevent initData) when HLS playlistKEYIDattribute is absent (#7775, #7415) @robwalch @yajin2021 - Support playback of elementary (containerless) audio encrypted with Sample-AES (#7479) @Yesterday17
- Load the key for the fragment of a selected LL-HLS part so encrypted parts decrypt correctly (#7874) @robwalch
Audio switching, live, and buffering
- Smooth audio track switching (#7575, #7795) @krseager
- Download init segments in parallel for a faster start (#7867) @krseager
- Add
hls.audioForwardBufferInfogetter for audio-specific forward buffer info (#7865) @robwalch - Flush the back buffer for looped streams (#7869) @dzianis-dashkevich
- Improve audio/video append synchronization (#7842) @robwalch
- Avoid an audio buffer flush on the first track switch (#7696)
- Reach the "ended" state reliably when a playlist ends with empty or gap segments (#7609)
- Better playlist alignment when PDT is inconsistent across renditions (#7482)
Stability and error handling
- Add
abrSwitchIntervalto throttle automatic level switches (#7669) @christriants - Re-elect penalized levels once
errorPenaltyExpireMshas passed (#7771) @Harshit661000143 - Error and stop streaming after max unchanged live updates (#7704) @dzianis-dashkevich
- Keep
PLAYLIST_UNCHANGED_ERRORnon-fatal so playback can reach the end of the playlist (#7812) @robwalch
- Keep
- SourceBuffer append operation timeout handling (#7670) @dzianis-dashkevich
- Detect and recover from a MediaSource that reports "ended" or "closed" while still attached, which fixes ManagedMediaSource cold starts failing on iOS 26.2 (#7697) @zalishchuk
- Surface the condition as the
MEDIA_SOURCE_REQUIRES_RESETerror so applications can handle it before automatic recovery (#7699) @christriants - Respond with a variant switch, a switch to SDR, and a MediaSource reset error action, so content that causes append errors no longer loops through recovery (#7702) @robwalch
- Limit recovery attempts when a media element decode error, rather than an append error, closed the MediaSource (#7707) @robwalch
- Surface the condition as the
Timed metadata and track management
- Extract MISB KLV timed metadata from MPEG-TS and CMAF streams (#7668) @jacorbello, including when audio is present (#7673) @jacorbello
- Add
subtitleTrackandclosedCaptionsto theCUES_PARSEDevent (#7843) @robwalch - Only emit
FRAG_PARSING_USERDATAwhen text samples are found (#7686) @XephyrKenny - Allow removing text tracks that HLS.js created (#7515) @xxoo
- (Uses removable DOM
<track>elements overHTMLMediaElement.addTextTrack()which does not allow removal)
- (Uses removable DOM
Networking and resilience
- fetch-loader retry logic for transient network failures (#7756) @dzianis-dashkevich
- Pass the loader context to
xhrSetupand export loader context types (#7831 @robwalch, #7762 @dzianis-dashkevich) - Verify byte-range responses and warn on a size mismatch (#7701) @robwalch
- Detect corrupt MPEG-TS video streams (#7094) @mstyura
Performance, memory, and lifecycle
- Cap the selected level to the player size with
ResizeObserver, and makenextLevelSwitchmore responsive (#7108) @robwalch - Clear the resolved fragment/part URL cache when done to reduce memory use (#7731)
- More reliable transmuxer teardown on
destroy()(#7863) - Keep inherited logger methods intact on
destroy()(#7864) - Improve M2TS init-segment handling and append-queue logging (#7695)
- Remove dead code and some unused exports for a smaller bundle (#7882)
- Faster parsing on low-powered devices: CEA-608 captions, Annex-B marker scanning in the tsdemuxer, and mp4 box parsing (#7949, #7955, #7956) @itsjamie
Playback start, seeking, and timestamps
- Fix backward seeking that led to stalling or elevated buffering (#7577) @krseager
- Fix certain Tizen devices getting stuck seeking over buffer gaps (#7630) @krseager
- Fix an endless loop in the gap controller on bad streams (zero-duration segments) (#7661) @robwalch
- Restore playback after page restoration from bfcache in Safari (#7683) @christriants
- Restart loading from
recoverMediaError()whenautoStartLoadis disabled (#7693) @robwalch - Roll initPTS forward when needed by earlier segments (#7537) @robwalch
- Correct a
computeInitPtsrollover that caused a segment-0 loop (#7752) @christriants - Adjust initPTS when a level switch drops the opening GoP (#7700) @robwalch
- Do not update initPTS on small drift caused by playlist segment-duration rounding (#7792) @robwalch
Media parsing and codecs
- Work around Chrome silently evicting coded frames on PTS overlap (#7807) @robwalch
- Pad the initial PTS of remuxed MPEG-TS to avoid Chrome rendering glitches (#7805) @robwalch
- Drop bad MP4 data instead of failing the append (#7815) @robwalch
- HEVC: set sync samples from IRAP VCL NALs (#7861) @gemxx
- HEVC: correct access-unit sample boundaries in Safari (#7854) @gemxx
- Switch away from containerless EC-3 audio that HLS.js cannot demux (Safari) instead of stalling (#7873) @robwalch
- Handle implicit HE-AAC for AAC Main at low sample rates (#7835) @robwalch
- Fix unterminated emsg infinite loop and scheme parsing (#7968) @Jaybhade
Audio tracks
- Fix switching back to main (audio-only) after end-of-stream is buffered (#7645) @robwalch
- Fix AES-128 decryption failure on alternate audio when a shared key load is pending (#7834) @robwalch
- Fix audio TS segment duration calculation (#7646) @robwalch
- Stop
AUDIO_TRACK_LOAD_TIMEOUTfrom following theerrorRetrypolicy inplaylistLoadPolicy(#7506) @CongCong-1228
Content protection (DRM)
- Fix PlayReady on some devices (#7631) @KunXi-Fox
- Fix PlayReady key endianness (#7510) @ShubhamSharma2311
- Fix an eme-controller type error that depended on promise state (#7877) @bwallberg
- Fix
licenseXhrSetupreturn types and aselectKeySystemnested-Promise anti-pattern (#7888) @robwalch
Subtitles and captions
- Decrypt LL-HLS VTT AES parts per-part (#7881) @hongjun-bae
- Fix Low-Latency HLS VTT subtitle part loading, including segments where only the first parts were requested (#7626, #7893) @robwalch
- Align WebVTT segments missing an
X-TIMESTAMP-MAPheader with the media timeline (#7852) @robwalch - Fix WebVTT loading by disabling progressive loading for WebVTT (#7649) @krseager
- Cache initial cues added to a
TextTrackso the browser does not remove them (#7809) @robwalch - Fix CEA-608 cursor clamping so position stays within the column array bounds (#7666) @chelleccarlyle
Live, interstitials, and content steering
- Fix Low-Latency Live joins and resumption around interstitial prerolls and midrolls (#7846, #7908, #7913, #7935, #7944) @robwalch
_HLS_start_offsetmissing from asset-list requests on live join (#7846, #7944)- Live join with a
PRE,ONCEpreroll starting at the wrong position (#7908) - Preroll resume colliding with a midroll, and midroll buffering and playback (#7913)
- Fatal "init load aborted" when the init segment load context changes at preroll end (#7935)
- Fix interstitial live start with a short sliding window (#7799)
- Do not reset interstitials when seeking between assets (#7650)
- Fix an interstitial-controller exception on legacy engines where
media.play()returns no Promise (#7586) @malickyeu - Fix fallback to primary on live start (#7651) @robwalch
- Content Steering: apply
URI-REPLACEMENTHOSTto the hostname only (#7655) - Pathway Cloning: apply
PARAMSafterPER-VARIANT-URIS(#7710) - Fix "discontinuity sequence mismatch" for fragment hint with no parts (#7964)
- Preserve existing query string when adding HLS delivery directives (#7969) @CarlLindqvist
Live updates and playlist parsing
- Support an
EXT-X-DISCONTINUITY-SEQUENCEdeclaration after the first media segment (#7750) - Detect stream end after a live-to-VOD transition when
endListFragmentsis stale (#7754) @alchemyyy - Fix the initial reload time of a live playlist loaded with
hls.loadSource()(#7875) @robwalch - Defer playlist reload while the network is offline (#7926) @robwalch
- Fix
mapPartIntersectionloop bounds (#7859) @sugarzyc - Do not request a video buffer flush or EOS when the main playlist is audio-only (#7868)
- Fix "Missing format identifier #EXTM3U" playlist parsing errors (#7533)
- Multivariant playlist parsing fixes (#7523)
- Support
EXT-X-MEDIA-SEQUENCEdeclaration afterEXT-X-SKIP(#7905) @hongjun-bae
Buffering, memory, recovery, startup, and teardown
- Recover from
QuotaExceededErrorby evicting the back buffer and retrying (#7749) @alchemyyy - Limit buffering while paused outside the live sliding window (#7788) @robwalch
- Prevent loop-loading of segments whose appends were dropped (#7797)
- Forward transmuxer worker errors correctly (#7883)
- Make
part.gapwritable and handle part muxing errors as gaps (#7814) - Mark fragments as gaps after repeated appends without buffered range growth (#7941) @rudemateo
- Reported with the new
BUFFER_APPEND_NO_PROGRESSerror detail (see Error details above)
- Reported with the new
- Treat un-demuxable fragments as a gap to prevent infinite reloading (#7900) @hongjun-bae
- Fix selection with small samples (#7939) @robwalch
- Prevent loop loading for SourceBuffer mismatch append errors (#7965)
- Guard abandon-rules check after destroy (#7938) @AmPlace
Regressions in development and v1.7 beta
- Fix subtitle buffering up to or past media buffer (#7921) @robwalch
- Fix fatal KEY_SYSTEM_ERROR handling (#7920)
- Fix
autoStartLoad:falseand deferredstartPosition(#7903) - Fix uncaught init-segment abort errors (#7904)
- Fix key-status internal-error handling (#7963)
- Fix MPEG-TS Sample-AES decryption (#7959)
- Add minified ESM builds and a dist size budget check (#7970) @itsjamie
- Update minimum browser support documentation and build config (#7880) @robwalch
- Update Chrome configuration for macOS in build.yml (#7698)
- Increase minimum Windows test version for saucelabs (#7602)
- Use BrowserStack to run macOS CI tests (#7836)
- Update to TypeScript 5.9 (#7607)
- Type
networkDetailson playlist, fragment, and error events instead ofany(#7458) @ondreian - Migrate CI to Sauce Connect 5 (#7957) @itsjamie
- Add dev container support for contributors (#7758) @tjenkinson
- Use the GitHub
releaseenvironment for npm publish (#7544) @tjenkinson - Lint em-dash characters (#7899) @robwalch
- Correct interstitial env vars and content-steering condition (#7727) @zalishchuk
- Update README supported features (#7953) @robwalch
- Update README Alternative setup for 2026 browsers (#7844)
- Document testing with BrowserStack and SauceLabs (#7780)
- Add missing config options to API.md (#7628) @krseager
- Create SECURITY.md (#7685) @pr4v33n7-sa
- Fix links for API Docs in README (#7637) @daniemo2
- Add Labra-Flex to 'They use HLS.js in production!' section (#7419) @aaskaoui
- Add Streamfizz to "They use HLS.js in production!" (#7927) @geosigno
- Fix HLS.js product name in issue templates (#7828) @karlhorky
- Fix TypeError on playlist load/reload inside of 3rd party library Chart.js for demo page (#7801) @krseager
- Add an
hlsjsConfigquery param to populate the demo editor (#7473) @quentinms
Beyond the code contributors credited above, thank you to the community members whose issue reports drove fixes and improvements in this release:
- @AndreasFurster (#4553), @gdplayerto (#4958), @kiran-dcunha (#4954), @CaseV7 (#5392), @byumark (#6191), @iamsyk (#6374), @fresleo (#6666), @Hyddan (#6680), @vaseala (#6711), @ShoobyD (#6776), @luwes (#6777), @qiushaocloud (#7023), @LalitAgrawala004 (#7142, #7738), @jiho-bae (#7420), @Yeongjin-Jeong (#7460), @hongfeih-es (#7508), @gugaio (#7518), @SangwonOh (#7522, #7885, #7962), @Tzipi-kaltura (#7524), @twilson90 (#7531), @knuthaug (#7535), @bmarshall (#7536), @AfLosada (#7541), @dchan-harmonicinc (#7554), @xtne6f (#7556), @mtaher1996 (#7564), @MosheMaorKaltura (#7572), @janpe (#7578), @matvp91 (#7641), @martystefan (#7646), @bes (#7656), @doublex (#7667), @greeble31 (#7674), @thexeos (#7675, #7677), @gjanblaszczyk (#7687), @wei-li-dwango (#7808), @foliovision (#7833), @philhar88 (#7845, #7906, #7911, #7912, #7931, #7942), @robybales3 (#7850), @ai-bughunter (#7856), @mrlika (#7876), and @dloftus (#7898)
- @flagoworld, whose PR #7453 informed the live media playlist reload fix (#7875)
- Contributors credited above who also filed the issues behind these fixes: @krseager (#7576, #7627, #7629, #7648), @KunXi-Fox (#7580, #7608, #7640), @hongjun-bae (#7385, #7557, #7777, #7871), @littlespex (#6090, #7724, #7858), @mstyura (#7441), @gemxx (#7853), @cotid-qualabs (#7886), and @AmPlace (#7937)
Provide feedback in GitHub Issues. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.6.18
HLS.js v1.6.18 includes bug fixes previously scheduled to land in v1.7.
https://github.com/video-dev/hls.js/compare/v1.6.17...v1.6.18
- Bind initPTS to the lowest DTS across tracks to prevent negative timestamps (Cherry-picked from 45a1576 of #7880 and #7700 - Fixes #7932) @robwalch
https://12b4538a.hls-js-dev.pages.dev/demo/
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.7.0-rc.3
HLS.js v1.7.0-rc.3 includes bug fixes and improvements over the last pre-release.
https://github.com/video-dev/hls.js/compare/v1.7.0-rc.2...v1.7.0-rc.3
- Update README supported features (#7953) @robwalch
- Defer playlist reload while network is offline (#7926)
- Fix "discontinuity sequence mismatch" for fragment hint with no parts (#7964)
- Prevent loop loading for SourceBuffer mismatch append errors (#7965)
- Fixed v1.7 dev regressions:
- Fix key-status internal-error handling (#7963)
- Fix MPEGTS Sample-AES decryption (#7959)
- Migrate CI to Sauce Connect 5 (#7957) @itsjamie
- Improve CEA-608 performance for low powered devices (#7949)
- Improve tsdemuxer performance (#7955)
- Improve mp4 box parsing performance (#7956)
A complete list of 1.6 to 1.7 changes will be included in the v1.7.0 release. For now, please consult the earlier pre-release notes:
https://github.com/video-dev/hls.js/releases/tag/v1.7.0-rc.2 https://github.com/video-dev/hls.js/releases/tag/v1.7.0-rc.1 https://github.com/video-dev/hls.js/releases/tag/v1.7.0-beta.2 https://github.com/video-dev/hls.js/releases/tag/v1.7.0-beta.1
https://7d50c871.hls-js-dev.pages.dev/demo/
No public exports were removed and no runtime behavior changes are required to upgrade from v1.6 to v1.7. A list of changes impacting TypeScript consumers have been added to the migration guide: https://github.com/video-dev/hls.js/blob/v1.7.0-rc.3/MIGRATING.md#migrating-from-hlsjs-16-to-17
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.6.17
HLS.js v1.6.17 includes bug fixes previously scheduled to land in v1.7.
https://github.com/video-dev/hls.js/compare/v1.6.16...v1.6.17
- Fixed PTS rollover condition causing segment 0 loop (#7752) @christriants
- Fixed mapPartIntersection loop bounds (#7859) @sugarzyc
- Fixed initial reload time of live media playlist loaded with
hls.loadSource()(#7875) @robwalch - Fixed "discontinuity sequence mismatch" for fragment hint with no parts (#7964)
https://e5f5c274.hls-js-dev.pages.dev/demo/
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.7.0-rc.2
HLS.js release candidate v1.7.0-rc.2 includes bug fixes and improvements over the last pre-release.
https://github.com/video-dev/hls.js/compare/v1.7.0-rc.1...v1.7.0-rc.2
- Mark fragments as gaps after repeated appends without buffered range growth (#7941) @rudemateo
- Introduces
ErrorDetails.BUFFER_APPEND_NO_PROGRESS(newErrorTypes.MEDIA_ERRORtype error event) - Adds
chunkMeta: ChunkMetadatatoFragBufferedDataandFragParsedDatapayloads
- Introduces
I-Frame support
- Support muxed audio+video fMP4 and multi-trun I-Frame fragments (#7940) @rudemateo
- Consolidated the I-Frame remux code into one function (#7945) @robwalch
Interstitials
- Fix Interstitial live resumption estimate from preroll (#7944) @robwalch
Startup and teardown
- Fix selection with small samples (#7939) @robwalch
- Guard abandon-rules check after destroy (#7938) @AmPlace
https://71861d99.hls-js-dev.pages.dev/demo/
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.7.0-rc.1
HLS.js release candidate v1.7.0-rc.1 includes bug fixes and improvements over the previous beta.
https://0f9f490e.hls-js-dev.pages.dev/demo/
https://github.com/video-dev/hls.js/compare/v1.7.0-beta.2...v1.7.0-rc.1
- CMCDv2 Support: implement rtp, lb, dl, pb, tpb, ttfb and ttlb (#7895) @cotid-qualabs
I-Frame support
- Fixed I-Frame trick play rendering of stretched and backward-loaded frames (#7930) @rudemateo
- Force rendering of requested I-Frames and prevent loading of following segments (#7934) @robwalch
Interstitials
- Improved Low-Latency Live join from preroll into midroll (#7935) @robwalch
- Added Streamfizz to "They use HLS.js in production!" (#7927) @geosigno
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.7.0-beta.2
HLS.js v1.7.0-beta.2 includes bug fixes and improvements over the last beta release.
https://e29be494.hls-js-dev.pages.dev/demo/
https://github.com/video-dev/hls.js/compare/v1.7.0-beta.1...v1.7.0-beta.2
- CMCDv2 Support: custom events, custom keys and
ec(#7887) @cotid-qualabs
- Support
EXT-X-MEDIA-SEQUENCEdeclaration afterEXT-X-SKIP(#7905) @hongjun-bae - Treat un-demuxable fragments as a gap to prevent infinite reloading (#7900)
Interstitials
- Fix Low-Latency Live join with interstitial preroll (
PRE,ONCE) (#7908) @robwalch - Fix Live Interstitial midroll buffering and playback (#7913)
Low-Latency HLS
- Fix Low-Latency HLS subtitle part loading (#7893) @robwalch
I-Frame support
- Fix remuxing of encrypted I-Frame segments (#7896) @robwalch
- Fix AES byte-range addressed I-Frame decryption (#7892)
Regressions in dev / v1.7.0-beta.1
- Fix subtitle buffering up to or past media buffer (#7921) @robwalch
- Fix fatal KEY_SYSTEM_ERROR handling (#7920)
- Fix
autoStartLoad:falseand deferredstartPosition(#7903) - Fix uncaught init segment abort errors (#7904)
- Lint em-dash chars (#7899) @robwalch
For the complete list of v1.7 changes, on top of those above, see the beta.1 release notes: https://github.com/video-dev/hls.js/releases/tag/v1.7.0-beta.1
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.
v1.7.0-beta.1
HLS.js v1.7.0 adds I-frame playlist support, improved playback of protected content, and CMCD v2 for standardized streaming analytics. It also delivers smoother audio-track switching, faster startup via parallel init-segment loading, and broad fixes across Low-Latency HLS, subtitles, interstitials, and live streaming.
Highlights to try in this release:
- I-frame playback — call
hls.createIFramePlayer()andloadMediaAt(time)to render frames from a stream's#EXT-X-I-FRAME-STREAM-INFvariants in a video element, or load an#EXT-X-I-FRAMES-ONLYmedia playlist directly. - Smoother audio switching — set
hls.nextAudioTrack(or passflushImmediatetosetAudioOption) to schedule a seamless audio-rendition change that avoids stalls and added live latency. - CMCD v2 — set
cmcd.version: 2to enable it, and configurecmcd.eventTargetsto send standardized event reports to an external analytics endpoint. - Faster startup — alternate audio and video init segments now load in parallel; try a stream with separate audio/video renditions.
- Tune live resilience — new
errorPenaltyExpireMs,abrSwitchInterval, andappendTimeoutconfig options, plus thePLAYLIST_UNCHANGED_ERRORandMEDIA_SOURCE_REQUIRES_RESETevents.
https://github.com/video-dev/hls.js/compare/v1.6.15...v1.7.0-beta.1
- HLS I-FRAME playlist support —
#EXT-X-I-FRAME-STREAM-INFand#EXT-X-I-FRAMES-ONLY(#7757, #7791) @robwalch- Optimized I-frame parsing (#7794)
- "mjpg" image I-frame support (#7862)
- Parse I-frame multivariant tags that end at EOF without a trailing newline (#7851) @rudemateo
- Play single-keyframe fMP4 segments and parse
tfhddefault_sample_sizecorrectly (#7884) @rudemateo
- CMCD v2 — upgrade Common Media Client Data reporting to the CMCD v2 specification (#7725) @littlespex
- Smooth audio track switching via the
hls.nextAudioTrackAPI (#7575) @krseager
hls.iframeVariants,hls.createIFramePlayer()→HlsIFramesOnly.loadMediaAt(time): render frames from a stream's#EXT-X-I-FRAME-STREAM-INFvariants in a video element (#7757, #7791) @robwalchhls.createImageIFramePlayer()→HlsImageIFramesOnly.attachImage(image): render "mjpg" image I-frame variants (#7862) @robwalchiframeCacheLimitconfig option (default 2 MB) : cap I-frame data cached for rendering
hls.nextAudioTrackgetter/setter : Smooth audio switching (#7575) @krseagernextAudioTrackBufferFlushForwardOffsetconfig option (default 0.25) : forward buffer retained when scheduling a seamless switch
- Add optional
flushImmediateargument tohls.setAudioOption(#7795) @krseager hls.audioForwardBufferInfogetter : get audio-specific forward buffer info (#7865) @robwalchPLAYLIST_UNCHANGED_ERRORevent : Max Unchanged Live Updates (#7704) @dzianis-dashkevichliveMaxUnchangedPlaylistRefreshconfig option (default Infinity) : unchanged live refreshes allowed before the error fires
MEDIA_SOURCE_REQUIRES_RESETerror event : MediaSource closed while attached or ended on append error (#7699) @christriants- Started with: Track "sourceended" event and handle ManagedMediaSource recovery (#7697) @zalishchuk
- Additional work (#7702, #7707) @robwalch
- Only emit
FRAG_PARSING_USERDATAwhen text samples are found (#7686) @XephyrKenny - Add
subtitleTrackandclosedCaptionsproperties toCUES_PARSEDevent (#7843) @robwalch cmcd.versionandcmcd.eventTargetsconfig (pluscmcd.includeKeysand a customcmcd.loader) : enable CMCD v2 and report events to an external analytics endpoint (#7725) @littlespexabrSwitchIntervalconfig option (#7669) @christriantsappendTimeoutconfig option : SourceBuffer append operation timeout handling (#7670) @dzianis-dashkevicherrorPenaltyExpireMsconfig option : Re-elect penalized level after configurable penalty expiry (#7771) @Harshit661000- Add
xhrSetupcontext arg and loader context types (#7831 @robwalch, #7762 @dzianis-dashkevich) loopBackBufferFlushconfig option : flush the back-buffer on looped streams (#7869) @dzianis-dashkevichhandleMpegTsVideoIntegrityErrorsconfig option ('process'|'skip') : how to handle corrupt MPEG-TS video (#7094) @mstyuraemsgKLVSchemaUriconfig option (defaulturn:misb:KLV:bin:1910.1) : schema URI for MISB KLVemsgmetadata (#7668) @jacorbelloskipBufferHolePaddingconfig option (default 0.1) : padding applied when skipping buffer holes/gaps (#7630) @krseager
Content protection (DRM)
- DRM and multi-key handling improvements for improved protected playback (#7517) @robwalch
- Resolve usable keys from the latest key session before requesting another, and resolve
setMediaKeysonce attached (#7879, #7615) @robwalch - Parse the Widevine key id from the
EXT-X-KEYPSSH (andencryptedevent initData) whenKEYIDis absent (#7775, #7415) @robwalch @yajin2021 - Support playback of elementary (containerless) audio encrypted with Sample-AES (#7479) @Yesterday17
- Load the key for the fragment of a selected LL-HLS part so encrypted parts decrypt correctly (#7874) @robwalch
Audio switching, live & buffering
- Smooth audio track switching (#7575) @krseager
- Error and stop streaming after max unchanged live updates (#7704) @dzianis-dashkevich
- Download init segments in parallel for a faster start (#7867) @krseager
- Flush the back-buffer for looped streams (#7869) @dzianis-dashkevich
- Improve audio/video append synchronization (#7842) @robwalch
- Avoid an audio buffer flush on the first track switch (#7696)
- Reach the "ended" state reliably when a playlist ends with empty or gap segments (#7609)
- Better playlist alignment when PDT is inconsistent across renditions (#7482)
Timed metadata & track management
- Extract MISB KLV timed metadata from MPEG-TS and CMAF streams (#7668) @jacorbello, including when audio is present (#7673) @jacorbello
- Allow removing TextTracks that hls.js created (#7515) @xxoo
- (Uses removable DOM
<track>elements overHTMLMediaElement.addTextTrack()which does not allow removal)
- (Uses removable DOM
Networking & resilience
- fetch-loader retry logic for transient network failures (#7756) @dzianis-dashkevich
- Verify byte-range responses and warn on a size mismatch (#7701) @robwalch
- Detect corrupt MPEG-TS video streams (#7094) @mstyura
Performance, memory & lifecycle
- Cap the selected level to the player size with
ResizeObserver, and makenextLevelSwitchmore responsive (#7108) @robwalch - Clear the resolved fragment/part URL cache when done to reduce memory use (#7731)
- More reliable transmuxer teardown on
destroy()(#7863) - Keep inherited logger methods intact on
destroy()(#7864) - Improve M2TS init-segment handling and append-queue logging (#7695)
- Remove dead code and some unused exports for a smaller bundle (#7882)
Playback start, seeking & timestamps
- Fix backward seeking that led to stalling or elevated buffering (#7577) @krseager
- Fix certain Tizen devices getting stuck seeking over buffer gaps (#7630) @krseager
- Fix an endless loop in the gap controller on bad streams (zero-duration segments) (#7661) @robwalch
- Restore playback after page restoration from bfcache in Safari (#7683) @christriants
- Restart loading from
recoverMediaError()whenautoStartLoadis disabled (#7693) @robwalch - Roll initPTS forward when needed by earlier segments (#7537) @robwalch
- Correct a
computeInitPtsrollover that caused a segment-0 loop (#7752) @christriants - Adjust initPTS when a level switch drops the opening GoP (#7700) @robwalch
- Do not update initPTS on small drift caused by playlist segment-duration rounding (#7792) @robwalch
Rendering & codecs
- Work around Chrome silently evicting coded frames on PTS overlap (#7807) @robwalch
- Pad the initial PTS of remuxed MPEG-TS to avoid Chrome rendering glitches (#7805) @robwalch
- Drop bad MP4 data instead of failing the append (#7815) @robwalch
- HEVC: set sync samples from IRAP VCL NALs (#7861) @gemxx
- HEVC: correct access-unit sample boundaries in Safari (#7854) @gemxx
- Switch away from containerless EC-3 audio that hls.js cannot demux (Safari) instead of stalling (#7873) @robwalch
- Handle implicit HE-AAC for AAC Main at low sample rates (#7835) @robwalch
Audio tracks
- Fix switching back to main (audio-only) after end-of-stream is buffered (#7645) @robwalch
- Fix AES-128 decryption failure on alternate audio when a shared key load is pending (#7834) @robwalch
- Fix audio TS segment duration calculation (#7646) @robwalch
- Stop
AUDIO_TRACK_LOAD_TIMEOUTfrom following theerrorRetrypolicy inplaylistLoadPolicy(#7506) @CongCong-1228
Content protection (DRM)
- Fix PlayReady on some devices (#7631) @KunXi-Fox
- Fix PlayReady key endianness (#7510) @ShubhamSharma2311
- Fix an eme-controller type error that depended on promise state (#7877) @bwallberg
- Fix
licenseXhrSetupreturn types and aselectKeySystemnested-Promise anti-pattern (#7888) @robwalch
Subtitles & captions
- Decrypt LL-HLS VTT AES parts per-part (#7881) @hongjun-bae
- Fix Low-Latency HLS VTT subtitle part loading (#7626) @robwalch
- Align WebVTT segments missing an
X-TIMESTAMP-MAPheader with the media timeline (#7852) @robwalch - Fix WebVTT loading by disabling progressive loading for WebVTT (#7649) @krseager
- Cache initial cues added to a TextTrack so the browser does not remove them (#7809) @robwalch
- Fix CEA-608 cursor clamping so position stays within the column array bounds (#7666) @chelleccarlyle
Live, interstitials & content steering
- Fix live join following an interstitial preroll (#7846) @robwalch
- Fix interstitial live start with a short sliding window (#7799)
- Do not reset interstitials when seeking between assets (#7650)
- Fix an interstitial-controller exception on legacy engines where
media.play()returns no Promise (#7586) @malickyeu - Fix fallback to primary on live start (#7651) @robwalch
- Content Steering: apply
URI-REPLACEMENTHOSTto the hostname only (#7655) - Pathway Cloning: apply
PARAMSafterPER-VARIANT-URIS(#7710)
Live updates & playlist parsing
- Keep
PLAYLIST_UNCHANGED_ERRORnon-fatal so playback can reach the end of the playlist (#7812) @robwalch - Support an
EXT-X-DISCONTINUITY-SEQUENCEdeclaration after the first media segment (#7750) - Detect stream end after a live-to-VOD transition when
endListFragmentsis stale (#7754) @alchemyyy - Fix the initial reload time of a live playlist loaded with
hls.loadSource()(#7875) @robwalch - Do not request a video buffer flush or EOS when the main playlist is audio-only (#7868)
- Fix "Missing format identifier #EXTM3U" playlist parsing errors (#7533)
- Multivariant playlist parsing fixes (#7523)
Buffering, memory & recovery
- Recover from
QuotaExceededErrorby evicting the back-buffer and retrying (#7749) @alchemyyy - Limit buffering while paused outside the live sliding window (#7788) @robwalch
- Prevent loop-loading of segments whose appends were dropped (#7797)
- Make
part.gapwritable and handle part muxing errors as gaps (#7814) - Forward transmuxer worker errors correctly (#7883)
- Correct interstitial env vars and content-steering condition (#7727) @zalishchuk
- Update Chrome configuration for macOS in build.yml (#7698) @robwalch
- Increase minimum Windows test version for saucelabs (#7602)
- Use BrowserStack to run macOS CI tests (#7836)
- Update minimum browser support documentation and build config (#7880)
- Update to TypeScript 5.9 (#7607)
- Add dev container support for contributors (#7758) @tjenkinson
- Create SECURITY.md (#7685) @pr4v33n7-sa
- Fix links for API Docs in README (#7637) @daniemo2
- Add Labra-Flex to 'They use HLS.js in production!' section (#7419) @aaskaoui
- Add missing config options to API.md (#7628) @krseager
- Update README Alternative setup for 2026 browsers (#7844) @robwalch
- Fix HLS.js product name in issue templates (#7828) @karlhorky
- Document testing with BrowserStack and SauceLabs (#7780) @robwalch
- Fix TypeError on playlist load/reload inside of 3rd party library Chart.js for demo page (#7801) @krseager
- Add an
hlsjsConfigquery param to populate the demo editor (#7473) @quentinms
https://9f9035b8.hls-js-dev.pages.dev/demo/
Beyond the code contributors credited above, a big thank you to the community members whose issue reports drove fixes and improvements in this release:
- @gdplayerto (#4958), @iamsyk (#6374), @Hyddan (#6680), @luwes (#6777), @Tzipi-kaltura (#7524), @twilson90 (#7531), @knuthaug (#7535), @bmarshall (#7536), @AfLosada (#7541), @dchan-harmonicinc (#7554), @xtne6f (#7556), @MosheMaorKaltura (#7572), @matvp91 (#7641), @doublex (#7667), @thexeos (#7677), @gjanblaszczyk (#7687), @wei-li-dwango (#7808), @foliovision (#7833), @philhar88 (#7845), @robybales3 (#7850), and @mrlika (#7876)
- @flagoworld, whose PR #7453 informed the live media playlist reload fix (#7875)
Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.