Skip to content

Releases: canalplus/rx-player

v4.4.0

25 Sep 19:16
v4.4.0

Choose a tag to compare

Release v4.4.0 (2025-09-25)

Quick Links:
πŸ“– API documentation - ⏯ Demo - πŸŽ“ Migration guide from v3

πŸ” Overview

The v4.4.0 is here, with many new features and improvements:

  • new onAudioTracksNotPlayable and onVideoTracksNotPlayable loadVideo options to allow playback even if no audio or video tracks are supported on the current content.

  • A new disableAudioTrack API, to complement the existing disableVideoTrack and disableTextTrack APIs and give you control over all media track types

  • seekTo can now be relied on even when still LOADING / RELOADING, to correct a future playback position.

  • A new getWallClockOffset API to facilitate conversions between the RxPlayer's position and the "wallClockTime" that is generally more useful for live contents.

  • EncryptedMediaError errors, which are those linked to content decryption, now will also communicate context when possible, such as the corresponding key system name and configuration.

  • Add MediaError with 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 new forcedSubtitles property

  • The experimental MediaCapabilitiesProber tool 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 onAudioTracksNotPlayable and onVideoTracksNotPlayable loadVideo options to control whether to continue playback is one of those components is not compatible to the current device [#1624]
  • Add getWallClockOffset API to obtain a "live position"'s offset [#1601]
  • add disableAudioTrack API [#1715]
  • DRM: Add keySystem and keySystemConfiguration to most EncryptedMediaError so an application can determine which key system caused an issue [#1690]
  • Update API of the experimental mediaCapabilitiesProber API 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 seekTo even while LOADING or RELOADING the content [#1607]
  • local: local-manifests now can have a forcedSubtitles property in an adaptations object, 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]
  • representation object 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_MANIFEST or MEDIA_TIME_AFTER_MANIFEST events [#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 / AbortController is 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....

Read more

v3.33.6

25 Sep 19:15
6089f01

Choose a tag to compare

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

01 Apr 16:06
cd7e0f0

Choose a tag to compare

Release v4.3.0 (2025-04-01)

Quick Links:
πŸ“– API documentation - ⏯ Demo - πŸŽ“ Migration guide from v3

πŸ” 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 ManagedMediaSource API (the MSE variant found on iOS devices), along with its startstreaming / endstreaming events, 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[].wantedSessionTypes loadVideo option 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_THREAD experimental 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 WebSocket are 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 ManagedMediaSource on iOS devices [#1562]
  • DASH: Implement DASH Thumbnail tracks by adding renderThumbnail and getAvailableThumbnailTracks API [#1496]
  • DRM: Add keySystems[].wantedSessionTypes loadVideo option to also initialize a DRM config for future contents, not just the current one [#1604]
  • Add experimentalOptions.enableRepresentationAvoidance option to loadVideo to enable our new Representation avoidance mechanism [#1523]

Bug fixes

  • Tracks API do not return unplayable representations by default [#1599]
  • MULTI_THREAD: Fix onmessageerror being 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 MediaKeys reusage on some devices including desktop browsers [#1615]
  • DRM: Only ask for "persistent-license" MediaKeySession (and not also for "temporary" license) when only a keySystems[].persistentLicenseConfig is communicated [#1604]
  • DRM: Fix reusage of some keySystems[] option changing when reusing a MediaKeySystemAccess with a different keySystems[] configuration [#1616]
  • DRM: Fix KEY_UPDATE_ERROR which was mistakenly inheriting the code KEY_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 newAvailablePeriods event [#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 MediaKeySystemAccess if none is more wanted for the current content [#1591]
  • MULTI_THREAD: Some LOADING and RELOADING attempts may have taken more time than necessary due to a wrong "initial Period prediction", this is fixed [#1628]
  • Improve FREEZING work-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 hdr information to video Representation [#1583]
  • Set LogFormat to full on RxPlayer's debug mode [#1625]
  • Avoid error log when stopping a stream with a pending BufferGarbageCollector buffer 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.

thumbnail example
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.

bif
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.

![Screenshot from 2025-03-31 16-53-43](https://github.com/user-att...

Read more

v3.33.5

01 Apr 16:06
f6faa8d

Choose a tag to compare

Release v3.33.5 (2025-04-01)

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 MediaKeys reusage on some devices including desktop
    browsers [#1679]
  • DRM: Only ask for "persistent-license" MediaKeySession (and not also for
    "temporary" license) when the keySystems[].persistentLicense option is set to true
  • DRM: Fix reusage of some keySystems[] option changing when reusing a
    MediaKeySystemAccess with a different keySystems[] configuration [#1678]
  • DRM: Fix KEY_UPDATE_ERROR which was mistakenly inheriting the code KEY_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
    newAvailablePeriods event [#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 MediaKeySystemAccess if 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 hdr information to video Representation [#1671]
  • Avoid error log when stopping a stream with a pending BufferGarbageCollector buffer
    removal [#1685]

v4.2.0

17 Oct 13:17
419d66a

Choose a tag to compare

Release v4.2.0 (2024-10-17)

Quick Links:
πŸ“– API documentation - ⏯ Demo - πŸŽ“ Migration guide from v3

πŸ” 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 filterPlayableRepresentations option 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 contentProtections property to Representations returned by the API to let applications know which Representations are encrypted and what their key id are.

  • We added the checkManifestIntegrity option, 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 directfile transport) and having a system language different than the playlist's default language.

  • We added the LogFormat static property to produce more informative logs.

  • Many other fixes, including some for the experimental MULTI_THREAD feature, some for the DASH_WASM feature, for a short-lived firefox issue, for legacy bundles...

Changelog

Features

  • Add cmcd object to loadVideo options to enable CMCD (Common Media Client Data) [#1461, #1518]
  • Add checkManifestIntegrity loadVideo option as a temporary work-around when you suspect your packager or CDN to sometimes deliver corrupted data [#1471]
  • Add contentProtections to the representations of the tracks API to know if they're considered encrypted [#1505]
  • Add filterPlayableRepresentations property to audio and video tracks API to get information on ALL representations, even those that won't be played [#1501]
  • Add LogFormat static property to the RxPlayer to 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 (1911283 and 1912238 on 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_ERROR when QuotaExceededError mitigations after appendBuffer MSE calls don't work #1546
  • Fix issues when handling a QuotaExceededError after an appendBuffer MSE call [#1546, #1559]
  • Directfile/Compat: Fix startAt.fromLastPosition handling on Safari when playing directfile contents [#1548]
  • DRM/Compat: Re-create MediaKeys for each content on Philips' NETTV, and KSTB40XX set-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 Label element never being parsed [#1541, #1540]
  • Fix RxPlayer not being exposed in release bundles [#1542]
  • Consider stpp.ttml codec for text format [#1557]
  • Prevent very rare cases of infinite rebuffering after getting errors from calling the SourceBuffer.prototype.appendBuffer and SourceBuffer.prototype.remove MSE API [#1560, #1561]
  • MULTI_THREAD: Fix rare CancellationError error 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 hev1 codec and hvc1 codecs as part of the same family of codecs when trying to check for compatibility between the two [#1499]
  • Better handle QuotaExceededError issue after appendBuffer MSE calls when wantedBufferAhead is set to Infinity [#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.

cmcd
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:

Read more

v3.33.4

17 Oct 13:09
f9be414

Choose a tag to compare

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 (1911283 and 1912238 on
    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.fromLastPosition handling on Safari when playing
    directfile contents [#1574]
  • Consider stpp.ttml codec 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 Label element never being parsed [#1543]

Other improvements

  • DASH: provide a more precize calculation for the timeshift buffer depth [#1492]
  • Handle hev1 codec and hvc1 codecs as part of the same family of codecs when trying
    to check for compatibility between the two [#1536]
  • Better handle QuotaExceededError issue after appendBuffer MSE calls when
    wantedBufferAhead is set to Infinity [#1566]
  • Bring prettier to the v3 [#1545]

v4.1.0

08 Jul 17:23
74b603a

Choose a tag to compare

Release v4.1.0 (2024-07-08)

Quick Links:
πŸ“– API documentation - ⏯ Demo - πŸŽ“ Migration guide from v3

πŸ” Overview

We're now releasing the v4.1.0.
This release adds multiple fixes and improvements:

  • it improves our MULTI_THREAD experimental 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 maxVideoBufferSize option 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 ContentProtection references [#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 maxVideoBufferSize API [#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 0x0 key 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_THREAD experimental 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 autoPlay is set to false or 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 LOADING state if the duration is set to NaN (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 normalized property equal to "und" for better ISO 639-3 compatibility [#1428]
  • MULTI_THREAD: The experimental MULTI_THREAD feature does not need a dashWasmUrl anymore nor compatibility to WebAssembly [#1384]
  • MULTI_THREAD: The DEBUG_ELEMENT feature now allows to display all debug information even under the "multithreading" mode [#1438]
  • Generate TypeScript declaration maps [#1412]
  • Do not rely on the performance.now API 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 type keyword 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_thread and src/core respectively for main thread and worker code in a "multithread" mode [#1365]
  • code: Rely on the prettier and rustfmt formatting tools in the codebase [#1387]
  • build: remove dependency to webpack [#1435, #1425, #1420]
  • tests: migrate all tests to the vitest framework 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.

protscreen1
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.

protscreen2
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...
Read more

v3.33.3

08 Jul 17:02

Choose a tag to compare

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 maxVideoBufferSize API [#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 0x0 key 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 autoPlay is set to false or 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 LOADING state if the duration is set to NaN (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

  • Signal an error if multiple active RxPlayer are linked to the same media element [#1453]
  • Undetermined audio and text track language now have a normalized property equal to "und" for better ISO 639-3 compatibility [#1454]

v4.0.0

21 Feb 15:47

Choose a tag to compare

Release v4.0.0 (2024-02-21)

Quick Links:
πŸ“– API documentation - ⏯ Demo - πŸŽ“ Migration guide from v3

πŸ” 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:

new-bitrate-choice
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)                                             |
|                                ...
Read more

v3.33.2

21 Feb 15:33

Choose a tag to compare

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_WASM feature do not rely on WebAssembly's sign-extension operators anymore as that is poorly supported on older Samsung and LG TVs [#1372]

Other improvements

  • build: automatically install Rust and WASM toolchain locally if unavailable when building the RxPlayer WebAssembly file
  • doc: Update our documentation generator and fix all invalid anchors in it
  • npm: prevent the publishing of unnecessary files on the npm registry [#1377, #1378]