Skip to content

v3.30.0

Compare
Choose a tag to compare
@peaBerberian peaBerberian released this 07 Mar 16:39
ebd1266

Release v3.30.0 (2023-03-07)

πŸ” 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 and createDebugElement 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 the BUFFER_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

klingon
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 availableTextTracksChangeandtextTrackChange` 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.

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

template-number2

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:

  1. The first, holding the number 1, from 0s to 10s
  2. The second, number 2, from 10s to 20s
  3. from 20s to 30s
  4. from 30s to 40s
  5. from 40s to 50s
  6. 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:

template-number-endnumber2

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.