Releases: canalplus/rx-player
v4.4.0
Release v4.4.0 (2025-09-25)
  Quick Links:
  π API documentation
  -
  β― Demo
  -
  π Migration guide from v3
- π Overview
 - π Changelog
 onVideoTracksNotPlayable/onAudioTracksNotPlayable- new 
disableAudioTrackAPI - new method: 
getWallClockOffset seekTonow callable whileLOADING/RELOADING- Key system information on most 
EncryptedMediaError - Firefox and Chrome now handling PlayReady SL3000 on Windows
 - More structured logs
 - New hidden experimental API: Dummy Media Element
 - Improved MediaCapabilitiesProber Experimental API
 - Auditable RxPlayer releases
 
π Overview
The v4.4.0 is here, with many new features and improvements:
- 
new
onAudioTracksNotPlayableandonVideoTracksNotPlayableloadVideooptions to allow playback even if no audio or video tracks are supported on the current content. - 
A new
disableAudioTrackAPI, to complement the existingdisableVideoTrackanddisableTextTrackAPIs and give you control over all media track types - 
seekTocan now be relied on even when stillLOADING/RELOADING, to correct a future playback position. - 
A new
getWallClockOffsetAPI to facilitate conversions between the RxPlayer'spositionand the "wallClockTime"that is generally more useful for live contents. - 
EncryptedMediaErrorerrors, which are those linked to content decryption, now will also communicate context when possible, such as the corresponding key system name and configuration. - 
Add
MediaErrorwith the"NO_AUDIO_VIDEO_TRACKS"code for when neither audio nor video is available or when both are disabled - 
"local"Manifests (experimental feature to load contents that are downloaded locally) can now announce forced narrative subtitles tracks, through the newforcedSubtitlesproperty - 
The experimental
MediaCapabilitiesProbertool had its API updated to be more flexible (see below) - 
WebVTT embedded in an mp4 segment are now properly handled.
 - 
Firefox and Chrome recently added PlayReady SL3000 support under most Windows 11 devices. It is now properly handled.
 - 
Thumbnails (from our new thumbnails API brought in v4.3.0) now have a better caching mechanism.
 - 
RxPlayer logs have been rewritten to be more easily read and exploited by people relying on the RxPlayer logs for debugging
 - 
many bug fixes and other improvements
 
