v3.30.0
Release v3.30.0 (2023-03-07)
- π Overview
- π Changelog
- Forced subtitles
updateContentUrls
API- For encrypted contents:
getKeySystemConfiguration
API - An experimental debug element
- DASH
endNumber
attribute handling - API deprecation
- No dependency on RxJS in the RxPlayer source code anymore
π Overview
The v3.30.0
release is, at last, available!
It's a relatively big release which took a long time to test and finish, mainly because it internally completely removes our dependency on the RxJS library. This is the end of a long time effort started with the v3.26.1
(2021-09-14), whose goal is mainly to improve the approachability of the code and the debugging experience.
Note that the v4.0.0-beta.0
pre-release already included an early version of many features introduced here, so you might already know some of them. On that matter, we will release soon after this release a v4.0.0-beta.1
which re-implements future v4 features on top of this release.
The v3.30.0
release brings:
-
A new
updateContentUrls
method allowing to change the Manifest's URL, as long as it represents the same content. -
"forced" narrative subtitles handling.
-
DRM: A new
getKeySystemConfiguration
API which allows to obtain the complete key system configuration obtained from the browser -
DASH: The
SegmentTemplate@endNumber
attribute is now handled -
A new
createDebugElement
experimental API (behind the new"DEBUG_ELEMENT"
experimental feature) was added, allowing to show debugging information. -
Panasonic 2019 TVs are now properly supported. We had some issues before with content with DRMs
-
LG TV: Contents with DRM are now also better supported
-
A new
BUFFER_FULL_ERROR
avoiding mechanism, trying to limit some of such (rare) errors seen in the wild
π Changelog
Features
- Add
updateContentUrls
API, allowing to update the Manifest's URL during playback [#1182] - DASH: implement forced-subtitles, adding the
forced
property to the audio tracks API and selecting by default a forced text track linked to the audio track's language if present [#1187] - DRM: add the
getKeySystemConfiguration
method to the RxPlayer [#1202] - add experimental
DEBUG_ELEMENT
feature andcreateDebugElement
method to render a default debugging HTML element [#1200]
Deprecated
- Deprecate the
getVideoLoadedTime
method which can be easily replaced (see Deprecated method documentation) - Deprecate the
getVideoPlayedTime
method which can be easily replaced (see Deprecated method documentation) - Deprecate the
transportOptions.aggressiveMode
option - DRM: Deprecate the
keySystems[].onKeyStatusesChange
callback as no good use case was found for it.
Bug fixes
- Fix segment requesting error when playing a DASH content without an url and without BaseURL elements [#1192]
- API: Stop sending events if the content is stopped due to a side-effect of one of the event handler [#1197]
- text-tracks/ttml: fix inconsistent line spacing when resizing the
textTrackElement
[#1191] - DRM: Fix race condition leading to a JS error instead of a
NO_PLAYABLE_REPRESENTATION
[#1201] - DRM/Compat: Renew MediaKeys at each
loadVideo
on all WebOS (LG TV) platforms to work around issues [#1188]
Other improvements
- DASH: better detect closed captions [#1187]
- DASH: handle
endNumber
DASH attribute [#1186] - DASH: Do not merge AdaptationSet with role "main" anymore [#1214]
- DASH: parse
transferCharacteristics
property in the MPD to better detect hdr [#1212] - Support encrypted contents on Panasonic 2019 TVs [#1226]
- Better handle SourceBuffer's QuotaExceededError, responsible for
MediaError
with theBUFFER_FULL_ERROR
code [#1221] - API: send available...TracksChange events in the very unlikely scenario where tracks are added after a manifest update [#1197]
- Completely remove RxJS dependency from the RxPlayer's source code [#1193]
- DRM: Request PR recommendation when PlayReady is asked and try default recommendation robustnesses [#1189]
Forced subtitles
Note: this feature was first presented in the v4.0.0-beta.0
beta release
Forced subtitles, also referred as forced narrative or just narrative subtitles are subtitles which are meant to be displayed by default when no other subtitle track is selected.
They allow to clarify audio or visual cues that might not be clear for the user, by providing text translation to:
- clarification of audio when it is not clearly audible (for example due to a strong accent or due to distorted audio)
- foreign - or even sometimes invented (e.g. Klingon) - languages spoke in films
- other types of communication which might not be easily understood (a frequent example would be sign language)
- text in foreign languages present on the video track
Screenshot: french forced narrative subtitles translating what the character is saying. The spoken language here is Klingon which few people know how to speak (besides Klingons of course - and yes, I just repeated the same joke on both release notes).
In previous RxPlayer versions, forced subtitles were treated as any other type of text track, with no mean to identify them.
This version adds a new forced
property to text tracks described through text tracks API (the getAvailableTextTracks
and getTextTrack
methods, the availableTextTracksChangeand
textTrackChange` events) to help you identify which text track is a forced one, as you most likely don't want to list it with other regular tracks:
const textTracks = rxPlayer.getAvailableTextTracks();
const textTracksToDisplay = textTracks.filter(t => !t.forced);
Also, the RxPlayer will for now automatically select a forced text track by default (instead of no text track) if one is present for the same language than the default audio track chosen - unless text tracks are explicitely disabled, for example by setting null
in the preferredTextTracks
.
This means that - if you're using forced narrative subtitles - you might want to be careful if switching the audio track to also switch the text track if a forced one exist in that new language or if the old one is not adapted anymore.
updateContentUrls
API
Note: this feature was first presented in the v4.0.0-beta.0
beta release
Some applications recently introduced us to a new need: being able to change the Manifest's URL while the content is playing.
The URL would represent the same content, it's here just a change of URL in itself that is wanted. For example, a usage would be to switch from an overloaded CDN during playback or to change a token present in the URL.
The v3.30.0
gives an answer to these needs by introducing a new method: updateContentUrls
.
It allows to update the URL(s) of the Manifest, and even to trigger a manifest refresh directly, through a simple call:
rxPlayer.updateContentUrls([newUrl], {
// trigger the refresh immediately
refresh: true,
});
As usual it has been properly documented in its own documentation page.
For encrypted contents: getKeySystemConfiguration
API
Note: this feature was first presented in the v4.0.0-beta.0
beta release
Encryption-related issues are the most frequent category of issues currently investigated by the RxPlayer team and its associated applications at least made by Canal+ and our partners.
In that context, we missed a crucial API allowing to facilitate encryption-related debugging on various platforms: One that would allow to indicate easily the current key system configuration relied on.
Particularly the robustness level: PlayReady SL3000 or SL2000? Widevine L1, L2 or L3? And so on.
That's why this release adds the getKeySystemConfiguration
API which returns both the actual key system string and the
MediaKeySystemConfiguration
currently relied on.
I put there an emphasis on "actual" because, in opposition to the getCurrentKeySystem
API, which is now removed, it is the name actually reported by the MediaKeySystemAccess that is here reported, whereas getCurrentKeySystem
returned the exact same string than the type
originally set on the keySystems
option - an arguably less useful value when the RxPlayer could have made translations in between.
An experimental debug element
Applications relying on the RxPlayer often include a special element displaying various playback-related metrics, used for debugging.
That debugging element generally depended on RxPlayer API as well as on attributes of the media element.
The fact that it was entirely constructed by the application allowed it to fully personalize its aspect and even sometimes to better bind its content to mechanisms like log collecting or other back-ends.
However, we lastly found out that applications could also profit from relying on a debug element fully designed inside the RxPlayer. One of the major advantage is to have access to metrics that are not exposed by the RxPlayer API - and is not planned to be - like the content of the audio, video and text buffers.
It also allows to have a common debugging template, which can have the effect of facilitating debugging on several applications which rely on the RxPlayer.
Screenshot: Aspect of the debug element on top of the video element.
At Canal+, we're now testing its integration on applications (for example, it could be made accessible behind some contextual menu) to help people testing streams and/or the application realize what's going on under the hood on the RxPlayer during playback.
Note that debugging element is totally optional and won't be in an RxPlayer build unless explicitely imported. It is for now also only defined as an "experimental" feature, meaning that its API may change from release to release, or that the feature may even disappear if noone seems to be using it.
How to rely on this feature has been fully documented in a new debugging element documentation page.
DASH endNumber
attribute handling
Note: this feature was first presented in the v4.0.0-beta.0
beta release
The RxPlayer handled the DASH MPD's startNumber
attribute around the time it added DASH support, which allowed to properly handle the huge majority of "Number-based" DASH MPD <SegmentTemplate>
elements.
For example, let's consider the following MPD:
The MPD in this screenshot indicates that for a time period going from the second 0
to the second 51
(respectively the attributes start
and duration
from the <Period>
element), we have a number-based segment requesting scheme ($Number$
in the media
property of the <SegmentTemplate>
element). Each segment represents 10 seconds of media content (duration
attribute, after dividing it by the timescale
one) with the exception of maybe the last one which may be shorter, as usual.
Here, we can also see that the first segment holds the number 1
(startNumber
attribute) .
Based on all of this, the RxPlayer deduces that there are 6 segments, from the one holding the number 1
to one holding the number 6
:
- The first, holding the number
1
, from 0s to 10s - The second, number
2
, from 10s to 20s - from 20s to 30s
- from 30s to 40s
- from 40s to 50s
- from 50s to 51s (the end of the
<Period>
element)
However, it turns out that some contents do not provide all those assumed segments. For a concrete example, in our current scenario the 6th segment (the 1 second one) may not actually exist. In some other cases, we could even have the actual last segment's end at 45s for example - in the middle of the fifth segment - with no media data from that point on to the end of the Period.
When encountering those exceptions, the RxPlayer would previously still try to request the 6th segment multiple times, following the retry rules communicated through its API.
However, we found out that a endNumber
attribute existed in the DASH specification (though it isn't yet in the generally more adopted DASH-IF IOPs). This attribute allows the MPD to communicate to the player the number of the last segment to request.
Taking the previous example, an MPD might indicate that there's only 5 segments to request instead by adding an endNumber
attribute to 5
, like this:
This is now automatically handled by the RxPlayer.
API Deprecation
To facilitate transition to the future v4.0.0, some API which should be unneeded have been deprecated:
- The
getVideoLoadedTime
method: code to replace it can be seen here. - The
getVideoPlayedTime
method: code to replace it can be seen here. - The
transportOptions.aggressiveMode
loadVideo
option: it has always been a difficult-to-maintain hack and is now planned to be removed without replacement - The
keySystems[].onKeyStatusesChange
loadVideo
option: we know of no legitimate use-cases for that API for now, please open an issue if you have one.
No dependency on RxJS in the RxPlayer source code anymore
Note: this "improvement" was first presented in the v4.0.0-beta.0
beta release
This is the end of an era for the RxPlayer's source code.
The RxPlayer previously depended heavily on RxJS, inspiring even its name, for most aspects where asynchronicity and/or message passing is wanted.
This library helped us greatly in building a complex media player with advanced features but it progressively appeared that its abstractions and specificities were also needlessly complexifying our code, making its maintenance more difficult, but also many times creating hard-to-debug issues.
This is not an attack on the RxJS library which is a fantastic piece of work both on the theoretical and on the practical side, but more of a realization that newer RxPlayer versions started to be big enough and complex enough that the opportunity cost of RxJS appeared not worthwile anymore: alternatives started to looked better due to the RxPlayer's evolution.
We're now both using more usual JavaScript abstractions, like Promises and Event Emitters when it is sufficient and our own abstractions, simpler than RxJS Observables (like the AbortController
-like TaskCanceller
, allowing to cancel asynchronous tasks, and "Shared references", allowing to share and observe a values at several places), only when needed.
And because it's a recurrent question, yes, we for now decided to keep the name!
As for the impact of this removal for applications, it should be relatively minimal. You should in result see better call stacks when debugging issues and it fixes some minor issues, such as unnecessary warnings when using the create-react-app
tool to build your application, or uncaught errors displaying in the console in some situations.