Skip to content

Releases: canalplus/rx-player

v3.10.2

08 Jan 10:36
2e3b3b7
Compare
Choose a tag to compare

Release v3.10.2 (2019-01-08)

Overview

This release mainly fixes two issues:

  • One in our manifest refreshing logic that prevented some MPDs/Manifests to be refreshed.
    To be exact (and technical), this issue mainly impacted DASH dynamic content in a SegmentTimeline indexing scheme without SegmentTemplate.

    As it is not the first time we had an issue in this area of the code, and as it is sensitive enough, we also decided to double our efforts on unit testing.

  • The second, that we tried to fix already in the v3.10.1 release is a better workaround to an Edge/Playready issue with initialization data: Some contents with DRMs could not be played on the Edge Browser.

Manifest-refreshing bug

Some Manifests were never refreshed (mainly DASH contents, but also Smooth ones in some specific use-cases) due to an unfortunate mix-up made in the v3.10.1 release.

We also improved on the interval at which some DASH MPD were refreshed. It should now happen less often.

DRM issue on Edge

The work-around we brought to a IE11/Edge issue with encrypted contents in the v3.10.1 did not seem to provide good enough results with our test contents.

We now adopted another strategy, which is to move CENC PSSH boxes at the end of the initialization data.

Simply put:

  • previously we made two tries on IE11/Edge: one with the problematic data, the second without (only called if the first failed)
  • now we directly put the problematic data at the end on the first try

This new method provided better results with our test contents. Do not hesitate to open an issue if you still experience KEY_GENERATE_ERROR errors with encrypted contents on IE11/Edge.

Jest and unit testing

To limit regressions like the one we fixed in this release, we decided to put more and more of our time on tests.

Multiple months ago, we reinforced our end-to-end tests which automatically launch contents, perform some manipulation on them (change the speed, seek everywhere) and check that everything is ok.

If those tests definitely helps us to ship new releases confidently, we still had specific areas of our code that was vulnerable. One of those was live contents, for which end-to-end tests are difficult to write as those evolve over time.

For those issues, we tried to implement a reliable unit testing strategy for the v3.10.1. However, we went into multiple problems: the tools we used at the time were not adapted. After taking different paths, we decided to rely on Jest running in a Node.js environment for our unit tests.

This choice was mainly motivated by the fact that it was the less troublesome tool to use with our specific situation (TypeScript code + TypeScript tests, globally defined variables, coverage reports, high necessity of dependency injection).

We're now happy to announce that the unit test coverage of our code went just from a (minuscule) 13% in the v3.10.1 to a (less minuscule) 22% in the v3.10.2, and that only in a few days! We concentrated our efforts on sensitive parts of our codebase for now but we definitely want to approach as much as possible 100%.

For now however, at least 10% more coverage for each release seems to be a doable objective.

Changelog

Bug fixes

  • dash/smooth: fix manifest updates for some DASH contents (SegmentTimeline without SegmentTemplate) and for some Smooth usages
  • compat/drm: adopt a new strategy for malfunctioning CENC PSSH on Edge by moving them at the end of the initialization data
  • dash/smooth: update deprecated Manifest.adaptations property when updating the manifest

Other improvements

  • dash: refresh the MPD less often
  • dash/smooth: improve precision of getMaximumPosition when the Manifest is updated
  • tests: use the Jest library for unit tests
  • tests: add a lot of unit tests to sensitive code (from a coverage of 13% in the v3.10.1 to 22% in the v3.10.2)
  • npm: reduce size of the npm package

v3.10.1

03 Jan 16:08
ec0e29a
Compare
Choose a tag to compare

Release 3.10.1 (2019-01-03)

Overview

The v3.10.1 fixes minor issues:

  • adaptive: fix an issue which could lead our adaptive logic to be less performant
  • drm: fix issue with Edge and IE11 where encrypted content could not be played
  • dash: become more tolerant on what DASH MPD we accept
  • dash/smooth: throw a clearer MANIFEST_PARSE_ERROR when the MPD/Manifest given propose an audio or video track with no supported codec

Behind the hood, it also embarks a cleaner code architecture - which will help us to bring future improvements (improved adaptive streaming, xlinks in onResolve mode...).

adaptive: fix non-urgent switches issue

In the v3.9.0 release, we brought support to non-urgent quality switches. The difference between an "urgent" and a "non-urgent" quality switch is that:

  • an urgent switch will interrupt any download of the previous quality and begin to download the new one
  • a non-urgent one will wait before the previous quality finishes its download before truly switching the quality

