Skip to content

Releases: canalplus/rx-player

v4.0.0

21 Feb 15:47
Compare
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
Compare
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]

v4.0.0-rc.2

07 Feb 17:44
Compare
Choose a tag to compare
v4.0.0-rc.2 Pre-release
Pre-release

Release v4.0.0-rc.2 (2024-02-07)

Quick Links:
📖 API documentation - Demo - 🎓 Migration guide from v3

Overview

This new release candidate mainly fixes issues we've seen with the WebAssembly parser for DASH MPD, that is used for both the DASH_WASM feature (which lost its "experimental" label at v4.0.0-rc.1) and the MULTI_THREAD experimental feature.

Another minor fix is on the handling of the <UTCTiming> element in a DASH MPD. If it pointed to an URL and if the resource behind it could not be fetched when first loading the MPD due to issues with the request(s) (there may be several attempts), then the RxPlayer would keep re-loading the resource each time the MPD was refreshed, instead of just stopping doing it once it loaded successfully once - which is what the RxPlayer does now.

None of these issues are regressions, and thus some also concern the v3.33.0 (the DASH_WASM and <UTCTiming> ones). As those all are very minor issues (DASH_WASM being still experimental in v3.33.0 - with an error triggering a fallback on the JS-based parser anyway - and the <UTCTiming> issue being rare and not preventing smooth playback) they will only be released as a future v3.33.1 release once the 4.0.0 is released.

Changelog

Features

  • MULTI_THREAD: attachWorker now returns a Promise to indicate when WebWorker attachment failed [#1374]

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]
  • MULTI_THREAD: properly categorize forced subtitles in multithread scenarios

Other improvements

  • build: automatically install Rust and WASM toolchain locally if unavailable when building the RxPlayer [#1373]
  • 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]

DASH_WASM and MULTI_THREAD fix