Changelog
Features
- Add 
onAudioTracksNotPlayableandonVideoTracksNotPlayableloadVideooptions to control whether to continue playback is one of those components is not compatible to the current device [#1624] - Add 
getWallClockOffsetAPI to obtain a "live position"'s offset [#1601] - add 
disableAudioTrackAPI [#1715] - DRM: Add 
keySystemandkeySystemConfigurationto mostEncryptedMediaErrorso an application can determine which key system caused an issue [#1690] - Update API of the experimental 
mediaCapabilitiesProberAPI so it's more flexible to use [#1472] - Implement inband WebVTT (vtte/vttc) [#1639]
 - Add 
"NO_AUDIO_VIDEO_TRACKS"error for when neither audio nor video is available or when both are explicitly disabled [#1624] - Allow seeking through 
seekToeven whileLOADINGorRELOADINGthe content [#1607] - local: local-manifests now can have a 
forcedSubtitlesproperty in anadaptationsobject, to indicate that a text track actually represents "forced narrative" subtitles [#1722] 
Bug fixes
- Subtitles: Fix some subtitle missing on multiple period assets [#1708]
 - DRM: renew the mediaKeySystemAccess on Edge and Firefox when using a PlayReady keySystem to work-around frequent DRM issues. [#1694]
 - DASH: Fix some rare occurence of infinite rebuffering on multi-Period when seeking exactly at the end of a Period. [#1738]
 - DRM: On Firefox check extensively PlayReady DRMs support before using them to work-around recent firefox issue with PlayReady integration [#1691]
 - DRM: Fix persistent session loading when content has no key id [#1713]
 representationobject returned by some API had incorrect shape for optional attributes [#1720]- Directfile: set autoplay attribute on directfile contents, to work-around safari-specific issues [#1711]
 - Remove unnecessary duration logs when reaching the end of some VoD contents [#1744]
 
Other improvements
- Add hidden experimental API "Dummy media API" to facilitate tests and debugging of the RxPlayer behavior without having to support the content in the current environment [#1478]
 - Thumbnails: Cache pending thumbnail request [#1718]
 - For Dynamic contents, let the initial position go outside the range of the Manifest and let the application correct if if needed based on 
MEDIA_TIME_BEFORE_MANIFESTorMEDIA_TIME_AFTER_MANIFESTevents [#1607] - Update log syntax so users can follow them more easily [#1717]
 - Add to hidden RxPlayer config most compat switches [#1514]
 - Prevent unnecessary resources usage by inactive worker [#1696]
 - Improve on freeze resolution, especially for encrypted contents [#1705]
 - Detect that 
fetch/AbortControlleris native to provide a better experience for application relying on (broken) polyfills instead [#1698] - enable debug logs as soon as 
__RX_PLAYER_DEBUG_MODE__is set [#1626] - rely on "provenance statements" when publishing our builds [#1742]
 
onVideoTracksNotPlayable / onAudioTracksNotPlayable
One of the most significant additions in this release is the introduction of two new loadVideo options:
Reason: error or reduced experience?
Until now, when playing a content whose audio was not supported on the device, the RxPlayer would stop playback and throw a MANIFEST_INCOMPATIBLE_CODECS_ERROR error.
Technically, we could have just continued only playing video and no audio in that scenario. We only stop playback on an error because we inferred that most applications didn't want the possibility of those kind of reduced experiences.
And the same rules apply if video is unsupported yet audio is, or when one of them is non-decipherable (in which case you could by default see the NO_PLAYABLE_REPRESENTATION fatal error) but the other is.
novideoshort.mp4
Video: When you play content whose audio or video is not currently supported (here HEVC video on my device), you're left with an error. Here is how it displays in our demo page.
But failing directly is not what everybody want: we had multiple feature requests to allow playback without audio or video if one of them was unsupported (either due to codec issues or due to the impossibility to decipher it).
Two new options
We thus brought two new options in this release to give you granular control over how the player behaves in such scenarios:
player.loadVideo({
  transport: "dash",
  url: "https://example.com/content.mpd",
  autoPlay: true,
  onAudioTracksNotPlayable: "continue", // Play without audio instead of failing
  onVideoTracksNotPlayable: "error", // Still fail if video tracks are incompatible
});Both options accept either "continue" or "error":
- 
"error": The player will throw the corresponding error and stop, maintaining the default behavior. - 
"continue": The player will continue playback without the problematic media type. 
You can thus set either of those to "continue" now to continue playback anyway:
novideo1.mp4
Video: Demonstration of how the onVideoTracksNotPlayable in "continue" mode could work. Here in our demo page we end up playing the content without the video (but with audio playing).
If the video does not play, it is available here: https://github.com/user-attachments/assets/8595d290-62cd-4f45-8d7f-7ff74bcba598
Note that if such a "fallback" happens during playback (for example: during a DASH Period transition), it may lead to a small RELOADING step.
New event: noPlayableTrack
When setting either of those two new options to continue, you might want to be alerted when and if such "fallback" scenario happens.
For exactly this, we also added the [noPlayableTrack](https://developers.canal-plus....
v3.33.6
Release v3.33.6 (2025-09-25)
  Quick Links:
  π API documentation
  -
  β― Demo
π Overview
The v3.33.5 is a "legacy" release (now that the v4 is the current major version) mostly containing some of the bug fixes and improvements initially made for the upcoming v4.4.0 release that should be done just after this one.
Note that, after a year and a half of support while our v4 was our main focus, it may be our last legacy v3 release, unless a sensible issue is found on it.
Though we encourage all applications to switch to our v4, we understand that some applications don't have the time for this change. Our v3 will still be available and you can also report issues specifically seen with it, in which case we may still fix the issue depending on the effort for doing so.
π Changelog
Bug fixes
- Subtitles: Fix some subtitle missing on multiple period assets [#1726]
 - DRM: renew the mediaKeySystemAccess on Edge and Firefox when using a Playready keySystem to work-around frequent DRM issues. [#1728]
 - DRM: On Firefox check extensively Playready DRMs support before using them to work-around recent firefox issue with PlayReady integration [#1730]
 - DRM: Fix persistent session loading when Manifest has no key id [#1724]
 - Directfile: set autoplay attribute on directfile contents, to work-around safari-specific issues [#1729]
 - Remove unnecessary duration logs when reaching the end of some VoD contents [1750]
 
v4.3.0
Release v4.3.0 (2025-04-01)
  Quick Links:
  π API documentation
  -
  β― Demo
  -
  π Migration guide from v3
- π Overview
 - π Changelog
 - DASH Thumbnail tracks
 - ManagedMediaSource API support
 - Representation avoidance mechanism
 - Codec checking in the same environment where MSE is running
 keySystems[].wantedSessionTypes
π Overview
The v4.3.0 is finally here.
We took some time to release it compared with previous releases due to a lot of other subjects coming our way late last year.
We do have worked on a larger amount of features since the last release, yet many of them are thus still in a review phase for now, and we focused on stability and what we thought were the most awaited features for a (normal-sized!) v4.3.0, especially:
- 
Handling of DASH thumbnail tracks.
To minimize the complexity on your side, our thumbnail-related API takes care of every details about thumbnail fetching, caching and rendering, all you'll have to do is providing a timestamp for the wanted thumbnail and the DOM element on which you want to display the corresponding thumbnail.
 - 
We now automatically handle the
ManagedMediaSourceAPI (the MSE variant found on iOS devices), along with itsstartstreaming/endstreamingevents, minimizing battery usage on those devices. - 
We added a new "Representation avoidance" algorithm. The idea is to automatically detect audio and video contents that lead to unexpected decoding issues on the current device and, if detected, to avoid playing them. This follows real issues we had seen on some WebOS and TitanOS devices (respectively mostly LG Smart TVs and mostly Philips Smart TVs).
For now this new behavior is behind an option - though it might become a default feature in the future as explained below.
 - 
We added a
keySystems[].wantedSessionTypesloadVideooption for very specific DRM-related optimizations. The reasons why applications could need this are somewhat complex and are explained below. - 
We realized that multiple newer devices (at least the Meta Quest 2 and some other embedded devices) had issues decoding Dolby Digital+ only when it was encrypted.
We had a small issue in our logic detecting codec support in an encrypted context (added in
v4.2.0) that made this specific case not handled. Now we should properly avoid any audio or video codec that is unsupported when encrypted. - 
We fixed an issue preventing playback of some contents with h265 video, for now only seen on the Edge browser if specific updates for H265 support were manually installed and if the RxPlayer was running in
"multithreading"mode (which seems rare, but it does happen, especially for some techy customers!).The root issue may be an Edge Browser bug, but it did reveal an area where we could improve our resilience. We found the components of that issue to be interesting so we added more information on it in this release not!
 - 
We brought several improvements for Tizen devices, including fixing two issues that led to infinite rebuffering in specific scenarios.
Tizen devices were known to have a worse experience in general due to the way it implements some media-related aspects from the HTML standard.
 - 
We improved multiple minor aspects of the
MULTI_THREADexperimental feature, including some bug fixes and performance improvements. - 
We also brought improvements on some of the RxPlayer's sister projects: most notably, RxPaired (our RxPlayer-specialized remote inspector) is now able to fallback to HTTP POST on devices where
WebSocketare not available and README (our documentation generator - which generates the RxPlayer API documentation) has now some improvements linked to search, mainly tree-organized results and a different client-side search library, 
Changelog
Features
- Add the possibility to rely on 
ManagedMediaSourceon iOS devices [#1562] - DASH: Implement DASH Thumbnail tracks by adding 
renderThumbnailandgetAvailableThumbnailTracksAPI [#1496] - DRM: Add 
keySystems[].wantedSessionTypesloadVideooption to also initialize a DRM config for future contents, not just the current one [#1604] - Add 
experimentalOptions.enableRepresentationAvoidanceoption toloadVideoto enable our new Representation avoidance mechanism [#1523] 
Bug fixes
- Tracks API do not return unplayable representations by default [#1599]
 - MULTI_THREAD: Fix 
onmessageerrorbeing undefined on older devices [#1585] - MULTI_THREAD: Do not attempt to play audio and/or video media data in a Worker whose codec is not supported specifically in a Worker context (previous behavior led to some fatal errors on Edge with HEVC support) [#1664]
 - Compat: On "FREEZING" try to un-freeze regardless of if the wanted position was reached to fix a remaining Tizen (Samsung) infinite rebuffering issue [#1586]
 - MULTI_THREAD: Fix error not being thrown on manifest update [#1653]
 - DRM: check that ec-3 codec is supported when encrypted [#1657]
 - DRM: fix typo which prevented 
MediaKeysreusage on some devices including desktop browsers [#1615] - DRM: Only ask for 
"persistent-license"MediaKeySession(and not also for"temporary"license) when only akeySystems[].persistentLicenseConfigis communicated [#1604] - DRM: Fix reusage of some 
keySystems[]option changing when reusing aMediaKeySystemAccesswith a differentkeySystems[]configuration [#1616] - DRM: Fix 
KEY_UPDATE_ERRORwhich was mistakenly inheriting the codeKEY_LOAD_ERROR[#1670] - Fix minor memory leak when switching RepresentationStream through ABR [#1665]
 - On Tizen, fix infinite loading that may occur in some condition if both the audio and video segments have a gap at the expected initial position [#1637]
 - fix rare infinite rebuffering issues that may happen when updating tracks in a 
newAvailablePeriodsevent [#1643] - MULTI_THREAD: Fix potential leak when cleaning now inexistant Period [#1644]
 
Other improvements
- Compat: Limit long "FREEZING" issues on Tizen (samsung) by awaiting for browser action before seeking ourselves over a discontinuity [#1587]
 - DRM: Only reuse cached 
MediaKeySystemAccessif none is more wanted for the current content [#1591] - MULTI_THREAD: Some 
LOADINGandRELOADINGattempts may have taken more time than necessary due to a wrong "initial Period prediction", this is fixed [#1628] - Improve 
FREEZINGwork-arounds by reloading if our initial strategies do not give a result [#1523] - DRM: Reuse cache even if key system type given in API is not the same [#1611]
 - DEBUG_ELEMENT: Add buffer size estimate to debug buffer content graph [#1558]
 - DEBUG_ELEMENT: Add 
hdrinformation to video Representation [#1583] - Set LogFormat to 
fullon RxPlayer's debug mode [#1625] - Avoid error log when stopping a stream with a pending 
BufferGarbageCollectorbuffer removal [#1684] - tests: Our performance-regression tests now run on all RxPlayer updates to better protect against performance regressions [#1630]
 - CI/tests: CI integration tests on Edge and windows [#1621]
 
DASH Thumbnail tracks
Overview
The DASH specifications propose a way to declare a thumbnail track. Thumbnails are pictures representing different timecode of the video content, most often, they are used as preview thumbnails for seeking.

Screenshot: You can see in that screenshot a content being played with a thumbnail acting as a seeking preview on top of a mouse pointer (the thumbnail show a part of the content with a squirrel on screen).
Such "DASH thumbnails" is only one of the many ways to declare thumbnails linked to a video. Historically it was even not the preferred way: for example for VoD contents, an external archive following the BIF format was the most popular way as far as we know.

Schema: Crude representation of a bif file: some metadata at the start then all images concatenated.
However BIF files have a key issue: as an archive containing all images in advance, it doesn't work for live contents as future images are there only generated progressively.
This is a problem that DASH thumbnails don't have (because they follow roughly the same syntax than for the linked live video data), and we've recently seen more and more applications generating those, even for VoD contents.

  Quick Links:
  π API documentation
  -
  β― Demo
π Overview
The v3.33.5 is a "legacy" release (now that the v4 is the current major version) mostly containing some of the bug fixes and improvements initially made for the upcoming v4.3.0 release that should be done just after this one.
π Changelog
Bug fixes
- DRM: fix typo which prevented 
MediaKeysreusage on some devices including desktop
browsers [#1679] - DRM: Only ask for 
"persistent-license"MediaKeySession(and not also for
"temporary"license) when thekeySystems[].persistentLicenseoption is set totrue - DRM: Fix reusage of some 
keySystems[]option changing when reusing a
MediaKeySystemAccesswith a differentkeySystems[]configuration [#1678] - DRM: Fix 
KEY_UPDATE_ERRORwhich was mistakenly inheriting the codeKEY_LOAD_ERROR
[#1682] - Fix minor memory leak when switching RepresentationStream through ABR [#1681]
 - fix rare infinite rebuffering issues that may happen when updating tracks in a
newAvailablePeriodsevent [#1680] 
Other improvements
- Compat: Limit long "FREEZING" issues on Tizen (samsung) by awaiting for browser action
before seeking ourselves over a discontinuity [#1673] - DRM: Only reuse cached 
MediaKeySystemAccessif none is more wanted for the current
content [#1674] - DRM: Reuse cache even if key system type given in API is not the same
 - DEBUG_ELEMENT: Add buffer size estimate to debug buffer content graph [#1672]
 - DEBUG_ELEMENT: Add 
hdrinformation to video Representation [#1671] - Avoid error log when stopping a stream with a pending 
BufferGarbageCollectorbuffer
removal [#1685] 
v4.2.0
Release v4.2.0 (2024-10-17)
  Quick Links:
  π API documentation
  -
  β― Demo
  -
  π Migration guide from v3
- π Overview
 - π Changelog
 - CMCD v1 support
 - DRM: Detection of codecs unsupported when encrypted
 - DRM: More information on Representations in the API
 keySystems[].reuseMediaKeysoptionLogFormatstatic propertycheckManifestIntegrityoption- Safari/DRM: Fix for the DRM+language issue
 - Note 1: Facilitating tests of RxPlayer pending developments
 - Note 2: Work-around for a Firefox 129 issue
 
π Overview
The v4.2.0 is out, with both new features and multiple fixes:
- 
"cmcd" (for "common media client data") v1 is now (fully) supported. It is a standardized system to allow the communication of current playback conditions through http(s) requests.
 - 
When checking which media codec is supported on the device, we now also consider encryption as a factor.
This is following new Google Chrome releases supporting HEVC only when unencrypted.
 - 
We added a
filterPlayableRepresentationsoption to our audio and video tracks getters.This lets the application know about which media has been filtered out (e.g. 4k content due to it not being decipherable, or hevc content for not being decodable).
 - 
We added a
contentProtectionsproperty to Representations returned by the API to let applications know which Representations are encrypted and what their key id are. - 
We added the
checkManifestIntegrityoption, allowing to retry Manifest requests in cases where the CDN returned corrupted data.This was added after such behaviors was actually seen, in the name of resilience even when the issue is in another component of the media streaming process.
 - 
We worked around a Safari bug leading to infinite loading when playing encrypted HLS contents (through the
directfiletransport) and having a system language different than the playlist's default language. - 
We added the
LogFormatstatic property to produce more informative logs. - 
Many other fixes, including some for the experimental
MULTI_THREADfeature, some for theDASH_WASMfeature, for a short-lived firefox issue, for legacy bundles... 
Changelog
Features
- Add 
cmcdobject toloadVideooptions to enable CMCD (Common Media Client Data) [#1461, #1518] - Add 
checkManifestIntegrityloadVideooption as a temporary work-around when you suspect your packager or CDN to sometimes deliver corrupted data [#1471] - Add 
contentProtectionsto therepresentationsof the tracks API to know if they're considered encrypted [#1505] - Add 
filterPlayableRepresentationsproperty to audio and video tracks API to get information on ALL representations, even those that won't be played [#1501] - Add 
LogFormatstatic property to theRxPlayerto try improving on bug reports [#1469] - Experimentally re-export config in v4 (only intended for debugging matters) [#1510]
 
Bug fixes
- Detect cases where an encrypted media's codec is not supported specifically when the media is encrypted and prevent the playback of such contents [#1484]
 - Work-around the "hulu issue" seen on firefox 129 and 130 (
1911283and1912238on bugzilla) which also impacted the RxPlayer [#1495, #1498] - Fix rare cases where the active Period would not be advertised by the RxPlayer [#1502]
 - Actually trigger a 
BUFFER_FULL_ERRORwhenQuotaExceededErrormitigations afterappendBufferMSE calls don't work #1546 - Fix issues when handling a 
QuotaExceededErrorafter anappendBufferMSE call [#1546, #1559] - Directfile/Compat: Fix 
startAt.fromLastPositionhandling on Safari when playing directfile contents [#1548] - DRM/Compat: Re-create MediaKeys for each content on Philips' NETTV, and 
KSTB40XXset-top boxes [#1515] - DRM/Compat: fix content not starting on Safari because key are never considered usable for a track [#1479, #1512]
 - DASH_WASM: fix 
Labelelement never being parsed [#1541, #1540] - Fix RxPlayer not being exposed in release bundles [#1542]
 - Consider 
stpp.ttmlcodec for text format [#1557] - Prevent very rare cases of infinite rebuffering after getting errors from calling the 
SourceBuffer.prototype.appendBufferandSourceBuffer.prototype.removeMSE API [#1560, #1561] - MULTI_THREAD: Fix rare 
CancellationErrorerror happening when reloading while a reload is pending. [#1528] - MULTI_THREAD: fix wrong Period considered as current in multi-Period DASH contents with the multi-thread feature [#1527]
 - MULTI_THREAD: Fix rare occurrences of infinite loading on constrained devices [#1556]
 
Other improvements
- DASH: provide a more precize calculation for the timeshift buffer depth [#1483]
 - Handle 
hev1codec andhvc1codecs as part of the same family of codecs when trying to check for compatibility between the two [#1499] - Better handle 
QuotaExceededErrorissue afterappendBufferMSE calls whenwantedBufferAheadis set toInfinity[#1546] - Code: Forbid the direct usage of MSE and HTML5 media TypeScript type in profit of our own compatible ones to facilitate testing and the addition of platform-specific differences [#1397].
 - Demo: Remove standalone demo as we never relied on it [#1473]
 - Scripts: Automatize official releases and CHANGELOG.md updating through a script [#1524]
 
CMCD v1 support
CMCD, for "Common Media Client Data", is a standard allowing to communicate various playback-related metrics to the CDN when requesting resources.
The idea is that a back-end may then be able to exploit those metrics with the goal of improving both the streaming experience (e.g. by putting more bandwidth to customers that need it the most or by preparing segments that will be requested in the future) and the monitoring aspect (by being notified about buffer-related information, following the user's QoE).
The information CMCD v1 relies on can be here communicated either through HTTP(S) request headers or a query string in the URL and is opt-in: it is only enabled if the new cmcd loadVideo option is communicated.

Screenshot: request for an initialization segment with CMCD enabled as query string parameters.
Many players and CDN support CMCD today but the RxPlayer did not until now - mainly because we prioritized other work in the past.
We've now added a CMCD implementation so that application that wants to rely on it are now able to do so.
DRM: Detection of codecs unsupported when encrypted
Recently Google Chrome added support for HEVC (also known as "H.265"), though only if it was either unencrypted or if the current device had what we call "hardware DRM" available (which most desktop PCs do not have).
This was problematic because when considering what the RxPlayer was able to play it only checked if the codec was supported. It did not also take into consideration DRM matters.
We've now worked to not only consider whether a codec should theoretically be supported by a device but also consider, when the corresponding content is encrypted, if it is also supported when encrypted.
This improvement most notably now lead to the RxPlayer correctly avoiding encrypted H.265 video content on devices where hardware DRM is not available.
DRM: More information on Representations in the API
We sometimes work closely with applications using the RxPlayer, at least those at Canal+, to understand what API they might miss.
We noticed that our audio and video tracks API missed some key information that the application may find useful.
1. New filterPlayableRepresentations option
Previously, we filtered non-"playable" Representations (qualities) from our audio video tracks methods (getVideoTrack, getAvailableVideoTracks...) and events (videoTrackChange, availableVideoTracksChange...).
What this means is that video and audio qualities that were either in an unsupported codec or that were non-decipherable would not be communicated by those API, as they cannot be played anyway.
However, an application may want to know which qualities were present in the content yet are not supported, for example for monitoring and debugging use cases.
To allow this usage, the RxPlayer can now optionally take a filterPlayableRepresentations property through those following API:
- [
getAvailableVideoTracks](https://developers.canal-plus.com/rx-player/doc/api/Track_Selection/getAvailableVideoTracks.htm... 
v3.33.4
Release v3.33.4 (2024-10-16)
  Quick Links:
  π API documentation
  -
  β― Demo
π Overview
The v3.33.4 is a "legacy" release (now that the v4 is the current major version) mostly containing some of the bug fixes and improvements initially made for the upcoming v4.2.0 release that should be done just after this one.
π Changelog
Bug fixes
- Compat: Fix autoPlay on Tizen when the content starts on a discontinuity [#1500]
 - Work-around the "hulu issue" seen on firefox 129 and 130 (
1911283and1912238on
bugzilla) which also impacted the RxPlayer [#1544] - Fix rare cases where the active Period would not be advertised by the RxPlayer [#1534]
 - DRM/Compat: Re-create MediaKeys for each content on Philips' NETTV and 
KSTB40xx
set-top boxes [#1519, #1538] - Fix some issues that may arise on BUFFER_FULL situations [#1566]
 - Directfile/Compat: Fix 
startAt.fromLastPositionhandling on Safari when playing
directfile contents [#1574] - Consider 
stpp.ttmlcodec for text format [#1567] - DRM/Compat: Re-create MediaKeys for each content on Philips' NETTV, and 
KSTB40XX
set-top boxes [#1519, #1538] - DRM/Compat: fix content not starting on Safari because key are never considered usable
[#1535] - DASH_WASM: fix 
Labelelement never being parsed [#1543] 
Other improvements
- DASH: provide a more precize calculation for the timeshift buffer depth [#1492]
 - Handle 
hev1codec andhvc1codecs as part of the same family of codecs when trying
to check for compatibility between the two [#1536] - Better handle 
QuotaExceededErrorissue afterappendBufferMSE calls when
wantedBufferAheadis set toInfinity[#1566] - Bring prettier to the v3 [#1545]
 
v4.1.0
Release v4.1.0 (2024-07-08)
  Quick Links:
  π API documentation
  -
  β― Demo
  -
  π Migration guide from v3
- π Overview
 - π Changelog
 - DASH ContentProtection References
 MULTI_THREADfeature improvements- Better DASH URL path resolution
 - DRM: Comprehensively test DRM compatibility on Edge
 - DASH/DRM: All 
0key-id now ignored in container files - A lot of transparent large project updates
 
π Overview
We're now releasing the v4.1.0.
This release adds multiple fixes and improvements:
- 
it improves our
MULTI_THREADexperimental feature allowing to run most of the RxPlayer logic in another thread - which we're now using on the great majority of devices at Canal+. - 
This release also adds support for DASH Content Protection References, which can greatly reduce the size and thus improve parsing time of Multi-Period Manifest with complex DRM configurations.
 - 
After an issue report, we noticed that our DASH URL resolution algorithm did not handle all cases. We thus rewrote it so it completely respect the corresponding standard (the RFC 3986).
 - 
For the Edge browser, after having multiple PlayReady-specific issues, we now perform much more checks before validating the fact that PlayReady SL3000/SL2000 is available on the device. This helped to fix multiple Edge issues we were having.
 - 
Many other smaller fixes, including on the
maxVideoBufferSizeoption which was not always relying on good estimates, on better handling contents with mixed encryption and multiple fixes of minor compatibility issues (mainly on the PlayStation 4 and 5, and on Safari) 
π Changelog
Features
- DASH: Implement 
ContentProtectionreferences [#1439] 
Bug fixes
- DASH: support absolute path in URL resolution with RFC 3986 implementation [#1443, #1440]
 - DASH: fix cases of blinking subtitles [#1416, #1424]
 - Fix precision issues of the 
maxVideoBufferSizeAPI [#1421] - DASH: Prevent multiple loading of the same segment for some DASH low-latency contents [#1422]
 - DRM/Compat: on Edge test comprehensively KeySystems before considering them as usable [#1434]
 - DRM/DASH: Ignore 
0x0key id found in DASH initialization segments are they are often linked to unencrypted data. [#1466, #1458] - DRM/Compat: On the PlayStation 5, reload directly when a decryption key become unusable to prevent fatal errors [#1399]
 - MULTI_THREAD: Perform several actions so that our 
MULTI_THREADexperimental feature now works on older browser and on the Playstation 4 [#1401, #1402] - Directfile/Compat: On safari on iOS no longer stay stuck in buffering when 
autoPlayis set tofalseor not set and the video element has the attribute "playsinline" [#1408, #1390] - Directfile/compat: On safari mobile in directfile mode, do not stay in an infinite  
LOADINGstate if thedurationis set toNaN(rare issue in a normally-unsupported multiple RxPlayer-per-media-element scenario) [#1393] - Fix RxPlay error messages not properly displaying in Chrome's inspector since Chrome 126 [#1474]
 
Other improvements
- Signal an error if multiple active RxPlayer are linked to the same media element [#1394]
 - Undetermined audio and text track language now have a 
normalizedproperty equal to"und"for better ISO 639-3 compatibility [#1428] - MULTI_THREAD: The experimental 
MULTI_THREADfeature does not need adashWasmUrlanymore nor compatibility to WebAssembly [#1384] - MULTI_THREAD: The 
DEBUG_ELEMENTfeature now allows to display all debug information even under the "multithreading" mode [#1438] - Generate TypeScript declaration maps [#1412]
 - Do not rely on the 
performance.nowAPI if not available [#1402] - DRM: Refactor MediaKeys attachment logic to simplify device support updates [#1357]
 - tests: use exponential backoff to speed up integration tests [#1389]
 - code: Rely on the TypeScript 
typekeyword at type imports to be sure they have no code impact on our final build [#1365] - code: Reorganize core RxPlayer code into a 
src/main_threadandsrc/corerespectively for main thread and worker code in a "multithread" mode [#1365] - code: Rely on the 
prettierandrustfmtformatting tools in the codebase [#1387] - build: remove dependency to 
webpack[#1435, #1425, #1420] - tests: migrate all tests to the 
vitestframework to simplify and unify test-related dependencies and test writing [#1444, #1445] 
DASH ContentProtection References
ContentProtection metadata leading to huge MPD
DASH MPD can get quite huge on complex contents with multiple Period elements and various decryption keys depending on the Period and Representation.
One of the bigger part of the MPD in those scenario is the <ContentProtection> element, which contains metadata related to content decryption. This element can get very big as it contains Base64-encoded binary data for various client-side key systems.

Screenshot: For encrypted contents, we can see on this screenshot that encryption-related metadata (in <ContentProtection> elements) - especially base64-encoded data - are one of the main culprit for an MPD large size.
Moreover, note that this example only advertise metadata for PlayReady and Widevine. So this example is even lighter than most actual encrypted contents we play in production.
Each DASH AdaptationSet or Representation linked to that metadata is then supposed to have this element, contributing to the MPD's size. And when the same encryption metadata repeats, for example in another Period, that same huge element has to be repeated there - leading to a very large MPD.
Thankfully, newer iterations of the DASH specification provide a solution to greatly reduce the size of those kind of MPD: ContentProtection references.
ContentProtection references
With ContentProtection referecences we can only declare once (in the MPD) encryption metadata linked to multiple AdaptationSet or Representation and then refer to it through an identifier each time it is needed.

Screenshot: The same MPD than in the first screenshot, but this time making use of ContentProtection references. Here the actual metadata could be defined on top of the MPD, and only refered to through a ref attribute as pictured. You can see that the exact same information would take less space here.
This allows to greatly reduce the size of multi-Period MPD with encrypted media whose encryption key repeats multiple times in the stream - which happens often.
This feature is directly enabled, with nothing to do on the application-side.
MULTI_THREAD feature improvements
The MULTI_THREAD feature
In the v4.0.0, we added the MULTI_THREAD feature which allows to run most of the RxPlayer's logic in a Worker, and thus in another thread.
Doing this has multiple advantages, performance-related ones, yet this isolation also has a considerable effect on the quality of our adaptive algorithms: on some low-end devices where we before observed either a lower quality or frequent transitions between multiple qualities, we're now able to better maintain a higher quality.
Removing the need to add our WebAssembly parser
The main issue with adding the MULTI_THREAD mode was its complex setup, among which the need to add our WebAssembly MPD parser, which implies WebAssembly support and thus preventing its usage on many "old" (year ~2019 and less) devices.
We've since noticed some work done on efficient JavaScript-only XML parsing whose performance was impressive. As the need for optimal XML parsing in a Worker environment was the main reason why we relied on our WebAssembly parser, we wondered if we couldn't take inspiration from this work to much simplify the MULTI_THREAD setup and increase support.
This is now done and performance has been impressive enough that we now consider that this can be the default MPD parser directly included in the worker file provided to the RxPlayer's attachWorker method.
Without this supplementary step, the feature becomes much simpler to profit from:
import RxPlayer from "rx-player/minimal";
import { MULTI_THREAD } from "rx-player/experimental/features";
// To simplify this example, we'll directly import an "embedded" version of the
// supplementary code loaded by the `MULTI_THREAD` feature.
// We could also load it on demand through an URL
import { EMBEDDED_WORKER } from "rx-player/experimental/features/embeds";
RxPlayer.addFeatures([MULTI_THREAD]);
const player = new RxPlayer(/* your usual op...v3.33.3
Release v3.33.3 (2024-07-08)
  Quick Links:
  π API documentation
  -
  β― Demo
π Overview
The v3.33.3 is a "legacy" release (now that the v4 is the current major version) mostly containing some of the bug fixes and improvements initially made for the upcoming v4.1.0 release that should be done just after this one.
π Changelog
Bug fixes
- DASH: support absolute path in URL resolution with RFC 3986 implementation [#1446]
 - DASH: fix cases of blinking subtitles [#1447]
 - Fix precision issues of the 
maxVideoBufferSizeAPI [#1448] - DASH: Prevent multiple loading of the same segment for some DASH low-latency contents [#1449]
 - Await some delay before re-attempting to push a segment following an error [#1411]
 - DRM/Compat: on Edge test comprehensively KeySystems before considering them as usable [#1450]
 - DRM/DASH: Ignore 
0x0key id found in DASH initialization segments are they are often linked to unencrypted data. [#1466, #1458] - DRM/Compat: On the PlayStation 5, reload directly when a decryption key become unusable to prevent fatal errors [#1451]
 - Directfile/Compat: On safari on iOS no longer stay stuck in buffering when 
autoPlayis set tofalseor not set and the video element has the attribute "playsinline" [#1406, #1404, #1390] - Directfile/compat: On safari mobile in directfile mode, do not stay in an infinite 
LOADINGstate if thedurationis set toNaN(rare issue in a normally-unsupported multiple RxPlayer-per-media-element scenario) [#1452] - Fix RxPlay error messages not properly displaying in Chrome's inspector since Chrome 126 [#1474]
 
Other improvements
v4.0.0
Release v4.0.0 (2024-02-21)
  Quick Links:
  π API documentation
  -
  β― Demo
  -
  π Migration guide from v3
- π Overview
 - π Changelog
 - About the v3
 - A more flexible track API
 - Improved Representation selection
 - The new 
MULTI_THREADexperimental feature - More expressive decryption options
 - A new player state: 
"FREEZING" 
π Overview
It's finally time for the official v4.0.0 release with the v4 now becoming our default focus and the default major version when installing the RxPlayer through package managers relying on the npm registry (npm / yarn / pnpm etc.).
If you relied on the 4.0.0-rc.2 before, this release is a quasi-exact copy of that version, with only a minor fix for the representationListUpdate event - which was previously never triggered.
Because previous v4 beta and release candidate release notes already listed the new features available in v4 in comparison to v3, this release note will only summarize v4 features we consider to be the most important. They already all have been presented in one of the previous release notes.
To migrate from a v3 RxPlayer to a v4 one, you can rely on our migration guide, which lists every API that changed in that major version.
π Changelog
We decided to compile the full v4 changelog into one (instead of splitting and associating it to the various beta and release candidates they have been initially available in).
This lead to an enormous changelog for the v4. To avoid polluting this release note we will just redirect you to our CHANGELOG.md file, here.
About the v3
We will mainly only add bug fixes and small improvements from now on to the now legacy v3.x.x versions so it stays stable and usable for people not having time yet to do the switch to the v4.
As such, it should still work as expected, but new features probably won't be added to it, unless you provide the contribution and test cases for it yourself through pull requests.
However, we do recommend you to switch to v4 instead, and not hesitate to open an issue if you find an API change to be unclear or undesirable for your usage.
A more flexible track API
Note: this feature was already presented in the v4.0.0-beta.0 release note.
One of the focus of this new major release was to improve the RxPlayer API on DASH multi-Period contents - which are contents with various set of AdaptationSets (tracks) and Representations (qualities) depending on the time period.
The RxPlayer's previous track API (e.g. setAudioTrack and getAvailableAudioTracks) only allowed to get the list and update the track for the currently-playing Period.
// Example setting the first english audio track for the current Period if found
const availableAudioTracks = rxPlayer.getAvailableAudioTracks();
const englishAudioTrack = availableAudioTracks.find((track) => {
  return track.language === "eng";
});
if (englishAudioTrack !== undefined) {
  rxPlayer.setAudioTrack(englishAudioTrack.id);
}Now, using the track API this way still works with the same result, but it is also possible to get and set the available tracks for any Period on the content.
// Get the list of Periods currently considered by the RxPlayer:
const availablePeriods = rxPlayer.getAvailablePeriods();
// Get the list of available audio tracks for a given period
const tracks = rxPlayer.getAvailableAudioTracks(availablePeriods[0].id);
// Set an audio track for that Period
rxPlayer.setAudioTrack({
  trackId: tracks[0].id,
  periodId: availablePeriods[0].id,
});The new tracks API also let you to choose a behavior when switching from an old to any new track (e.g.: reloading, switching in place with a potential rebuffering or seamlessly) through a new switchingMode property and also allow to rewind a little (and let you set by how much) in cases where you want to give back some context (for example when switching the audio track to another language).
Last but not least, it is also possible to restrict the Representations (a.k.a. qualities) played under that new track, this will be described in the next chapter.
Some of those features have been described in our "Selecting a Track" tutorial. To have complete informations, you can also refer to our API documentation
Improved Representation selection
Note: this feature was already presented in the v4.0.0-beta.0 release note.
Previous RxPlayer versions only allowed to specify allowed Representation(s) (i.e. qualities) by using bitrate-oriented API.
For example you could call setVideoBitrate, setMaxVideoBitrate and setMinVideoBitrate to either choose a Representation (the first one) or to reduce the ranges of Representations to choose from (the latter two).
In real-life, you might instead want to select Representation(s) based on other criterias. In some more complex use cases, you might only want to allow Representations with a specific codec property. Both of those were not always possible with the previous API.
We chose to remediate to those issues in the v4 by providing a new API for Representation selection: the "Representation locking" family of API.
For example, the lockVideoRepresentations method allows to select which Representation for the current video track are allowed to play, the regular RxPlayer's adaptive logic then picking its choice between them, as usual. To lock a single Representation in place, you can just communicate a single Representation's id to that method:
// Example only playing the Representation with the lowest height in the
// current video track
const videoTrack = rxPlayer.getVideoTrack();
if (videoTrack !== null && videoTrack !== undefined) {
  const lowestHeight = videoTrack.representations.sort((a, b) => {
    // Put `undefined` heights at the end of the resulting array
    if (a.height === undefined) {
          return 1; // Put `a` after `b`
    } else if (b.height === undefined) {
      return -1; // Put `b` after `a`
    }
    // Sort ascending
    return a.height - b.height; // Put the higher height after
  })[0]; // Select the lowest one
  if (lowestHeight !== undefined) {
    // Only play the lowest anounced height
    rxPlayer.lockVideoRepresentations([lowestHeight.id]);
  }
}There is a lot more to know on this API, see the lockVideoRepresentations / lockAudioRepresentations documentation page to see all that is can do.
We rely on this new API to display a better quality selection in our demo page for example:

Screenshot: our new demo page now allows a user to select a video quality based on its height and/or the wanted bitrate, thanks to this new API.
We also chose to remove the previous bitrate-related API to simplify the general API of the RxPlayer, considering that its behavior can be completely replaced by the new "Representation locking" methods.
Information on how to make the switch is present in its own page in our migration guide
The new MULTI_THREAD experimental feature
Note: this feature was already presented in the v4.0.0-rc.1 release note.
This major release also brings the possibility of running most of the RxPlayer main logic in a WebWorker, letting your application to run concurrently with it. This has potentially large positive impacts on performance and adaptive streaming stability (e.g. keeping a stable high video quality).
This new behavior is totally optional and has to be enabled through specific APIs.
The RxPlayer is also able to automatically detect when multithreading is not possible (very old devices), to go back in the regular monothreading mode instead.
Running the RxPlayer without a WebWorker (the default):
+-------------------------------------------------------------------------------+
| Main thread (also running the UI)                                             |
|                                ...
v3.33.2
Release v3.33.2 (2024-02-21)
  Quick Links:
  π API documentation
  -
  β― Demo
NOTE: we skipped the v3.33.1 release due to a minor TypeScript typing issue seen when testing that release. This is now fixed.
π Overview
This release only brings minor bug fixes on top of the v3.33.0, none being regressions (those issues have been here since the corresponding features have been introduced).
This reassure us that the v3 is stable enough for it to be reliable for people not having the time yet to make the switch to a v4, as we plan to release the official v4.0.0 just after this release.
The v3 major releases should still be maintained and receive bug fixes for some time if we find them, but our main focus will now go to the v4 releases. Note that all future v3 releases will have the legacy-v3 tag on npm.
π Changelog
Bug fixes
- dash: Don't unnecessarily reload external 
<UTCTiming>resources at each refresh if it failed for the first request of the Manifest [#1370] - dash: The 
DASH_WASMfeature do not rely on WebAssembly's sign-extension operators anymore as that is poorly supported on older Samsung and LG TVs [#1372]