However, we had a bug in this logic. If multiple switches were triggered while an old quality did not have time to finish to download - which is the case if at least the first one was non-urgent - only the first quality switch would then be taken into account (instead of the last one).
This behavior would then continue and the result would be a lag in quality switches.

This is now fixed.

DRM/EME: Fixed issue with Edge/IE11

An issue localized somewhere between the Edge and IE11 browser and the PlayReady CDM prevented the RxPlayer to play some encrypted content.

On some contents containing a CENC (for Common ENCryption) PSSH, which simply put, is a part of an MP4 file containing encryption-related informations, the browser would reject those informations leading us to stop the content and emit an EncryptedMediaError.

The CENC PSSH in itself was well-formed and should have worked with any browser. With that in consideration, we decided to adopt a safe strategy:
For now, if encrypted informations which contains such metadata is not accepted by IE11 or Edge, we will retry without that data. If it fails again, the usual EncryptedMediaError error will be thrown.

DASH: MPD tolerance improved

We accept now much more DASH's MPD than in the previous thanks to the following improvements:

  • In SegmentTimeline-based MPD, we now support S nodes which have their r ("repeat") attributes set to -1 (which means, repeat indefinitely)
  • In SegmentTimeline-based MPD again, we also now infer the time of the first S node if it was not declared as its t attribute
  • we now better calculate the minimum time we can seek to in an MPD

DASH/Smooth: throw better error when no audio or video codecs are supported

After downloading a DASH/Smooth MPD/Manifest, we usually filter out media with a codec not supported in the current browser.

We can arrive in a case where the MPD/Manifest announce video and audio tracks, but one of those have none of their codecs supported. As a player, we face now two choices:

  • we could play the content without audio or video
  • we could throw to warn the user that this content is not supported

Although the first case could look like the better solution, real-life cases made us prefer the second one, as such contents are not intended to be shown without audio or video.

Previously, the fatal error sent was very cryptic (about not being able to read "length of undefined"). Now, a proper MANIFEST_PARSE_ERROR with a descriptive message is sent instead.

Code architecture refresh

For those interested in our code architecture, we also refreshed our code and updated our modules to be easier to follow:

  • the Stream is now renamed the Init, as its main role is to initialize and start every modules necessary to play a content. The name is of course short for "initialization".

  • the net directory has been renamed transports, its role being to define a layer where streaming protocol-specific loading and parsing takes place (and not just for internet request as the previous name could indicate)

  • the complex buffer directory has been renamed buffers and separated into clear sub-modules:

    • The PeriodBufferManager has been renamed the BufferOchestrator: its role is to create the right PeriodBuffers at the right time and to react to their events.
    • The PeriodBuffer is now clearly defined in its own directory (it was previously included in the PeriodBufferManager). Its role is to create the right AdaptationBuffer depending on track choices.
  • multiple "somethingManager" have been completely renamed to better communicate what their role are. For example the MediaErrorManager became throwOnMediaError and the SpeedManager was renamed updatePlaybackRate.

The code architecture documentation has been properly updated.

Changelog

Bug fixes

  • abr: always consider the last quality estimation
  • drm: work-arround Edge bug where the browser does not accept a valid CENC PSSH (DRM-related information in an ISOBMFF)
  • dash: handle S nodes (segments) with an @r attribute at -1 in an MPD
  • dash: handle SegmentTimeline which have as a first S node (segment) an undefined @t attribute in an MPD
  • dash: Representation.index.getLastPosition() for SegmentBase-based DASH Representations now returns the end of the last segment (it returned the start of the last segment before)
  • dash/smooth: throw better error (MANIFEST_PARSE_ERROR) if none of the audio or video tracks of a content can be played (e.g. none have supported codecs)

Other improvements

  • manifest: better infer the minimum time of a Manifest
  • code: refresh code architecture (rename and move modules, remove some dependencies...)
  • tests: add coverage reports for both unit and "integration" tests, to check where tests are lacking and better pin down our hot-spots
  • tests: add appveyor countinous integration service for unit tests

v3.10.0

11 Dec 18:32
c70f932
Compare
Choose a tag to compare

Release 3.10.0 (2018-12-11)

Overview

The v3.10.0 brings a lot of features and improvements:

  • dash: the player now handle DASH' XLinks in "onLoad" resolution mode
  • dash: adaptation-set-switching is now available
  • compatibility: we improved the API to allow a cleaner management of browsers restrictive autoplay policies
  • compatibility: we fixed many other compatibility issues and inconsistencies
  • and more

DASH: XLink management for the "onLoad" resolution mode

