Skip to content

v3.22.0

Compare
Choose a tag to compare
@peaBerberian peaBerberian released this 17 Nov 19:12
5ccb21f

Release v3.22.0 (2020-11-17)

Overview

This release adds multiple features and improvements:

  • add an audioTrackSwitchingMode property to loadVideo to select the RxPlayer's behavior when switching the audio track (to choose between smoothness or instantaneity)
  • add the initialManifest loadVideo option to avoid loading the Manifest when not necessary
  • add an enableFastSwitching loadVideo option to enable or disable optimizations doing segment replacement in the browser's buffer
  • the TextTrackRenderer tool is not experimental anymore. It can be used without fearing that its API will change
  • A new version of the experimental local Manifest which allows much more advanced behavior, such as playing a content which is still downloading.
  • A fix for an issue which made it impossible to play encrypted contents when in directfile mode
  • saner defaults for TTML subtitles (white, centered text)

audioTrackSwitchingMode: behavior when switching between audio tracks

Until now when switching to a different audio track, the RxPlayer tried to make the transition as smooth as possible.

It doesn't interrupt playback of the old track, but load in parallel the new track and once done, replace the old by the new - most of the time without needing to pause playback.
Because this means that the user would still play in the old track for some time, a time limit (now of 2.5 seconds) is set from the point when the user chose a different track. If he/she has played until that limit, the player will enter a BUFFERING phase until the new track is available.

This behavior allows a very smooth experience but has two drawbacks:

  1. It means that the switch won't happen right away.
    For example when switching between languages, you might prefer to interrupt the track in the previous language to play the right one at the same position you were in when you switched, even if it means interrupting playback for a while.

  2. On some peculiar devices, multiple issues could arise when replacing those tracks smoothly. Sometimes it is not taken into account, sometime it doesn't even work.
    Note that we're not speaking of the usual web targets here but only of a minority of embedded devices.

Thus, we now let the possibility to adopt different strategies depending on how the audioTrackSwitchingMode API is set:

  • Either, "seamless", which is the default behavior, where the transition will appear smooth and will not interrupt playback but could take time to be effective.
  • Or, "direct", it will be much more instantaneous but it is possible that the player will go in "RELOADING" state in the meantime and so, may interrupt playback during a brief time.
    Note that we try to avoid going into the "RELOADING" state. We only do it when it is really necessary.

This property is a loadVideo option documented here.

For example to go into a more "direct" track switching, you can do:

rxPlayer.loadVideo({
  // ...
  audioTrackSwitchingMode: "direct",
});

initialManifest: provide the Manifest file if already downloaded

At Canal+, we encountered situations where the application calling the RxPlayer needed to process data from the Manifest before loading a video.

As such, the Manifest would be loaded twice. Once by the application beforehand and then by the RxPlayer.
This mean that we would perform an unnecessary request which would be both a waste of time and resources.

To load faster when the Manifest is already available, we consequently just added the initialManifest option to the transportOptions of loadVideo:

rxPlayer.loadVideo({
  // ...
  transportOptions: {
    initialManifest: myManifest,
    // ...
  }
});

As using it has some implications for live contents, we advise to first read the corresponding API documentation, in the transportOptions before using it.

enableFastSwitching: avoid segment replacement on some targets

The RxPlayer always try to play the best possible quality by default.

For example, when you begin to play a content at a low quality (because of poor bandwidth or because this is the initial content) but the bandwidth indicates that we can now download segments of a much higher quality, the player will try to directly replace the low-quality segments it has in its buffer by the higher quality segments it can download.

This lead to a much faster visible change in quality than if the player only loaded and pushed segments coming after those already loaded.

This optimization - replacing low-quality segments with higher quality-segments for raising faster in quality - has been integrated in the player for multiple years, but was given a name only recently: "fast-switching" (name admittedly taken from another player, dash.js as they developped a similar optimization).

By default, "fast-switching" is enabled and has been for a long time. But it's now possible to disable it through a new loadVideo option: enableFastSwitching.
By setting it to false, the player will just push new segments at the end of the buffer, regardless of the quality they are in.

