Skip to content

v4.0.0

Latest
Compare
Choose a tag to compare
@peaBerberian peaBerberian released this 21 Feb 15:47

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)                                             |
|                                                                               |
| +------------------+     +----------------------+    +----------------------+ |
| |    Application   | --> |  RxPlayer Main [1]   | -> |   RxPlayer Core [2]  | |
| +------------------+     +----------------------+    +----------------------+ |
+-------------------------------------------------------------------------------+

Running with a WebWorker:

+----------------------------------------------------+
| Main thread (also running the UI)                  |
|                                                    |
| +------------------+      +----------------------+ |
| |    Application   | ---> |  RxPlayer Main [1]   | |
| +------------------+      +----------------------+ |
+--------------------------------------|-------------+
                                       | (messages)
+--------------------------------------|-------------+
| WebWorker                            V             |
|                           +----------------------+ |
|                           |  RxPlayer Core [2]   | |
|                           +----------------------+ |
+----------------------------------------------------+


[1] RxPlayer Main: Exposes an API to the application, performs some high-level
media monitoring, handles content decryption, displays text tracks and interacts
with web API that are only usable in the main thread.

[2] RxPlayer Core; Loads and parses the Manifest as well as media segments that
will be be played. Also monitors what's being played and will be played to
ensure a smooth playback.

Schema: Here is some high level schema of how the RxPlayer would roughly work without and with a WebWorker.

There's many things to say about this new feature and we encourage you to check if it improves the experience on your application.
Everything should be detailed in its API documentation, here.

More expressive decryption options

Note: this feature was already presented in the v4.0.0-beta.0 release note.

We added and updated several decryption-related options, allowing to be more flexible in expressing how to play encrypted contents.

onKeyOutputRestricted / onKeyInternalError

Two string properties imitating the already there onKeyExpiration API have been added:

  • onKeyOutputRestricted: allows to indicate the behavior the RxPlayer should have when encountering the "output-restricted"
    MediaKeyStatus, like fallbacking to another quality or stopping with an error (the default)

  • onKeyInternalError: allows to indicate the behavior the RxPlayer should have when encountering the "internal-error "
    MediaKeyStatus, like here also fallbacking to another quality or stopping with an error (the default)

Because it allows more powerful configuration than the previous fallbackOn option, the latter has been removed.

persistentState / distinctiveIdentifier

The v4.0.0 major release adds two string properties to the keySystems option of loadVideo:

Because, they allow the easy replacement of respectively the persistentStateRequired and of the distinctiveIdentifierRequired boolean properties of keySystems, both of those have been removed.

videoCapabilitiesConfig / audioCapabilitiesConfig

Two keySystems properties videoCapabilitiesConfig and audioCapabilitiesConfig now allow to configure respectively the videoCapabilities and audioCapabilities properties of the asked MediaKeySystemConfiguration.

Relatively powerful, this option allows to configure the asked codecs, robustnesses or both.
Like the other ones presented here, this option provokes the removal of the less powerful videoRobustnesses and audioRobustnesses undocumented options.

A new player state: "FREEZING"

Note: this chapter was first written for the v4.0.0-beta.0 release note.

A new player state (gettable either through the playerStateChange event or the getPlayerState method) has been added: "FREEZING".

It's important to note that this new new state does not characterize a new behavior, it only put a better word onto a specific problematic playback state. Previously, it was either reported as a "BUFFERING", "SEEKING", or even "PLAYING" state depending on the situation.

This state appears when playback is temporarily stuck in place, though in opposition to the more usual "BUFFERING" and "SEEKING" state, this is not due to buffer starvation but to another, generally unknown, factor. As such, it can in most cases be considered just like a "BUFFERING" state in your application (e.g. by displaying a spinner on top of the media element) but it may be logged differently to help you pinpoint playback issues.

buffering
Screenshot: A "FREEZING" state can be treated just like a "BUFFERING" one, here with a spinner on top of the video.

Under that state, which is generally much rarer than a "BUFFERING" state for example, the RxPlayer will try various tricks to try to un-freeze playback. If they become too frequent or if those tricks don't work, it might be an issue worth investigating.