XLink is a specification allowing to refer to external links in a given XML document. In the context of DASH, it can be used to define a single or multiple Periods not directly in the Manifest, but via another external ressource.

DASH' XLinks can come in two flavors:

  • in an "onLoad" resolution mode: the corresponding link is loaded as soon as the Manifest is loaded

  • in a "onRequest" resolution mode: the corresponding link is only loaded when we need it.

For the moment, only the onLoad flavor is handled, but onRequest support should come very soon in one of our next release.

DASH: adaptation-set-switching

The RxPlayer already handle advanced DASH features such as multiple media licenses for different media qualities.

This comes with several drawbacks however, such as the obligation to divide such qualities into separate DASH AdaptationSets, which the player precedently handled as different unrelated tracks. To allow seamless switching between those, we had to support a specific DASH feature called adaptation-set-switching.

As managing this advanced feature could complexify a lot our API, we decided to provide a straightforward implementation: "switchable" AdaptationSet having similar characteristics are now merged into a single RxPlayer's Adaptation.

This means that the RxPlayer definition of an Adaptation is slightly different than a DASH AdaptationSet. To clarify that difference, we decided to add a new documentation page.

Better autoplay policies management

Due to browser's policies a play action can be completely blocked by the browser. This is often done as a mechanism to prevent a video from being played without any user interaction.

To alert users when a call to play failed, we decided to bring two new features:

Compatibility improvements

As with the last releases, we continue towards improving our compatibility across all browsers:

  • we added a new warning: "MEDIA_ERR_METADATA_NOT_LOADED", triggered when we're unable to load the current content. For the moment, this problem has only been seen on the Samsung mobile browser, when playing a content in directfile mode. This error is documented here.

  • we re-defined when our LOADED state should be set, to be sure it is the same definition across all browsers. Until now, the state could arrive too soon on Firefox leading sometimes to a SEEKING or PAUSED state without any interaction.

  • we fixed an issue we had with Smooth Content on Edge, which prevented some contents to be played with that browser

  • we fixed an issue we had with the MediaCapabilitiesProber on Safari

  • we provide an implementation of Promise for browsers not supporting it

Deprecating NetworkError "xhr" property

To prepare the management of CMAF low-latency and other advanced features, we decided to deprecate the xhr property, as found in a NetworkError.

This is because those new features might lead us to use the fetch API instead of an XMLHttpRequest, which is necessary in the current NetworkError API.

Changelog

Features

  • dash: Manage xlinks in "onLoad" resolution model
  • dash: Implement AdaptationSet switching by merging similar and switchable AdaptationSet into a single track
  • compat: add MEDIA_ERR_METADATA_NOT_LOADED warning, triggered when the browser has issues with loading the initial data (only seen on the Samsung mobile browser in directfile mode)
  • compat: add MEDIA_ERR_PLAY_NOT_ALLOWED warning, triggered when the application tries to play but the current browser doesn't allow it (often due to autoplay policy)
  • api: the play API now returns a Promise, mirroring the original browser's play API

Deprecated

  • api: The xhr property from a NetworkError is now deprecated

Bug fixes

  • compat/smooth: fix fatal error BUFFER_APPEND_ERROR happening on some HSS contents with Edge
  • dash/smooth: never refresh the manifest if its content is not dynamic
  • dash/smooth: use new URL if the initial manifest request is redirected (again :/ - thanks @fnatte)
  • api: do not go out of the LOADING state if the metadata could not be fetched (even if the browser tells us otherwise) - to work around Samsung Browser bug
  • api: avoid going out of the LOADED state until the initial seek is done and metadata is fetched
  • compat: use Promise ponyfill to improve IE11 compatibility with the MediaCapabilitiesProber and some EME functionalities
  • api: translate most IETF language tags into corresponding ISO639-3 codes for the normalizedLanguage property - given from APIs such as getAvailableAudioTracks
  • tools: fix mediaCapabilitiesProber.getCompatibleDRMConfigurations experimental tool on Safari
  • api: filter out duplicates in getAvailableVideoBitrates and getAvailableAudioBitrates

Other improvements

  • dash: better infer unknown Period durations
  • dash: better manage overlapping Periods by giving more importance to the last chronological one
  • memory: clean-up Adaptation and Representation informations on Periods which are not considered anymore
  • log: warn through our logs every time a warning event is sent by the API
  • demo: authorize DRMs in IE11 or Safari when in HTTP in the demo page
  • demo: fix time indication for non-live contents

v3.9.3

23 Nov 14:38
5a8f7b6
Compare
Choose a tag to compare

Release 3.9.3 (2018-11-23)

