Releases: canalplus/rx-player
v4.4.1
Release v4.4.1 (2025-12-10)
Quick Links:
π API documentation
-
β― Demo
-
π Migration guide from v3
π Overview
This is a very small patch release we're doing because of a v4.4.0 regression that seemed to impact some applications in various ways.
We did not include new features to ensure this patch release is as stable as possible.
Changelog
Bug fixes
- Fix v4.4.0 regression where the RxPlayer might base itself on the previous content's position [#1758]
- Add resilience to DRM fallback when position is not yet known instead of triggering
MEDIA_TIME_NOT_FOUNDerror [#1755]
Issue when loading several contents without stopping
The v4.4.0 regression this release fixes, brought with the ability of seeking while the RxPlayer hasn't yet loaded the content, led to an internal RxPlayer issue where for a very brief chunk of time it relied on the position from a potential previous content while running its logic for a new content.
Yet because we've built the RxPlayer to be resilient, that issue did not have any effect for most applications.
After a few weeks, one of canal+ application started seeing MEDIA_TIME_NOT_FOUND errors only in multithreaded scenarios and only under a set of time-related conditions. We saw the issue, brought a fix, but thought that it was sufficiently rare, only under the "experimental" MULTI_THREAD feature and had many work-arounds (stopping a content between loads, disabling the MediaKeySession cache etc.) so we thought the impact was limited.
Yet last week, another application had an "infinite loading" issue, linked to the same root cause.
Note that in any case, calling stop before calling loadVideo again totally fixes the issue (as our internal position tracking is reset when a content is stopped).
Anyway, we decided to release the fix in its own patch release on top of v4.4.0 so it can just work as expected under the more efficient strategy of calling loadVideo without stopping first.
We also added resilience to our handling of a position that seems not-right to avoid seeing MEDIA_TIME_NOT_FOUND errors even in similar future scenarios, handling minor, recoverable, state discrepancies gracefully instead.
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) |
| ...