v3.33.0
Release v3.33.0 (2024-01-24)
- π Overview
- π Changelog
- About it being the last "main v3 release"
- DASH
supplementalCodecs
handling getLivePosition
method andstartAt.fromLivePosition
option- Possibility to set a new
keySystems
when callingreload
- Multiple minor debug element improvements
π 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 andfromLivePosition
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 thereload
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 thereload
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 ofcodecs
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:
-
It will not be the version installed by default through
npm
/yarn
, which will be thev4
instead once the officialv4.0.0
version is released.
The idea will be to set the npmlegacy-v3
tag for newer v3 releases, so an rx-player v3 may be installed through something like:npm install rx-player@legacy-v3
. -
When planning new improvements, we now will implement it on the
v4
first, and only backport it to thev3
if it is simple enough with few risks to break. -
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
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
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 Period
s.
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.
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 meant to be played in the future.
In turn, the RxPlayer may want to load in advance that new data (reducing the risks of rebuffering comparatively to just loading until the live position) while preventing the user to play further than the "live position" (which is here still 11:04).
Schema: Illustration of the aforementioned example, where future ads are already announced and loaded in advance. We can see that the maximum position the RxPlayer will load is much further than the live position we usually want the user to play.
Because in that situation. there may be a difference between the maximum reachable position (here the end of the ad break at 11:09 AM) returned by the getMaximumPosition
method and the intended live position (here 11:04 AM) relatively to which the user should probably be playing (note: the RxPlayer doesn't enforce that: the initial position is relative to the live position but the user could then technically seek further than it if the application lets him/her do it), we added the getLivePosition
method to let applications know about the latter.
Likewise, we added the startAt.fromLivePosition
loadVideo
option allowing to set an initial playback position relative to the "live position". Previously that role was filled by start.fromLastPosition
but that option is only relative to the maximum position, which now might be very different.
The getLivePosition
method is documented here and the startAt
loadVideo
option here.
Note however that the RxPlayer will only make a live position "guess" when there's an explicit clock that has been communicated to it, either through an <UTCTiming>
element in the MPD, or through a serverSyncInfos
option.
In other situations, the RxPlayer will infer the live position from various heuristics, including the last position reachable in the Manifest.
Possibility to set a new keySystems
when calling reload
In the v3.23.0
, we added the reload
API allowing to re-load the last loaded content at the last played position.
The idea was to allow an application to reload a since-stopped or failed content with the same options than it was loaded with.
2024-01-24.12-30-31.mp4
Video: action of reloading on the demo page. We can see that we restart back roughly from the same position.
Previously, the reload
API had an optional argument, which only allowed to update a reloading position, and to indicate whether the content should auto-play after the reload. The idea was that if you needed to set more options, you would generally prefer to rely on the more powerful loadVideo
method instead.
However, it turned out that the most frequent issues we encounter in production are DRM-related, and that many of those can be avoided by setting another DRM configuration.
The main example would be low-level issues we encounter with Microsoft PlayReady SL3000 (hardware-based DRM) that we do not encounter when relying on PlayReady SL2000 (software-based DRM). In many cases, it's not even possible to guess in advance that SL3000 would fail: those problems are generally linked to PlayReady low-level implementation issues.
Specifically for those cases, we decided to add a keySystems
property to the reload
API, allowing you to reload the last content at its last played position with an updated DRM configuration. This keySystems
property follows the exact same syntax than the one for a loadVideo
call, and as such is documented at the same location, here.
This new feature thus allows to "reload" right away a content when encountering unexpected but known DRM issues on a given device, improving the quality of experience for the final user.
Multiple minor DEBUG_ELEMENT
improvements
We added in v3.30.0
the DEBUG_ELEMENT
experimental feature to allow the display of a RxPlayer overlay relying on its internal metadata to provide debugging information. We found it very useful when debugging and so we made some improvements to it in this version.
The most important is that now, undecipherable video and audio qualities are signaled by adding an E!
string after the corresponding bitrate in the vb
(for "Video Bitrates") and ab
(for "Audio Bitrates") parts of the debug element:
Screenshot: The RxPlayer experimental DEBUG_ELEMENT
as it can be seen when playing a content on https://www.canalplus.com. Here we can see that both the 3400000
and 4500000
video bitrates are linked to undecipherable video contents (they are followed by E!
). Consequently we will not be able to play them.
Likewise, unsupported codecs are signaled by adding an U!
string after the corresponding quality's bitrate (note that a quality can both be undecipherable and in an unsupported codec, in which case both E!
and U!
might be present).
We made other cosmetic changes on this debug element, such as ensuring that the "buffer graphs" are readable (by e.g. limiting their scale if the content is very long) and always up-to-date.