Overview

The v3.9.3 fixes minor compatibility issues and continue our efforts toward reinforcing our automated tests.

Compatibility issues with IE11

There were two compatibility issues that could arise mainly with Internet Explorer 11:

  • some code in our adaptive logic used called Object.values, which is not defined in that browser (as well as in old webkit versions which we use internally)
  • the mediaCapabilitiesProber.getCompatibleDRMConfigurations called Array.prototype.find, which is not available in IE11 as well

Thankfully, most of our users seem to use polyfills which allow to completely avoid those issues.

We could use polyfills in the Rx-player but we voluntarly choose not to. This is because as a library, we avoid doing any side-effect that could conflict with another codebase (for example, our polyfill could overwrite yours, which could have more features).

As this is not the first time we used an API not available in IE11, we now added an automated check in our validation process which alerts us when such API call is written in our code.

This should avoid most issues of the same type in the future.

Compatibility issue with Safari

A very specific compatibility issue was found on Safari, where a modification we did on the MediaKeys object could provoke issues when using another DRM-aware media player.

This side-effect was written as part of a legacy code to improve our compatibility with older browsers.
Since then, monkey-patching has been a banned practice in the player, again to make sure our library does not conflict with your codebase.

By the way, the RxPlayer should now be (finally) completely free of such patches 🎉

EME optimization on Edge

We have an EME (DRM)-related optimization in the RxPlayer, which allows the player to re-use created key sessions.
This allows to load an encrypted content much faster when that content was already loaded before.

However, our previous logic did not allow the Edge browser to profit from that optimization, as we had a really conservative way to authorize it (basically, it was forbidden because IE11 could not profit from it).

We now became confident enough to allow this optimization on Edge.

Automated tests reinforcement

After the HSS issue which triggered the v3.9.2 release (about not accepting empty tracks), we became a lot more realist of our ability to completely avoid or at least detect in advance regressions.

Our current validation policy involves running automated tests and manual "shallow" checks. Unfortunately, we do not have the ressources necessary to manually check every edge case (nor do we think that this would be efficient).

That's why we are currently putting a lot of effort towards automated tests. Those are mainly validating the behavior of the library as a whole and its effect on a page as we believe that such tests are especially adapted to a media-player library.