The main reason you would want to disable that feature, and the main reason behind making that option configurable, is that some specific environments react very poorly when segments already in the buffer are replaced.
For example, we noted that some rare environments do not consider the new segments (making that optimization useless). We also worked recently on an environment which reacted very poorly to this optimization, leading sometimes to the video "freezing".
This was for a very specific environment which was still in heavy development and they since fixed that issue, but it was the main trigger behind making this behavior configurable, as anyone could encounter the same situation on a new device.

So you should probably not put it to false (even if there's no problem in doing so beside slower change in quality) but it can be useful when you know what you're doing.
You can consider this as an "expert" option!

This option is documented here.
It is set to true by default. To disable fast-switching, you can thus do:

rxPlayer.loadVideo({
  // ...
  enableFastSwitching: false,
})

The TextTrackRenderer is not experimental anymore

The TextTrackRenderer tool, which was added in the v3.18.0 version of the RxPlayer, allows to show any subtitles in the supported formats on top of a media element (it both parses and synchronizes them), even when the content is not played through the RxPlayer.

Until now, the API was marked as "experimental" which meant that its API could change at any time.

It now has a stable API, meaning it's not experimental anymore!

Note that if you already used it, you now have an action on your side to be compatible to the v3.22.0.
When before you imported the TextTrackRenderer as such:

import TextTrackRenderer, {
  TTML_PARSER,
  VTT_PARSER,
  SRT_PARSER,
  SAMI_PARSER,
} from "rx-player/experimental/tools/TextTrackRenderer";

You now have to get rid of the /experimental tp instead write:

import TextTrackRenderer, {
  TTML_PARSER,
  VTT_PARSER,
  SRT_PARSER,
  SAMI_PARSER,
} from "rx-player/tools/TextTrackRenderer";

As usual, its API documentation is available here.

Default TTML style

We encountered an issue where a user of the RxPlayer library basically told us that we badly formatted TTML subtitles, he couldn't read them well as they were in a black color and they were displayed on the top left of the screen.

After some investigations, we found out that we had no big problem with TTML formatting but that the real issue is that we do not make styling decisions if no style is present in the TTML file itself (and generally, when you are using TTML subtitles, the style is included!).
This means that by default, only the already-present styles of the concerned HTML elements are considered.
On most cases, this means black and on the top left of the screen!

Resolving that issue was not straightforward, because no default style seems to be defined in the TTML specification.
So we weren't sure of what to do here.

After looking at what other players were doing and at what the most sensible thing to do in that situation would be, we now consider that if no style at all is declared in a TTML file, we should apply a default style at its place.
Therefore, if no styles are defined for regions in the TTML, but other styles are (e.g. on HTML elements), we decide not to apply the default style. Indeed, we consider the style to have been defined on purpose, and we may interfere with the overall look of the cue if we apply a different style.

That default style objective is to display text cues in the clearer and cleaner possible way: at the bottom, centered and with white text

serverCertificate optimizations

The serverCertificate property of the keySystems option (in loadVideo) allows to communicate a server certificate.
This is DRM-specific data usually needed to encrypt message between a Content Decryption Module (or CDM) and a license server.

It appears that setting that certificate can take some time: up to 1 second on some embedded devices.
We thus decided to allow a new optimization: when we know a serverCertificate is already set (into the element it has to be set to, called MediaKeys), we do not try to re-set it.
This can lead to big improvements on some devices.

Moreover, while testing that new behavior, we noticed that for some CDMs (at least for a widevine CDM on Chrome + Firefox on linux), only a single server certificate can be set on a given MediaKeys. Once it has been set, we cannot either remove it, nor replace it (if we do, we are welcolmed by an error).

Because of that, the RxPlayer now re-creates the MediaKeys after a loadVideo if one of the following conditions is met:

  • the previous MediaKeys instance had a server certificate attached but the new loadVideo call has none
  • the previous MediaKeys instance had a server certificate attached as well as the loadVideo call but they are different

v0.2 of the "local" Manifest

We added in the v3.18.0 release the possibility to play downloaded contents through the experimental (meaning its API can change at any time) "local" transport.

We worked a lot the last months with at least two implementations - one web-oriented the other more on the set-top-boxes side.
While doing so, we realized that the "local Manifest" format had some weaknesses.
Most of all, playing while finishing to download the content we are playing was poorly supported (the RxPlayer would have weird behavior when doing so).

We thus decided to define a new version of the "local" Manifest, the 0.2, which tries to fix all those issues.
This new format is documented here.

We added a chapter here to facilitate the transition from the 0.1 version if you were already using it.

A new tool: the StringUtils

In the player, we have a lot of code related to string to byte conversion and vice-versa.

Because this is something you can need on your application, and because it won't move out of the player's code soon, we decided to add a StringUtils tool exporting some of those functions.

For the moment only functions converting to and from UTF8 and UTF16 (both big and little endian) are available, they are documented here.

Changelog

Features

  • Add audioTrackSwitchingMode loadVideo option to allow different strategies when switching between audio tracks [#801, #806]
  • Add enableFastSwitching loadVideo option to enable or disable optimizations doing segment replacement in the browser's buffer [#779, #780]
  • Add initialManifest loadVideo option to provide the Manifest to the RxPlayer when it has already been loaded [#807]
  • tools: Add StringUtils utilitary functions to tools to convert bytes to strings and the other way around [#809]
  • tools: The TextTrackRenderer tool is not experimental anymore: it now has a stable API [#810]
  • experimental/local-manifest: The RxPlayer now (only) plays the new "0.2" format version of the "LocalManifest" (in the experimental "local" transport) [#810]

Bug fixes

  • directfile: Fix impossibility to play an encrypted content in directfile mode (regression brought in v3.21.1) [#827, #830]
  • subtitles: Display multiple cues with overlapping times [#829]
  • smooth: Fix minimum position in a Smooth live content when fewer segments than the dvr window length are available [#826]
  • dash/metaplaylist: Fix possible playback issues on multi-Period contents, where segments from multiple Periods overlap [#837]
  • Fix very rare race condition which triggered a "setting priority of null" error after synchronous segment requests were done [#817]
  • local-manifest: LocalManifest that transition from not finished to finished while playing now end properly [#818]
  • local-manifest: Fix and clarify the duration and maximum position reported for a playing LocalManifest [#818]
  • compatibility/drm: On some webkit-based browsers, do not require the use of a server certificate for DRM if the key system used is not FairPlay [#833]
  • drm: Properly update to a different server certificate on the MediaKeys or remove it if needed [#835]
  • drm: throw MEDIA_IS_ENCRYPTED_ERROR again when playing an encrypted event without either the EME feature, EME APIs or a keySystems option [#841]

Other improvements

  • subtitles/ttml: Apply default position to TTML subtitles in "html" textTrackMode when no style is found [#815]
  • subtitles/ttml: Set default text color to white to TTML subtitles in "html" textTrackMode [#832]
  • drm: Avoid re-setting a server certificate we know has already been pushed to improve loading performance [#824, #835]
  • dash: Always prefer a "main" AdaptationSet when hesitating between multiple ones [#828]
  • dash: Improve minimum position precision for dynamic DASH contents when less segments are available than what would be guessed from the timeShiftBufferDepth [#826]
  • drm/logs: Better log why a MediaKeySession is not considered as "usable" [#822]
  • drm/logs: Be more verbose with DRM-related logs, even at lower logger levels [#821]
  • tests/conformance: Add "conformance tests", to quickly test the capabilities of new devices and targets [#814]
  • code: avoid circular dependency in src/features in original typescript source files [#805]
  • demo: Fix default position for the video track select element in the demo to always be at the currently selected video track [#813]
  • demo/code: Better integrate the RxPlayer to the demo: through a simple import, instead of adding a script tag for the bundled version [#811]
  • dev: Remove all enforced git-hooks (on pre-commit and pre-push) [#808]