yarn hls.js 1.7.0-beta.1
v1.7.0-beta.1

latest releases: 1.7.0-rc.1.0.canary.11893, 1.7.0-rc.1.0.canary.11892, 1.7.0-rc.1.0.canary.11891...
one month ago

Summary

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() and loadMediaAt(time) to render frames from a stream's #EXT-X-I-FRAME-STREAM-INF variants in a video element, or load an #EXT-X-I-FRAMES-ONLY media playlist directly.
  • Smoother audio switching — set hls.nextAudioTrack (or pass flushImmediate to setAudioOption) to schedule a seamless audio-rendition change that avoids stalls and added live latency.
  • CMCD v2 — set cmcd.version: 2 to enable it, and configure cmcd.eventTargets to 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, and appendTimeout config options, plus the PLAYLIST_UNCHANGED_ERROR and MEDIA_SOURCE_REQUIRES_RESET events.
  • Improved support for looped video — new loopBackBufferFlush config option flushes the back-buffer of lower quality on looped streams

Changes Since The Last Release

v1.6.15...v1.7.0-beta.1

Features

  • HLS I-FRAME playlist support#EXT-X-I-FRAME-STREAM-INF and #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 tfhd default_sample_size correctly (#7884) @rudemateo
  • CMCD v2 — upgrade Common Media Client Data reporting to the CMCD v2 specification (#7725) @littlespex
  • Smooth audio track switching via the hls.nextAudioTrack API (#7575) @krseager

New API, events & config options

  • hls.iframeVariants, hls.createIFramePlayer()HlsIFramesOnly.loadMediaAt(time) : render frames from a stream's #EXT-X-I-FRAME-STREAM-INF variants in a video element (#7757, #7791) @robwalch
  • hls.createImageIFramePlayer()HlsImageIFramesOnly.attachImage(image) : render "mjpg" image I-frame variants (#7862) @robwalch
    • iframeCacheLimit config option (default 2 MB) : cap I-frame data cached for rendering
  • hls.nextAudioTrack getter/setter : Smooth audio switching (#7575) @krseager
    • nextAudioTrackBufferFlushForwardOffset config option (default 0.25) : forward buffer retained when scheduling a seamless switch
  • Add optional flushImmediate argument to hls.setAudioOption (#7795) @krseager
  • hls.audioForwardBufferInfo getter : get audio-specific forward buffer info (#7865) @robwalch
  • PLAYLIST_UNCHANGED_ERROR event : Max Unchanged Live Updates (#7704) @dzianis-dashkevich
    • liveMaxUnchangedPlaylistRefresh config option (default Infinity) : unchanged live refreshes allowed before the error fires
  • MEDIA_SOURCE_REQUIRES_RESET error event : MediaSource closed while attached or ended on append error (#7699) @christriants
  • Only emit FRAG_PARSING_USERDATA when text samples are found (#7686) @XephyrKenny
  • Add subtitleTrack and closedCaptions properties to CUES_PARSED event (#7843) @robwalch
  • cmcd.version and cmcd.eventTargets config (plus cmcd.includeKeys and a custom cmcd.loader) : enable CMCD v2 and report events to an external analytics endpoint (#7725) @littlespex
  • abrSwitchInterval config option (#7669) @christriants
  • appendTimeout config option : SourceBuffer append operation timeout handling (#7670) @dzianis-dashkevich
  • errorPenaltyExpireMs config option : Re-elect penalized level after configurable penalty expiry (#7771) @Harshit661000
  • Add xhrSetup context arg and loader context types (#7831 @robwalch, #7762 @dzianis-dashkevich)
  • loopBackBufferFlush config option : flush the back-buffer on looped streams (#7869) @dzianis-dashkevich
  • handleMpegTsVideoIntegrityErrors config option ('process' | 'skip') : how to handle corrupt MPEG-TS video (#7094) @mstyura
  • emsgKLVSchemaUri config option (default urn:misb:KLV:bin:1910.1) : schema URI for MISB KLV emsg metadata (#7668) @jacorbello
  • skipBufferHolePadding config option (default 0.1) : padding applied when skipping buffer holes/gaps (#7630) @krseager

Enhancements

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 setMediaKeys once attached (#7879, #7615) @robwalch
  • Parse the Widevine key id from the EXT-X-KEY PSSH (and encrypted event initData) when KEYID 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 & 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 over HTMLMediaElement.addTextTrack() which does not allow removal)

Networking & resilience

Performance, memory & lifecycle

  • Cap the selected level to the player size with ResizeObserver, and make nextLevelSwitch more 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)

Bug fixes

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() when autoStartLoad is disabled (#7693) @robwalch
  • Roll initPTS forward when needed by earlier segments (#7537) @robwalch
  • Correct a computeInitPts rollover 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_TIMEOUT from following the errorRetry policy in playlistLoadPolicy (#7506) @CongCong-1228

Content protection (DRM)

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-MAP header 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-REPLACEMENT HOST to the hostname only (#7655)
  • Pathway Cloning: apply PARAMS after PER-VARIANT-URIS (#7710)

Live updates & playlist parsing

  • Keep PLAYLIST_UNCHANGED_ERROR non-fatal so playback can reach the end of the playlist (#7812) @robwalch
  • Support an EXT-X-DISCONTINUITY-SEQUENCE declaration after the first media segment (#7750)
  • Detect stream end after a live-to-VOD transition when endListFragments is 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 QuotaExceededError by 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.gap writable and handle part muxing errors as gaps (#7814)
  • Forward transmuxer worker errors correctly (#7883)

Build and CI

  • 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)
  • Add dev container support for contributors (#7758) @tjenkinson
  • Correct interstitial env vars and content-steering condition (#7727) @zalishchuk

Documentation and README

Demo

  • Fix TypeError on playlist load/reload inside of 3rd party library Chart.js for demo page (#7801) @krseager
  • Add an hlsjsConfig query param to populate the demo editor (#7473) @quentinms

Demo Page

https://9f9035b8.hls-js-dev.pages.dev/demo/

Special thanks

Beyond the code contributors credited above, a big thank you to the community members whose issue reports drove fixes and improvements in this release:

Feedback

Please provide feedback via Issues in GitHub. For more details on how to contribute to HLS.js, see our CONTRIBUTING guide.

Don't miss a new hls.js release

NewReleases is sending notifications on new releases.