We now automatically check for that HSS regression (as well as other, older ones). We will from now on try to do the same thing for most encountered issues in the future ("most" as many are only reproducible on specific browsers for which it's hard to launch tests from) and for new features.

Changelog

Bug fixes

  • compat: fix undefined Object.values function issue happening in some older browsers (mainly encountered in IE11 and old webkit versions)
  • compat: remove side-effects relative to DRM on Safari
  • tools: fix issue about an undefined Array.prototype.find method in some older browsers when calling mediaCapabilitiesProber.getCompatibleDRMConfigurations (mainly encountered in IE11)

Other improvements

  • eme: activate MediaKeys caching on Edge
  • compat: add in our validation process a ban of methods and functions unavailable in older browsers
  • tests/smooth: reinforce our Smooth Streaming integration tests

v3.9.2

14 Nov 13:22
471acfe
Compare
Choose a tag to compare

Release 3.9.2 (2018-11-14)

Overview

This (very small) release fixes a bug introduced in the v3.9.1.
In this version, the player threw if a smooth Manifest proposed an audio, video or text track without any segment (an empty track).

We fixed that issue by being more resilient in that case: empty tracks are now correctly managed (even if switching to them has no utility).

As this is a playback-stopping issue, and as this case is encountered by some of our users, we decided to directly ship a release with only this fix.

We're sorry for the inconvenience, we will write a corresponding automated test in the following release to make sure this type of issue cannot happen again.

Changelog

Bug fixes

  • smooth: authorize empty tracks ("StreamIndex") in Smooth manifests

v3.9.1

13 Nov 11:45
61a9959
Compare
Choose a tag to compare

Release 3.9.1 (2018-11-13)

Overview

This release fix issues regarding the manifest-refreshing logic for both Smooth and DASH:

  • for smooth contents, the player could stall indefinitely when playing a live content close to the live edge and switching a text, audio or video track

  • for dash contents with a minimumUpdatePeriod attribute and a customManifestLoader argument given to loadVideo, the manifest could be refreshed too often

To lower the memory usage when playing Smooth live contents for a long time, we also now clean-up regularly the informations we have on segments becoming unreachable.

Infinite rebuffering issue with Smooth live contents

The main fix concerns Smooth contents, where the player could stall indefinitely when playing live contents.

It was due to two issues in our Smooth Manifest refreshing logic:

  • we overwrote the previous segment informations we had when refreshing the manifest
  • we had a time-conversion error which prevented emergency Manifest updates to happen

This could mostly be experienced when switching to another audio track in specific situations (live content, close to the live edge...), those two issues could combine and lead ultimately to a player staying in a rebuffering state.

This release fixes both of these issues.

Changelog

Bug fixes

  • smooth: fix issue preventing emergency manifest updates
  • dash: fix timeout for minimumUpdatePeriod in cases where the time at which the manifest was last requested is not known (like when setting a customManifestLoader argument)

Other improvements

  • smooth: keep supplementary segment informations when updating the manifest
  • smooth: when updating segment informations, perform garbage-collection of those concerning unreachable segments

v3.9.0

08 Nov 19:28
8775d4c
Compare
Choose a tag to compare

Release 3.9.0 (2018-11-08)

Overview

The v3.9.0 brings some new features and continue our serie of improvements made on the adaptive side.
Most notably, it brings:

  • management of the minimumUpdatePeriod attribute for DASH contents
  • seamless codec-switching for browsers supporting the changeType API
  • a more intelligent bitrate-switching algorithm, which can decide to let the current segment requests to be finished before switching

As an enjoyable side-note, this release contains three outside contributions:

  • @fnatte worked on the initial minimumUpdatePeriod feature and on a TypeScript typing bug.
  • @necccc worked on reducing the size of our npm package (which is now divided by three!)

Thanks again to both of them.

minimumUpdatePeriod

minimumUpdatePeriod is an attribute found in DASH MPDs which indicates an interval at which the manifest should automatically be refreshed.

The RxPlayer previously refreshed the manifest only when it needed it (this usually means when available segments it needs were not yet declared in the last downloaded manifest), which is fine in most cases.

Now, we also consider the minimumUpdatePeriod to decide when to refresh it.
This allows more complex usecases where the manifest can change unexpectedly over time (e.g. an evolving timeshift window).

Codec-switching thanks to the changeType API

The changeType API allows us to seamlessly transition from one codec to another.

In the RxPlayer, we now detect when the content is switching to a new codec and call changeType if this API is available.
Please note however that this API is very new (at the moment, it is only in Chrome 70+ and Firefox 63+).

adaptive improvements

We worked a lot on our adaptive streaming algorithm lately, which is the part of the code deciding which video or audio quality should be downloaded depending on the user's situation (such as its network bandwidth).

This is what we brought in the v3.9.0:

Bitrate switching urgency

We added a notion of "urgent" changes of video or audio bitrates.

Simply put, if a change is urgent, pending segment downloads relative to the old bitrate will be canceled, and segment downloads relative to the new bitrate will start immediately.
If a change is not urgent however, we wait for the current segment request(s) to finish before switching to the new bitrate.

Previously, only the urgent mode was available, which can be seen as more "costly" than the "not urgent" mode, because it means that we might throw some already-downloaded bytes.
The urgent mode has its own advantages though, it allows the player to adapt to the bandwidth more rapidly and can help to avoid rebuffering when the bandwidth fall down.

At the end, using both modes depending on the situation seems to be the best of both worlds. This is what we do now.

Raise the bitrate estimation frequency

We now perform new bitrate estimations much more often (each time we have a new bandwidth metric - usually after each request) than before (where it was at a regular interval and important user events).

This allows to react to new network conditions faster, most notably at the beginning of the content.

Fix priority updates

Segment priorities is an advanced fetching optimization. How it works can be simplified as such: we assign to each wanted media segment a "priority" depending on its distance with the current position (closer segments have a higher priority).
Every requests with the same priority can run at the same time, while those with a lower-priority wait for their turn.

This feature allows a great flexibility. Thanks to it, we can allocate more bandwidth to closer segments (to avoid rebuffering) and still optimize the bandwidth usage when we're considering distant segments (we can for example download an audio segment beginning in 25 seconds at the same time than a video segment beginning in 20 seconds).

As playback conditions evolve over time (for example, when the position in the content changes), those priorities can also need to be updated over time.
Previously, an issue prevented priority updates to be functionnal, this should now be completely fixed.

Memory tests

In our previous release (the v3.8.1), we fixed a memory leak we had for some time.
Because the RxPlayer targets devices with relatively important memory constraints (such as set-top boxes), this was a pretty big issue for us.

As a first step, we decided to add memory tests, specifically ensuring that the RxPlayer's memory consumption stays at an acceptable level. For now, only a single memory test is written, checking the memory usage after loading a video 1000 times. More should come in the future.

Changelog

Features

  • dash: consider minimumUpdatePeriod attribute in MPDs
  • buffer: add codec-switching for browsers supporting the SourceBuffer.prototype.changeType API
  • dash/smooth: accept and parse segments with a "stpp.ttml.im1t" codec (TTML IMSC1 in MP4)

Bug fixes

  • smooth: fix calculations of the initial time, duration and minimum position for HSS VOD contents not starting at a '0' time
  • buffer: fix priority updates for segment requests
  • dash: calculate VOD duration from the last period if undefined in the MPD's root
  • dash: remove possibility of obtaining two periods with the same id
  • typings: make manualBitrateSwitchingMode loadVideo option an optional TypeScript typing (thanks @fnatte again!)

Other improvements

  • abr: do not always cancel pending requests when switching to a new bitrate
  • abr: re-estimate the bandwidth immediately after each request
  • buffer: remove automatic garbage-collection of the "image" source-buffer (its rules should be more complex than those in place)
  • tools/mediaCapabilitiesProber: Make getCompatibleDRMConfigurations work under IE11 and old webkit versions
  • tools/mediaCapabilitiesProber: Add a multitude of bug fixes to the experimental mediaCapabilitiesProber
  • package: divide by more than 2 the size of our package published in npm (thanks @necccc)
  • tests: add memory tests to detect memory leaks
  • demo: add 'favicon' to the demo page

v3.8.1

17 Oct 14:49
935e960
Compare
Choose a tag to compare

Release 3.8.1 (2018-10-17)

Overview

The v3.8.1 fixes some issues and delivers some improvements on the adaptive side:

  • fix memory-leak in adaptive logic
  • set the right video quality faster on the first loadVideo
  • perform better bandwidth estimation when downloading from misconfigured servers
  • avoid re-attaching the optional serverCertificate at each quality switch for encrypted contents

Memory leak in adaptive logic

We found out that a callback performing some computations useful for adaptive streaming was never cleared, even when the content was stopped.
This dates back from some time (v3.5.2) and was due to a still ongoing issue with RxJS, the main library we use.

As this callback only performed relatively simple computations without interacting much with the rest of the code, the only problem was that the memory and CPU usage could be too high after loading too many contents.

This issue is now completely fixed.

Better video quality faster on first loadVideo

We currently are improving our adaptive algorithm, which chose the best quality possible depending on the bandwidth.

Before all those improvements are released, we bring here a few which mainly improve the speed with which the right quality is set on the first loadVideo call.
If you want more details, we did some experiments and found out that we could profit from lowering two values:

  • the minimum number of bytes to download before we perform the first bandwidth estimation
  • a value dictating whether better quality content should be downloaded to replace some lower-quality content already buffered.
    Basically here, we replace more aggressively the current buffer if it means a better quality will be shown instead.

Those modifications should mostly have an effect when the quality raises and thus should not have a big impact on the frequency of rebuffering.

Better bandwidth estimation when downloading from misconfigured servers

We previously relied on the "Content-Length" header to know the size of downloaded segments, which we use to estimate the bandwidth.
We found out that some misconfigured servers sometimes send a wrong "Content-Length", often when we do byte-range requests.

To be more resilient, we decided to directly rely on the length in bytes of the response (the downloaded segments) instead.

Avoid setting the serverCertificate at each quality switching

Note: This only affects you if you set a serverCertificate when playing an encrypted content.

Due to evolutions regarding key rotation and multi-key contents, we made some changes on encrypted contents which led to a server certicate being set at each quality switch (instead of a single time).
Although that behavior causes no problem when decrypting the content, this is unnecessary and lead to pointless warning events triggered with the code "LICENSE_SERVER_CERTIFICATE_ERROR".

We fixed that by going back to the previous behavior, the certificate is now only set once at the beginning of the playback.

Changelog

Bug fixes

  • abr: fix memory leak in ABR Management
  • eme: avoid re-attaching a server certificate at each encrypted event

Other improvements

  • buffer: lower the "paddings" applied to the video buffer when raising the quality
  • abr: when pratical, avoid relying on the "Content-Length" header to protect against miscalculations when downloading from misconfigured servers
  • abr: lower the minimum number of bytes we wait to download before we evaluate the bandwidth
  • abr: use performance.now instead of Date.now for better precision
  • module: move express from the dependencies to the devDependencies
  • demo: fix standalone demo and add possibility to launch it via HTTPS

v3.8.0

11 Oct 15:11
b7acce1
Compare
Choose a tag to compare

Release 3.8.0 (2018-10-11)

Overview

This release comes with multiple new features:

  • you can now provide a callback to loadVideo to prevent some Representations (i.e. media qualities) from being played (can be useful when you know a device won't be able to play such media quality).

  • the new manualBitrateSwitchingMode loadVideo option allows for more direct quality switches

  • we now provide directly a warning when the current position is out of the bounds of what is available in the manifest

representationFilter API

DASH and Smooth contents are often constituted of multiple video and audio qualities. This allows for example adaptive streaming, where a lower video quality could lead to less buffering and thus a better user experience.

In some advanced use-cases you might want to prevent some of those qualities from being played. One of those use-cases is when you know in advance that a particular quality won't be decodable by the current device.

To answer that need, we added representationFilter, a new user-provided callback to the transportOptions you can provide to loadVideo.

For more informations on it, you can find the transportOptions documentation here and more specifically the representationFilter documentation here.

Manual bitrate switching modes

Previously, when you updated the current video or audio quality manually through respectively the setVideoBitrate and setAudioBitrate APIs, you wouldn't see the quality switch right away: You would actually see the previous quality being played for some amount of time and then progressively the new quality taking its place.

This was because those APIs didn't "flush" the previous buffers: the previous quality stays here and is replaced progressively as you continue to play.

That seamless switch allows a smooth transition, but depending on your player implementation you might want to provide the quality switch directly if a user ask for it (e.g. like YouTube does when you set a particular video resolution from their player interface).
To let you choose what behavior you want, we added a new loadVideo option called manualBitrateSwitchingMode. By default, it stays at the old "seamless" behavior, but you can switch to "direct" to profit from a more direct switch.

Documentation on manualBitrateSwitchingMode is available here.

Warnings when the current position is out of the bounds of the manifest

We added two warnings:

  • when the position is before the first time declared in the manifest

  • when the position is after the last time currently declared in the manifest

Those two warnings have respectively the MEDIA_TIME_BEFORE_MANIFEST and MEDIA_TIME_AFTER_MANIFEST.

They are mostly useful when you play live contents.

For example, live contents often don't have an unlimited buffer depth, meaning that you won't be able to seek in the past indefinitely.
As such, if your position is too far behind, you can be in a situation where the player will buffer indefinitely. This is how you might want to workaround this problem:

player.addEventListener("warning", (warning) => {
  if (warning.code === "MEDIA_TIME_BEFORE_MANIFEST") {
    // seek and play 5 seconds after the current minimum position
    const minimumPosition = player.getMinimumPosition();
    player.seekTo(minimumPosition + 5);
    player.play();
  }
});

Those warnings were added to the errors and warnings documentation.

Automatic garbage collection of subtitles and thumbnails

Subtitles and thumbnails buffers are entirely managed by the RxPlayer, without the help of the browser (as opposed to audio and video buffers).

As we have much less informations on the memory available than the browser does, we won't be able to clear them a little when the user's computer is low on memory.

Because of this, we now regularly clean those two buffers 5 hours behind and ahead of the current position.
This is a minor move to avoid memory problems when the user is playing a content for very extended amount of time.

These 5 hours values can be seen and updated in the config (it is now called MAXIMUM_MAX_BUFFER_AHEAD and MAXIMUM_MAX_BUFFER_BEHIND in there).

Changelog

Features

  • api/dash/smooth: add representationFilter API to prevent Representations (i.e. media qualities) from being played
  • api/buffer: add manualBitrateSwitchingMode option to allow a direct representation switch when calling setVideoBitrate and setAudioBitrate
  • api/buffer: emit a MEDIA_TIME_BEFORE_MANIFEST warning when the wanted time is before what is announced in the manifest
  • api/buffer: emit a MEDIA_TIME_AFTER_MANIFEST warning when the wanted time is after what is announced in the manifest

Bug fixes

  • remove export of undeclared ICompatVTTCue from modular build

Other improvements

  • buffer: to avoid taking too much memory, regularly clean-up text and image buffer 5 hours ahead/behind the current position (customizable)
  • demo: add HTTPS capabilities on local full demo
  • rxjs: update rxjs to 6.3.3
  • typescript: update typescript to 3.1.2

v3.7.0

21 Sep 14:50
c131a20
Compare
Choose a tag to compare

Release 3.7.0 (2018-09-21)

Overview

This release mainly brings improvements for DRM (EME) matters:

  • it improves license expiration management
  • it adds the possibility to skip license updates
  • it replaces the experimental tool mediaCapabilitiesProber.isDRMSupported by the more useful mediaCapabilitiesProber.getCompatibleDRMConfigurations

It also brings multiple minor bug fixes:

  • DASH: We now consider multiple Role nodes for an AdaptationSet
  • Smooth: we fixed some minor URL parsing bugs (note: some legacy behavior has been deprecated see the Deprecated Smooth Behavior chapter for more information)
  • TypeScript: we fixed some problems of missing interfaces people where having when type-checking our library
  • API: we fixed some minor state bugs

Last but not least, we have now a new demo page that manage encrypted contents.
We also added a LOT of integration tests.

DRM: expiration management

In previous versions, managing license expiration was really hard for the following reason: we stopped with an error as soon as a currently-used license expired.
License renewal was still possible, but it had to be done before it was expired.

For our current use-cases, expiration management becomes much more important. This is why we chosed to improve this situation for this release.

This issue was REALLY easy to fix, the problem was that just doing so would break our current API. Now, applications which do not manage license expiration might be blocked infinitely in a rebuffering situation where previously, they would have just stopped and displayed an error screen (which, arguably, might be preferable).

Due to that situation, we chosed to introduce a new possible property in keySystems (the loadVideo option): a boolean called throwOnlicenseExpiration.
It is set to true by default to ensure compatibility with our previous API but you can set it to false explicitely to continue playback even when a license is expired (you can still be notified about expiration through a warning with a "KEY_STATUS_CHANGE_ERROR" code or the optional onKeyStatusesChange callback - also from keySystems).
Then, the usual getLicense callback (keySystems) should be enough to perform renewal requests.

The throwOnLicenseExpiration property is documented here.

DRM: avoiding license updates

License updates are done through the rx-player via two user-provided callbacks:

  • getLicense: triggered every time the content decryption module (or CDM) of the browser send us a message, usually to request a license
  • onKeyStatusesChange: optional callback triggered every time the status of a current decrypting key changes

Both can return a license or a promise resolving with a license, which will then be passed to the underlying CDM.

The problem with that approach is that you might not want to update the license each time a message is sent by the CDM or each time the status of a key updates.

To allow users to "skip" license updates, we added the possiblity to return null or a promise resolving with null to both of these callbacks.

We updated accordingly the documentation on the keySystems option.

getCompatibleDRMConfigurations experimental tool

In the v3.5.0, we added the mediaCapabilitiesProber experimental tool which included a isDRMSupported function, to test which key systems were supported in the current browser.

After feedbacks from users, we found out that this API was not very useful.
As a result, we replaced it by a more complete getCompatibleDRMConfigurations function and we are now waiting for your feedbacks on it.

The status of this API is still possible to evolve, as we're still trying to find out your needs on encryption-related tooling.

You can find documentation on the mediaCapabilities in the corresponding documentation page.

Deprecated Smooth Behavior

Previously, we authorized ".isml", ".ism" and ".wsx" URL when loading a Smooth streaming content due to some legacy use-cases.

We deprecated that behaviour to incite people to set the Manifest URL directly.

Changelog

Features

  • eme: add throwOnLicenseExpiration boolean to keySystems (loadVideo option) to allow better expiration management
  • eme: in the getLicense property of keySystems (loadVideo option), it is now possible to resolve with null to avoid a license update.
  • eme: in the onKeyStatusesChange property of keySystems (loadVideo option), it is now possible to resolve with null to avoid a license update.
  • tools: replace experimental tool mediaCapabilitiesProber.isDRMSupported by the more useful mediaCapabilitiesProber.getCompatibleDRMConfigurations

Deprecated

  • smooth: giving a WSX URL instead of the Manifest URL for a smooth content is now deprecated.
  • smooth: giving a publishing point definition URL (.isml) instead of the Manifest URL for a smooth content is now deprecated.
  • smooth: giving a Smooth Streaming server manifest URL (.ism) instead of the Manifest URL for a smooth content is now deprecated.

Bug fixes

  • api: switch state to "ENDED" if seeking to the end while the player is in the "LOADED" state.
  • api: switch state to "SEEKING" if seeking in the content while the player is in the "LOADED" state.
  • dash: consider multiple Role nodes for an AdaptationSet.
  • typescript: fix typings error when an application build us without the skipLibCheck TypeScript option enabled.
  • smooth: fix Manifest URL generation when a ".ism" or a ".isml" URL is given.
  • doc: document deprecation of the adaptations property returned from a Manifest object (as returned from the getManifest method).

Other improvements

  • doc: add quick start tutorial.
  • doc: add player states documentation.
  • demo: add possibility to play encrypted contents.
  • demo: update demo page.
  • tests: consolidate our integration tests.