After testing the MULTI_THREAD feature on a large array of smart TVs, we noticed that some old Samsung and LG TVs had issues instantiating our WebAssembly MPD parser (on which both the MULTI_THREAD and DASH_WASM features rely).
It turned out that those TVs had support for WebAssembly (if they did not, the RxPlayer would automatically have disabled "multithread" mode), yet to a very old version of it which did not have some of its early features present in the WebAssembly file produced by the Rust compiler (the compiler we're using) by default.

This was not known to us as we always assumed that the compiler targeted by default the earliest available version of WebAssembly.

We ended up doing supplementary transformations on our WebAssembly file to remove the reliance on those newer features. The new mpd-parser.wasm file delivered with this version (as well as exported through "rx-player/experimental/features/embeds") should now be compatible with those devices.

attachWorker now returns a Promise

The aforementioned DASH_WASM and MULTI_THREAD issue put a light into some scenarios we were not enough prepared for: how to handle cases where the WebWorker and/or WebAssembly module relied on when using the MULTI_THREAD feature fail to initialize.
This should hopefully be very rare now, yet may still happen if e.g. any of those resources are behind an URL that is not accessible or if browser security settings prevents the RxPlayer from creating or relying on a WebWorker.

To better handle those cases for now, we decided that the attachWorker method now returns a Promise. That promise will either resolve if the Worker was initialized with success and reject if it did not.

Like before, you may still call loadVideo synchronously after the attachWorker call has been made (you don't have to await this Promise) but it is now advised to await that Promise in scenarios where you're both relying on the MULTI_THREAD feature and on one of the corresponding monothreaded feature (either DASH or DASH_WASM) - in which case it is the role of the RxPlayer to choose between one or the other.

For example: the following code:

import RxPlayer from "rx-player/minimal";
import { DASH } from "rx-player/features";
import { MULTI_THREAD } from "rx-player/experimental/features";
import {
    EMBEDDED_WORKER,
    EMBEDDED_DASH_WASM,
} from "rx-player/experimental/features/embeds";

RxPlayer.addFeatures([
  // Will allow to play DASH contents in main thread
  DASH,

  // Will allow to play DASH contents in multithread scenarios
  MULTI_THREAD,
]);

const player = new RxPlayer(/* your usual RxPlayer options */);

try {
  await player.attachWorker({
    workerUrl: EMBEDDED_WORKER,
    dashWasmUrl: EMBEDDED_DASH_WASM,
  })
  console.log("Worker succesfully attached!");
} catch (err) {
  console.warn("An error arised while initializing the Worker", err);
}

player.loadVideo({ /* your usual loadVideo options */ });

Will only load the content in "multithread" mode if all of the following are true:

  1. Your browser supports the feature (which is already checked synchronously when attachWorker is called)
  2. Your content is compatible with multithread mode
  3. The Worker initialization went without issue (this is the case where awaiting attachWorker has an effect)

And in other cases, it will load in monothreaded mode, as the DASH feature is also added.

If you do not await attachWorker before calling loadVideo here and the Worker initialization fails, the RxPlayer might have already begun to load the content in "multithread" mode. In that case it might fail to do so and trigger an error for that content (we're also currently exploring ways of making the RxPlayer automatically reload in monothreaded mode in this exact last scenario but it isn't done for now).

Also note that if Worker initialization fails, the RxPlayer won't try to rely on it anymore for the next loadVideo and reload calls. If you want to retry Worker initialization in that unlikely scenario, you could call attachWorker again.

Project repository updates

As we're now very confident of the stability of the v4 pre-releases, we began making changes to the RxPlayer repository:

  1. The default branch seen on GitHub and choosen as a default target branch for Pull Requests is now dev, which corresponds to the latest merged developments on the v4. Note that it is currently further than the v4.0.0-rc.2 as we're already merging improvements for future v4 releases.

    Another branch, stable corresponds to the last released v4 version (so here v4.0.0-rc.2) plus optional hotfixes. dev is based on stable.

    The old master branch keeps refering to the v3 but has been renamed to legacy-v3. next does not exist anymore, any new developments for the v3 now targets legacy-v3.

  2. The default demo page exposed both by the GitHub link and in our README.md file now leads to the v4.0.0-rc.2 demo.

    The last v3.33.0 demo page can still be accessed here and the list of demo pages per version can be found here.

  3. Likewise, the default documentation pages exposed in our README.md file now leads to the v4.0.0-rc.2 documentation.

    The last v3.33.0 documentation page can still be accessed here and the list of documentation pages per version can be found here.

  4. We filtered files that were actually published on npm when we published a new version. For example, you now shouldn't be pulling the RxPlayer source files anymore when doing so.

v4.0.0-rc.1

24 Jan 16:54
Compare
Choose a tag to compare
v4.0.0-rc.1 Pre-release
Pre-release

Release v4.0.0-rc.1 (2024-01-24)

Quick Links:
📖 API documentation - Demo - 🎓 Migration guide from v3

🔍 Overview

After more than three years since its early drafts and one year of open beta releases, it is finally time for the first release candidate of the v4.0.0 of the RxPlayer.

The main ideas behind this new v4 major version are:

  • To provide a more flexible and powerful track and quality selection API, especially more adapted to multi-Period DASH contents.

    For example, it is now not only possible to set a particular quality on a content, you can also allow a subset of multiple qualities from which the RxPlayer will adaptively choose from, based on any of their characteristics exposed by the API.

    You can also indicate what to do if the buffer already contains media data in another quality (reload? Keep it in the buffer? Remove it?).

    Likewise, track switching becomes very configurable, allowing you to directly switch a track of any Period, again with a strategy if another track was previously present in the buffer. The RxPlayer 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).

    The main API documentation about quality selection can be found here.
    For track switching, you can refer to the API documentation of the concerned API, see for example the setAudioTrack API documentation.

  • To allow a more sane default behavior and more resilience in the RxPlayer.

    For example, we are now automatically reloading if something has been detected to have gone horribly wrong, such as when encountering some exceptional device-related decryption issues or when obtaining a completely different Manifest after updating it.

    Moreover, if the chosen track is linked to Representations (qualities) which are all impossible to decrypt, the RxPlayer will now automatically fallback to a supported track instead (after sending events to indicate that it does so).

    We were previously limited on how we could do those things to stay compatible to old APIs.

  • To facilitate the implementation of ambitious improvements.

    For example the v4.0.0-rc.1 brings the new MULTI_THREAD experimental feature, allowing to run the RxPlayer's main logic in a WebWorker for better adaptive streaming stability and performances.
    This is a huge work we're right now using on a multitude of devices at Canal+, intended to improve the quality of experience, especially on devices with limited resources.

Depending on return we have on our large-scale tests (basically, if no important issue is found with it), this release candidate may become an official v4.0.0 relatively fastly (in the coming weeks).

If you're still relying on a v3.x.x release, we recommend looking up our migration guide to make the switch more easily.

📑 Changelog

We decided to compile the full v4.0.0 changelog for this release (instead of comparing it to our latest beta release), which makes it too big for this release note!
So we're only linking you to it here: https://github.com/canalplus/rx-player/blob/bf79b9164f8d530a94e338725f795ec5a5c7b278/CHANGELOG.md

What about the v3?

The v3.33.0 release of the RxPlayer, which was published just before this one, is planned to be our final default release on npm in the v3 major version (unless there is a major issue with it).

Once the official v4.0.0 stable release is published, v4 releases will take its place as a default when installing the package through package managers such as yarn and npm.

Moreover, most incoming features and improvements will be planned for v4.x.x releases first from now on.

v3.x.x releases will still be maintained for some time (we were for example talking about providing at least 1 year of support), but it will mostly be only bug fixes and improvements simple enough to be ported to it. Of course, outside contributions are welcomed if you want to provide improvements on it yourself.

If you want to make the switch but you're afraid of relying on a release candidate right now, we recommend maintaining a branch which will depend on this
v4.0.0-rc.1 release in your project and putting it in production once the v4.0.0 is actually released.

v4 summary

The v4.0.0-rc.1 inherits from both the v4.0.0-beta.3 (and consequently any prior v4 release) and from the just-released v3.33.0 (and consequently all previous v3 releases).

The rest of this release note is going to focus ONLY on features brought in this particular release (which means we're not relisting features already announced in previous v4 and v3 release notes).

You can look at the v4 beta release notes for more information on some earlier v4 features:

And on the the v3.33.0 release note for the just-released features which are also in this one.

The new MULTI_THREAD experimental feature

This release 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]   | |
|                           +----------------------+ |
+--------------...
Read more

v3.33.0

24 Jan 16:39
Compare
Choose a tag to compare

Release v3.33.0 (2024-01-24)

🔍 Overview

The v3.33.0 is now available on npm.

It is planned to be the last main v3 release now that the official v4.0.0 is around the corner and became our main focus (a v4.0.0-rc1 will be published just after this one), yet is still contains its share of improvements and bug fixes:

  • DASH: To better support retro-compatible Dolby Vision content, the scte214:supplementalCodecs is now handled. Concerned contents will be advertised under a Dolby Vision codec for compatible devices, or the retro-compatible codec for those who aren't
  • A new getLivePosition method and fromLivePosition startAt option have been added, mainly for advanced ad-switching usages.
  • subtitles: the tts:lineHeight TTML attribute was not properly applied, it is now fixed
  • subtitles: A rare occurence of blinking subtitles could arise, especially on low-latency contents. This also has been fixed.
  • Add the possibility of setting another keySystems option on the reload API.
  • Several fixes on issues that could arise when doing API calls after reaching the last playable position of a content.
  • DEBUG_ELEMENT: Undecipherable and unsupported codecs are now announced in the debug element
  • Multiple other minor fixes and improvements linked to ad-switching, checking of codec support, and low-memory handling.

📑 Changelog

Features

  • Add getLivePosition RxPlayer method [#1300]
  • Add startAt.fromLivePosition loadVideo option [#1300]
  • Add the possibility to set a new keySystems option on the reload API [#1308]

Bug fixes

  • Fix subtitles "blinking" in some specific conditions, especially with some DASH low-latency contents [#1314]
  • DASH: Fix Period overlap resolution logic for when the first Period is removed [#1311]
  • TTML: Fix handling of the tts:lineHeight attribute [#1320]
  • Fix import of the LOCAL_MANIFEST experimental feature
  • Avoid very rarely skipping segments which initially were too big to be pushed due to memory limitations [#1323]
  • Fix issue arising when using track APIs at the exact last possible position of a Period with no consecutive Period [#1337]
  • Starting at the end (through a startAt loadVideo option) or reloading at the end led to the restart of the content [#1338]
  • DRM/Safari: also perform Safari DRM work-arounds when the page is launched from the dock [#1351, #1356]

Other improvements

  • DASH: rely on SCTE214 supplementalCodecs instead of codecs if it's supported to better support backward compatible Dolby Vision contents [#1307]
  • DASH: Provide better support of the availabilityTimeOffset attribute [#1300]
  • DEBUG_ELEMENT: Add unsupported and undecipherable bitrates to the debug element [#1321]
  • DEBUG_ELEMENT: update buffer graph maximum size so it becomes more readable for lengthy contents [#1316]
  • DEBUG_ELEMENT: always synchronize inventory of segments before rendering it [#1317]
  • Remove remaining RxPlayer dependency removing possibility of some application-side bundling errors [#1312]
  • Add exception to text Garbage collection logic to avoid unnecessarily reload text segments frequently [#1325]
  • Avoid logging too much the buffer's content when our debugging UI or the demo is used [#1341]
  • Demo: Fix reporting of live position in demo page [#1313]

About it being the last "main v3 release"

As we've reached a point where we plan to release the first official v4.0.0 release, we also plan to make v4 releases our main focus when new features and improvements are added. As such, a v4.0.0-rc1 release should be released just after this release. If our large-scale tests go well, it will become the first v4.0.0 release.

This do not mean that the v3 will become unsupported. It should still receive bug fixes yet:

  1. It will not be the version installed by default through npm / yarn, which will be the v4 instead once the official v4.0.0 version is released.
    The idea will be to set the npm legacy-v3 tag for newer v3 releases, so an rx-player v3 may be installed through something like: npm install rx-player@legacy-v3.

  2. When planning new improvements, we now will implement it on the v4 first, and only backport it to the v3 if it is simple enough with few risks to break.

  3. As more and more applications will rely on the v4 (we already "convinced" many at Canal+ to do so), we will progressively become more aware of issues when they concern the v4 and less about v3 issues.

DASH supplementalCodecs handling

We recently had some issues trying to play Dolby Vision content on LG TVs where the device would not play at all, due to a discrepancy between the video codec announced by the RxPlayer (which did not make mention of Dolby Vision), and the Dolby Vision data actually pushed to the video buffer.

This was because the media stream we've tested make usage of a smart trick: as the Dolby Vision video data was backward-compatible to regular HDR for devices not supporting Dolby Vision, two codecs were actually announced in the content's MPD (the DASH's Manifest file, which list available tracks and qualities):

  • The much more compatible HDR codec, as a codecs attribute (e.g. in a <Representation> or <AdaptationSet> element in the MPD) like expected
  • The Dolby Vision codec, as a scte214:supplementalCodecs property, that we did not process until now

repsupcodec
Screenshot: Content of a DASH MPD with both a codecs property and a supplementalCodecs property in the <Representation> element

The RxPlayer previously only relied on the codecs property (so here not the Dolby Vision video codec) when interacting with lower-level media API.
Though the HDR codec was compatible to the video data, it was actually expected by some Dolby Vision-capable device that the Dolby Vision codec should have been relied on when creating video buffers.

However, if we did rely on the Dolby Vision codec instead through those API, devices which do not handle Dolby Vision video content would not have been able to play the content as just "regular" HDR video data, for them it would have been Dolby Vision, which they do not know how to decode.

So we chose to put a little more intelligence in the RxPlayer, when there is a scte214:supplementalCodecs property (let's call the corresponding codec property the "supplemental codec"):

  • If the supplemental codec is supported by the current device (we can know that through the MediaSource.isTypeSupported API, we consider it to be the actual "codec" of the corresponding video data.
  • If it is not supported, we rely on the codecs instead, just like we did before

suppcodec
Flowchart: How the RxPlayer will decide whether to rely on a scte214:supplementalCodecs or a codecs attribute in a DASH MPD.

This also means that API communicating about video codecs, like the getVideoTrack method, may now actually indicate the "supplemental codec" through their codec property, where it always corresponded in DASH to the corresponding codecs attribute instead).
This should in most case not lead to any change in your application as this is mainly a lower-level detail about a Representation (a.k.a. media quality).

getLivePosition method and startAt.fromLivePosition option

Some applications at Canal+ relying on the RxPlayer make use of "ad-switching" technologies.
Basically, the idea is to replace ads present in a source stream by targeted ads.

There are multiple techniques to implement this, yet for DASH they generally rely on its concept of Periods.
In the MPD (DASH's Manifest file), each of those ads would be defined in a different <Period> element, which is a time-delimited division of the content with its own media tracks and qualities.

multiperiods
Schema: Exemple of a schema representing a DASH multi-Period live content, with an ad break where each Period corresponds to a single Ad.

Another effect of ad-switching is that the server may know in advance which ad should be served to a user.

Let's for example consider a user which plays a live content. That user now encounters an ad-switched ad break at 11:04 AM, which will end 5 minutes later, at 11:09 AM.
Though it is still 11:04, the server already knows which ads it's going to serve to that user from 11:04 to 11:09 (those ads are targeted and already scheduled), so it may want to already announce them in the MPD even though most of those ads are m...

Read more

v4.0.0-beta.3

19 Oct 18:15
c9dd85f
Compare
Choose a tag to compare
v4.0.0-beta.3 Pre-release
Pre-release

Release v4.0.0-beta.3 (2023-10-19)

Quick Links:
📖 API documentation - Demo - 🎓 Migration guide from v3

🔍 Overview

The v4.0.0-beta.3 release is now here. As usual, it is based on the last official v3 release (here the just released v3.32.1) as well as previous v4 beta releases.

The v4.0.0-beta.3 release should be the last v4 "beta" release, meaning that the next v4-linked release will probably be our first release candidate for a first official v4.0.0 release.

We already tested the code behind this beta.3 release extensively in production conditions on most environments we target at Canal+ (which helped us detect and fix an adaptive-linked issue only seen on older Edge browser versions), so we're becoming confident that this version will work on every supported devices and for a large panel of usages.

As we wanted to ensure that the v4 API is final (or very close to final), we reviewed every RxPlayer v4 API on current usages as well as future planned usages to ensure that API stability is easy to guarantee. This led to some changes, described in this release note.

📑 Changelog

Changes

  • The MediaError's trackInfo property is now an array renamed as tracksInfo and similar MediaError are grouped in one [#1264]
  • The manifestUpdateUrl loadVideo option has been removed as it was unused [#1276]
  • The /dist directory in the project has been removed [#1270]

Bug fixes

  • Fix adaptive logic on some legacy Edge browsers [#1302]

Other improvements

  • newAvailablePeriods is now sent lazily at the time new Periods are considered to improve performance [#1265]
  • Implement better error messages by not repeating the Error Type in it [#1290]
  • All import path to the RxPlayer now depend on the same RxPlayer modular build (and not just the minimal, as before) [#1301]

newAvailablePeriods event now sent lazily

The newAvailablePeriods event is a new RxPlayer event central to the v4 API indicating that new "Periods" from the current content begin to be considered by the RxPlayer.
As each Period brings with it its own set of audio/text/video tracks and qualities, it is the main event to listen to when you want to choose an initial track or quality.

hierarmpd
Screenshot: screenshot describing the Period, AdaptationSet and Representation elements of an MPD, which are advertised in the v4 API beginning with a newAvailablePeriods event.

In previous beta and alpha releases, the RxPlayer sent this event just after parsing the content's Manifest (and after refreshing it), by communicating directly about all Periods seen in that Manifest.

We became afraid that on very large Manifest with a large amount of Periods and track choices, the current design for this event could lead to performance issues: as soon as the Manifest was parsed (and before the content started to play), the RxPlayer would send a newAvailablePeriods event - perhaps for the hundreds of Periods seen in that Manifest.
The application (the software using the RxPlayer library) would then iterate through all of those Periods, as well as its inner tracks and qualities, to make its initial choice - and all that before the content is finally able to play.

supergraph
Graph: Timeline of situations leading to the newAvailablePeriods event and corresponding player actions. It then continues as the setting of the audio, video and text tracks by the application has to be done for all Periods advertised through the newAvailablePeriods event.

This seems risky performance-wise as well as unnecessary. When the content starts to play, the only track and quality choices we probably want to set are just the one linked to the Period we're initially playing. For live contents for example, we don't need to set the audio track for the program that was aired 15 minutes ago.
The only time where we might want to set it, is if the user ever seeks back to that program (a situation which might never occur).

The RxPlayer now "lazily" sends newAvailablePeriods events, meaning that it will only communicate about "Period(s)" that are either playing or will be played soon by the RxPlayer. For example when playing a live content, it will probably only send this event for the currently-playing program, not the one playing before or after it.

supergraph2
Graph: Updated timeline now that newAvailablePeriods only transports information on the Period(s) that matter for now. Here we can see that the application for example only set the tracks for a single Period.

If the user seeks to another Period or if playback position reaches a new Period, a new newAvailablePeriods will then be sent for it.

Normally, this doesn't break the previous v4 API so you shouldn't need to change anything if you relied on a previous v4 version. Still, as it is a considerable change, you could need to check if this doesn't break assumptions you previously had on your side.

Changes concerning Errors

Error message changes

Historically, the message property of RxPlayer errors had the peculiar following format:

<Error Type> (<Error Code>) <Error Message>

For example, for an EncryptedMediaError with an INCOMPATIBLE_KEYSYSTEMS code, we could have:

EncryptedMediaError (INCOMPATIBLE_KEYSYSTEMS) Some description message

Packing so much information into the message was unconventional, repeated information already available elsewhere and led to an ugly reporting in debuggging tools.
For example, error logged in most inspectors and debuggers are already prepended by the Error Type, leading in the previous example to the following log:

EncryptedMediaError: EncryptedMediaError (INCOMPATIBLE_KEYSYSTEMS) Some description message

Although error messages are not part of our API (so we could have changed its format at any time) we were still reluctant to do so as applications might have relied on that format to extract information programatically. Now that the official v4 is around the corner, we finally updated its format to a more legible:

<Error Code>: <Error Message>

As such the previous error message would be:

INCOMPATIBLE_KEYSYSTEMS: Some description message

And it would be logged by inspectors as:

EncryptedMediaError: INCOMPATIBLE_KEYSYSTEMS: Some description message

trackInfo renamed as tracksInfo

We made another small change to RxPlayer errors, this time on the recently-added trackInfo property that could be set on some MediaError, to add precizion on the particular track concerned.

We noticed that many of them were sent in bulk, for example when the Manifest is found to contain multiple tracks in unsupported codecs, we would send a warning event dispatching a MediaError with an MANIFEST_INCOMPATIBLE_CODECS_ERROR for each of the unsupported track (and in multi-Period contents, there could be hundreds of them).

Now we decided to group such errors together when they are happening at the same time, and to allow the setting of multiple tracks' information in a tracksInfo array property (with an s, instead of the previous trackInfo). The MediaError documentation has been updated.

Changes concerning the builds

In previous RxPlayer versions, we exposed several builds of the RxPlayer in the npm repository:

  1. The "legacy" build, which is a bundled single JS file, which was used when importing the RxPlayer "normally" through an import RxPlayer from "rx-player" line in ES6-style (or const RxPlayer = require("rx-player") ni CommonJS style).

    We relied on the Webpack bundler to produce that build.

  2. The "modular" build, targeted by most other imports (such as the minimal build: import RxPlayer from "rx-player/minimal") which uses multiple files, allowing for "tree-shaking" on the application-side.

    Here we mostly rely on TypeScript and on our own scripts.

Having this double way of exporting the RxPlayer led to some complexity on our side and we weren't too comfortable of having too much complexity in such an important area for a library.

We'r...

Read more

v3.32.1

19 Oct 17:19
Compare
Choose a tag to compare

Release v3.32.1 (2023-10-19)

NOTE: This is the v3.32.1 and not a v3.32.0 as you could have expected due to a small mistake when publishing our TypeScript types to npm for a v3.32.0. We detected it and fixed it immediately with a new release, the v3.32.1.

🔍 Overview

The v3.32.1 mainly brings stability improvements over the v3.31.0, as we start to focus more and more on the future v4.0.0 release.

On that matter we'll probably soon release the first v4.0.0 release candidate (paving the way for the first official v4.0.0 release), after a long period of alpha and beta releases (the next beta release should come just after this one) where we were still figuring out some API details.

Note that we're however still commited to maintain the v3.x.x releases for some time, at least in terms of providing bug fixes, as we know doing the switch to the v4 may not be in your agenda for now.
As such, even when the official v4.0.0 will be released, we will continue publishing some v3.x.x releases, only with a special npm tag (e.g. rx-player@v3).

📑 Changelog

Features

  • DASH: add optional isSpatialAudio boolean property to Representation returned by getAvailableAudioTracks, getAudioTrack, corresponding events, and trackInfo optional property of MediaError objects to signal Dolby Atmos techology [#1275]
  • LOCAL: add isSpatialAudio property to Representation of the experiment "local" transport (used for offline playback) [#1275]
  • addFeatures static method is now available on all RxPlayer builds. It was previously only in the minimal (rx-player/minimal import path) [#1287]
  • The NATIVE_TEXT_BUFFER, HTML_TEXT_BUFFER and IMAGE_BUFFER features are now totally optional [#1287, #1293]

Bug fixes

  • Fix setVideoBitrate and setAudioBitrate API which may have led to a higher quality than wanted in the default "seamless" manualBitrateSwitchingMode if our buffer-based adaptive logic decided to [#1267, #1271]
  • On the PlayStation 5, only switch to the "LOADED" state once the HTMLMediaElement's readyState of 4 has been reached, as it seems to switch to 3 too soon there [#1257]
  • DASH: Fix potential track duplication if more than two AdaptationSet have an adaptation-set-switching <SupplementalProperty> between one another [#1279]
  • DASH-WASM: availabilityTimeOffset is actually a floating number [#1278]

Other improvements

  • Do not load the last text segment if the current position goes after it as it is unnecessary [#1256]
  • Implement better NetworkError messages [#1274]
  • Set a better error message for when no keySystems option is set when playing an encrypted content
  • Fix very small memory leak when reloading a content [#1286]
  • Re-check for segments to load immediately after the manifest has been refreshed [#1282]
  • When "fallbacking" an undecipherable Representation, now empty the whole buffer if we can't make out where content was in the buffer [#1283]
  • Improve segment start detection in buffer when there's unknown data buffered before it [#1284]
  • DRM: Selection of alternative EME API like those used on IE11 or Safari has been refactored to facilitate future developments [#1261]

Deprecated

  • Deprecate the manifestUpdateUrl loadVideo option as it doesn't seem used anymore [#1288]
  • Deprecate the NATIVE_TEXT_BUFFER, HTML_TEXT_BUFFER and IMAGE_BUFFER features as they are now unneeded [#1287, #1293]

New isSpatialAudio property

This v3.32.1 release brings the new isSpatialAudio property to audio tracks on the following API:

This property is for now only set to true when an audio track relies on Dolby Atmos under the "Dolby Digital Plus Joint Object Coding" (or JOC) technology, which allows to distribute Dolby Atmos audio content in a format compatible with Dolby Digital Plus audio (most probably under the "ec-3" codec), which is Dolby's recommended way of distributing DASH contents with Dolby Atmos audio.

So in short, for now isSpatialAudio is only set to true when an audio track relies on Dolby Atmos technology. For any other cases for now, it is not defined (a value of false would semantically mean that we're sure that the audio track is not spatial audio, which is a guess we prefer not to make for now).

Due to what's allowed in DASH, the isSpatialAudio property is set on "representations" (a.k.a. qualities), not on the track itself:

function hasSpatialAudio(audioTrack) {
    if (!audioTrack) {
        return false;
    }
    return audioTrack.representations
        .some(representation => representation.isSpatialAudio === true);
}

if (hasSpatialAudio(player.getAudioTrack()) {
    console.log("We're currently playing an audio track with spatial audio");
}

The majority of the development on this feature has been provided by an external contributor, @klatoszewski-oke, which we thank again.

addFeatures now globally available

On previous RxPlayer releases you were forced to rely on the minimal RxPlayer build to use any of its experimental features like DASH_WASM (WebAssembly-based DASH MPD parser), LOCAL_MANIFEST (playback of offline contents), DEBUG_ELEMENT (debugging UI) or METAPLAYLIST (client-side content generation).

If instead you used the default RxPlayer build, for example through a simple import RxPlayer from "rx-player"; import in your files, you were just left with the default set of features.

Now any build of the RxPlayer can directly call the addFeatures static method to add any of those optional features. For example to add the DEBUG_ELEMENT feature (and thus be able to call the createDebugElement method), you can write:

// 1. Add `DEBUG_ELEMENT` feature
import RxPlayer from "rx-player";
import { DEBUG_ELEMENT } from "rx-player/experimental/features";

RxPlayer.addFeatures([DEBUG_ELEMENT]);

// 2. Create RxPlayer instance and call method
const player = new RxPlayer({ /* ... */ });
player.createDebugElement(myElement);

Consequently, the features documentation has been moved from the "Getting started" part to our regular "API" documentation.

Deprecation of the NATIVE_TEXT_BUFFER and HTML_TEXT_BUFFER features

Both the NATIVE_TEXT_BUFFER feature and the HTML_TEXT_BUFFER features, which are the arguments of the addFeatures static method, have been deprecated as they are now unneeded.

They're basically optional now that importing a text parser for the corresponding type of buffer is going to implicitely add the feature anyway.

This means that if you were previously doing:

import RxPlayerMinimal from "rx-player/minimal";
import { HTML_TEXT_BUFFER, HTML_TTML_PARSER } from "rx-player/features";
RxPlayerMinimal.addFeatures([HTML_TEXT_BUFFER, HTML_TTML_PARSER]);

You can now just omit the HTML_TEXT_BUFFER feature:

import RxPlayerMinimal from "rx-player/minimal";
import { HTML_TTML_PARSER } from "rx-player/features";
RxPlayerMinimal.addFeatures([HTML_TTML_PARSER]);

As you have no reason to import one of those features without at least one parser, making it optional and implicit will generally just simplify your code.

Many small fixes

This v3.32.1 brings a lot of small fixes and improvements, that you can see on the changelog on top of this release note.

A good chunk of them were found as we were extensively testing both the future v4.0.0 as well as our proof-of-concept of trying to run the RxPlayer's internal logic in a WebWorker (more details on this hopefully soon).

We also reinforced our debugging capabilities by continuing our work on RxPaired, our remote debugger specialized for the RxPlayer that we're using internally at Canal+.
This helps a lot when debugging the RxPlayer on devices such as smart TVs, chromecast and game consoles which often have their own issues.
It helped us ...

Read more

v4.0.0-beta.2

27 Jun 15:06
ab78c0f
Compare
Choose a tag to compare
v4.0.0-beta.2 Pre-release
Pre-release

Release v4.0.0-beta.2 (2023-06-27)

Quick Links:
📖 API documentation - Demo - 🎓 Migration guide from v3

🔍 Overview

The new v4 beta release, based on the v3.31.0, is here.
It contains all improvements from previous v4 alpha and beta releases, as well as some further improvements mostly related to DRM, all described in this release note.

About v4 beta releases

As a reminder, beta v4 versions are RxPlayer pre-releases (as some minor API changes are still done, see changelog) for the future official v4 release, a successor to the current v3 releases of the RxPlayer.

We're currently testing it on several applications. As we're doing it, our team as well as people porting it can propose some small API improvements, which may then be added to the next beta releases. After enough people have made the switch and are satisfied with the new API, the first official v4 release will be published (we're also in the process to have some applications running it in production to ensure its stability with a large enough population).

We will still continue maintaining and providing improvements to the v3 for at least as long as the v4 is in beta (and we will probably continue to provide bug fixes for the v3 for some time after the official v4.0.0 is released).
This process is long on purpose to be sure that we're providing a useful v4 API for applications and also to avoid alienating application developers, as the migration from the v3 might take time.

📑 Changelog

Changes

  • If all Representations from the current track become undecipherable, automatically switch to another track (also send a trackUpdate event) instead of stopping on error [#1234]
  • Only send MediaError errors with the NO_PLAYABLE_REPRESENTATION error code when no Representation from all tracks of a given type can be played [#1234]

Features

  • Add representationListUpdate event for when the list of available Representation for a current track changes [#1240]
  • Add "no-playable-representation" as a reason for trackUpdate events when the track switch is due to encrypted Representations [#1234]

Other improvements

  • DRM: Reload when playback is unexpectedly frozen with encrypted but only decipherable data in the buffer to work-around rare encryption-related issues [#1236]

NO_PLAYABLE_REPRESENTATION behavior change

In the v3 and previous v4 beta releases, if you could not play any Representation (i.e. quality) from your chosen audio or video track due to encryption matters, you would obtain a MediaError error with the NO_PLAYABLE_REPRESENTATION error code.

Stopping on error when no quality of the chosen track can be played seemed logical at the time, but we're now encountering use cases where it would be better if the RxPlayer automatically took the decision to change the current track instead, to one that perhaps has decipherable Representation(s).
The main example we encountered was cases where we had separate video tracks, each linked to another dynamic range (e.g. an HDR and a SDR track) and with different security policies (tracks with a high dynamic range would have more drastic security policies for example).
Here, I would guess that an application would prefer that by default we switch to the SDR video track if no Representation in the HDR one is decipherable, instead of just stopping playback with a NO_PLAYABLE_REPRESENTATION error.

Before:
-------

+----------------+
|    Selected    |  Not decipherable
|   Video Track  |  --------------------> NO_PLAYABLE_REPRESENTATION
| (example: HDR) |                        Error
+----------------+

Now:
----

+----------------+                        +---------------------+
|    Selected    |  Not decipherable      |      Automatic      |
|   Video Track  |  --------------------> |     fallback to     |
| (example: HDR) |                        | another video Track |
+----------------+                        |   (example: SDR)    |
                                          +---------------------+

Note that the NO_PLAYABLE_REPRESENTATION error might still be thrown, only now it is when no Representation of all tracks for the given type are decipherable.

New trackUpdate reason

Because an application might still want to be notified or even stop playback by itself when the initially-chosen track has no playable Representation, we also brought added the "no-playable-representation" reason to the trackUpdate event, which indicates that the current track for any Period of the current content was updated due to this situation.

player.addEventListener("trackUpdate", (payload) => {
  if (payload.reason === "no-playable-representation") {
    console.warn(
      `A ${payload.trackType} track was just changed ` +
      "because it had no playable Representation"
    );
  }
});

New representationListUpdate event

This new beta version of the v4 also brings a new event: representationListUpdate.

The problem without this event

Let's consider for example an application storing information on the currently available qualities (a.k.a. Representation) for the chosen video track of the currently-playing Period (said another way: being played right now).
With the v4 that application can simply get the initial list of Representation when that Period begins to be played through the periodChange event and update this list any time the video track changes, by listening to the trackUpdate event:

let currentVideoRepresentations = null;

function updateVideoRepresentations() {
  const videoTrack = player.getVideoTrack();
  if (videoTrack === undefined || videoTrack === null) {
    currentVideoRepresentations = null;
  } else {
    currentVideoRepresentations = videoTrack.representations;
  }
}

// Set it when the Period is initially played
player.addEventListener("periodChange", () => {
  updateVideoRepresentations();
});

// Set it when the video track is changed
player.addEventListener("trackUpdate", (t) => {
  // We only want to consider the currently-playing Period
  const currentPeriodId = player.getCurrentPeriod()?.id;
  if (t.trackType === "video" && t.period.id === currentPeriodId) {
    updateVideoRepresentations();
  }
});

// Remove it when no content is loaded
player.addEventListener("playerStateChange", () => {
  if (!player.isContentLoaded()) {
    currentVideoRepresentations = null;
  }
});

This seems sufficient at first.

But now let's consider that we're playing encrypted contents, and that one of the Representation of those current video tracks became un-decipherable at some point (e.g. after its license has been fetched and communicated to your browser's Content Decryption Module).
Here, an application won't be able to select that Representation anymore, so it generally will want to remove it from its internal state. However, there was no event to indicate that the list of available Representations had changed when neither the video track itself nor the Period has changed

The new event

We thus decided to add the representationListUpdate event. Exactly like the trackUpdate event, it is only triggered when the Representation list changes, i.e. not initially, when the track is chosen.

So taking into consideration that point, the previous code can be written:

let currentVideoRepresentations = null;

function updateVideoRepresentations() {
  const videoTrack = player.getVideoTrack();
  if (videoTrack === undefined || videoTrack === null) {
    currentVideoRepresentations = null;
  } else {
    currentVideoRepresentations = videoTrack.representations;
  }
}

// Set it when the Period is initially played
player.addEventListener("periodChange", () => {
  updateVideoRepresentations();
});

// Set it when the video track is changed
player.addEventListener("trackUpdate", (t) => {
  // We only want to consider the currently-playing Period
  const currentPeriodId = player.getCurrentPeriod()?.id;
  if (t.trackType === "video" && t.period.id === currentPeriodId) {
    updateVideoRepresentations();
  }
});

// Remove it when no content is loaded
player.addEventListener("playerStateChange", () => {
  if (!player.isContentLoaded()) {
    currentVideoRepresentations = null;
  }
});

// What's new:
...
Read more

v3.31.0

14 Jun 16:42
16f75e7
Compare
Choose a tag to compare

Release v3.31.0 (2023-06-14)

🔍 Overview

The v3.31.0 release is now here!

It brings:

  • Many new API to improve developer experience when relying on the RxPlayer: isContentLoaded, isBuffering, isPaused, play and paused events, getLastStoredContentPosition and the trackInfo property on error

  • A refactored adaptive logic allowing to limit the frequency of quality switches, generally seen as a poor experience and which could lead to rebuffering in some extreme situations

  • A fix for the "direct" audioTrackSwitchingMode which in some situations could lead to the absence of sound when changing the audio track

  • A fix for DASH multi-Period contents, where we could be led to an infinite rebuffering cases in-between two periods in some conditions

  • "forced" subtitles support in "directfile" mode on Safari

  • Some Playstation 5 fixes to avoid playback issues on this platform

  • Better error reporting when an issue arises when initializing the DASH_WASM experimental Webassembly-based MPD parser

The future v4.0.0-beta.2 release, which will be based on this one alongside v4 features, will be released soon (in the coming days).

📑 Changelog

Features

  • Add isContentLoaded, isBuffering, isPaused, and getLastStoredContentPosition methods [#1248]
  • Add play and paused events [#1253]
  • Add trackInfo property to some MediaError to expose information on the track that caused the error [#1241]

Bug fixes

  • DASH: Fix issue which could lead to infinite rebuffering when switching between multiple Periods [#1232]
  • Return actual ending duration through the getVideoDuration method when playing dynamic contents whose future end is already known [#1235]
  • DASH/WASM: actually reject the DASH_WASM.initialize's Promise if it fails [#1238]
  • On the PlayStation 5, set Infinity MediaSource duration for live contents to prevent playback issues [#1250]

Other improvements

  • adaptive: Perform various adaptive tweaks to avoid switching too much between qualities in some conditions [#1237]
  • Directfile: Detect "forced" subtitles on Safari when playing directfile contents (such as HLS) [#1239]
  • Improve "direct" audioTrackSwitchingMode compatibility by re-seeking [#1246]
  • The DEBUG_ELEMENT feature now uses the monospace fallback font as a default for a better rendering on apple devices
  • doc: externalize documentation-generator code

isContentLoaded and isBuffering method

Until now, an application had to obtain the player's state (either through the getPlayerState method or through the "playerStateChange" event) to know whether a content was loaded, buffering, ended and so on.
This is fine but we thought that we could do better in terms of API.

Amongst player states, we noticed that some are frequently grouped together in some situation.

Consequently, we added the two following methods to the RxPlayer API in the v3.31.0.

  1. isContentLoaded: Most states, with the only exceptions of the "LOADING", "RELAODING" and "STOPPED" states, could all be grouped together to indicate that a a content is currently loaded.

    In turn, knowing that a content is or isn't loaded is important because when none is loaded, many methods such as setAudioTrack, setVideoBitrate and so on cannot be called.

    RELOADING.mp4

    Video: The three cases where a video is not considered loaded are visible in this video:
    1. When loading a content
    2. When reloading it (here we have changed the video bitrate while the manualBitrateSwitchingMode option was set to "reload")
    3. When stopped

    Because detecting any of the corresponding states is important in the RxPlayer API, we chose to add the isContentLoaded method to the RxPlayer's API, which will return true when a content can be considered as loaded (which is exactly the same than checking the corresponding states, though it is now more explicit).

    This method is documented here.

  2. isBuffering: Most applications want to show a visual indicator such as a spinner for when a content is loaded or being loaded, but not enough data is buffered for playback to happen. This is most commonly called "buffering".

    BUFFERING.mp4

    Video: Rebuffering cases both when loading and after seeking in a content.

    This corresponds to the "SEEKING" (buffering due to a seek operation), "LOADING" (initial buffering), "RELOADING" (buffering due to the necessity to re-create media buffers) and "BUFFERING" (other regular cases of buffering) states.

    The v3.31.0 version of the RxPlayer now adds the isBuffering method to the RxPlayer API, which will return true when the current player's state corresponds to any of those.

    Note however that you still may want to divide, depending on your applications further those states. For example the "LOADING" and "RELOADING" states may both be associated to a black screen, whereas you'll most likely have the last frame displayed when encountering the "BUFFERING" and "SEEKING" states. So, you might still want to rely on the general state depending on what you want to do in your application.

    This method is documented here.

isPaused method

The isPaused method may initially seem similar to the isContentLoaded and isBuffering method but unlike those two, which just facilitate the exploitation of the RxPlayer's state, isPaused actually adds a functionality.

In a media player, you frequently want to know whether the RxPlayer is "technically paused" or not, for example to know whether you should display the play or pause button in your user interface.

pause_button
play_button

Screenshots: Two schreenshots of a player's control bar. In each of them, we can see at the bottom left the button which may represent a "play" order or a "paused" order depending on if the playback is currently playing or not.
Here the top one display a "pause" button (and thus we're probably currently playing) whereas the bottom one display a "play" button (we're probably currently paused).

Although the "PAUSED" player state exists, it isn't sufficient to determine this. For example, you could technically be seeking, and thus in the "SEEKING" state, yet paused (which means that once enough data has been loaded you won't be playing, but paused).

Based on this, the player's state is not sufficient to determine whether playback is paused or not.
Until now, applications generally kept track of their last play/pause calls and of the last RxPlayer states to deduce whether playback was paused.

However, it should be easier and less error prone to obtain such an important information directly and explicitly from the RxPlayer.
This can now be done through the isPaused method which will return false when playback is considered as paused, regardless of the player's state.

const isPaused = rxPlayer.isPaused();
if (isPaused) {
  console.log("playback is currently paused");
} else {
  console.log("playback is currently not paused");
}

This method is documented here.

"play" and "pause" events

Because now that you have the new isPaused method you may also want to know when the RxPlayer enters or exits a pause.

For example to properly implement a "play/pause button", you might want to switch it reactively after a play or pause call has been processed. To al...

Read more

v4.0.0-beta.1

08 Mar 15:50
9ca93b8
Compare
Choose a tag to compare
v4.0.0-beta.1 Pre-release
Pre-release

Release v4.0.0-beta.1 (2023-03-08)

Quick Links:
📖 API documentation - Demo - 🎓 Migration guide from v3

Overview

This is an update of the previous v4.0.0-beta.0 release.

Compared to it, the v4.0.0-beta.1:

  • is now based on the v3.30.0 stable release of which it inherits all features, bug fixes and improvements (and not a partial list of them like for the beta.0)
  • Fix a memory leak just seen on the v4.0.0-beta.0
  • Provide other minor fixes over the v4.0.0-beta.0 (see the Changelog below)

Changelog

Bug fixes

  • (v4.0.0-beta.0-only issue) Fix memory leak
  • (v4.0.0-beta.0-only issue) Fix MediaSource duration when the maximum buffered end is inferior to current duration but superior to calculated duration
  • (v4.0.0-beta.0-only issue) Fix stopAtEnd option by also switching to STOPPED state on ended
  • (v4.0.0-beta.0-only issue) Fix some target's support by not relying on Promise.prototype.finally anymore [#1224]
  • (v4.0.0-beta.0-only issue) For dynamic contents, always set a very high duration [#1220]
  • (v4.0.0-beta.0-only issue) DRM: Fix fallbacking for an already-played content by checking key statuses initially linked to a MediaKeySession

Other improvements

  • Based on the v3.30.0 of which it inherits all the features, bug fixes and other improvements