v4.0.0-beta.3
Pre-releaseRelease v4.0.0-beta.3 (2023-10-19)
Quick Links:
π API documentation
-
β― Demo
-
π Migration guide from v3
- π Overview
- π Changelog
newAvailablePeriods
event now sent lazily- Changes concerning Errors
- Changes concerning the builds
- Future work on exploiting WebWorkers
π 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
'strackInfo
property is now an array renamed astracksInfo
and similarMediaError
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.
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.
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.
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:
-
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 (orconst RxPlayer = require("rx-player")
ni CommonJS style).We relied on the Webpack bundler to produce that build.
-
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're now only relying on the "modular" build when the RxPlayer is imported. This should be completely transparent to you (if done well!) yet it greatly simplifies on our side the way the RxPlayer is built and distributed to applications.
Legacy single-file builds are actually still done, because they might be useful when for example relying on the "older" way of depending on the RxPlayer as a sepatate <script>
tag in an HTML file, but they will now only be attached to release notes such as this one.
Future work on exploiting WebWorkers
We recently put in place on top of the v4 a proof-of-concept of running most of the RxPlayer's logic in a WebWorker (which is a way of exploiting multi-threading capabilities) with the main goal being to offer better performance on some low-end devices, low-latency live contents and/or large Manifests.
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.
Simple explanation of what the WebWorker project is about.
The initial results have been very encouraging, with most of the time less rebuffering chances while doing heavy interactions with the user interface than before, so we continued that work with the goal of implementing that possibility in a future RxPlayer version.
We're now almost there. The main remaining issue is that there are some performance regressions when the part of the logic running in main thread is very busy yet the "worker" (the logic running in the other thread) runs at full speed. Sometimes in that situation, the worker thread seems to make it worse for the main thread by overwhelming it with new media data.
Still we're frequently doing releases of that work under the worker
tag in npm (the last version being: 4.0.0-worker.2023100500). You can have more information by looking at the corresponding Pull Request.