Skip to content

v4.0.0-beta.0

Pre-release
Pre-release
Compare
Choose a tag to compare
@peaBerberian peaBerberian released this 27 Jan 15:33
· 591 commits to next-v4 since this release

Release v4.0.0-beta.0 (2023-01-27)

Quick Links:
πŸ“– API documentation - ⏯ Demo - πŸŽ“ Migration guide from v3

πŸ” Overview

The first v4.0.0 beta version, v4.0.0-beta.0 is finally here!
The focus of this release was to provide a better API in the now more evolved streaming landscape, especially to better handle DASH multi-Period contents - which are becoming more and more frequent (thanks to new server-side features such as ad-switching, key rotation, live contents with multiple track lists depending on the program etc.). Another main point of this new major release was to clean-up deprecated features from the API, some preventing us from doing advanced work we plan to make in the future.

This is a very big release in terms of changes but don't be scared! This beta version represents a v4 API which though it can be seen as stable (after a less stable, mostly internal, alpha phase), can still evolve before its official release if issues with it are spotted. Also, new v3 releases with bug fixes, improvements and even features will still be made for the foreseeable future.

The goal of this first open beta release is too give you time to make the switch, ask questions, propose changes and report issues that you see with it.
Because we want to make the migration experience as painless as possible, we wrote a complete migration guide, accessible in our documentation pages for the v4.

As the changelog is here pretty big and thus less interesting to read. we moved it back at the end of the release note for this release only.
Also note that some of the changes made in this beta release will be brought in the next v3.30.0 release. They also will be documented in the corresponding release note.

Note: As this is not a stable release, installing/upgrading to it must generally be done explicity, either by adding the rx-player@v4.0.0-beta.0 package through your package manager, by adding it through its next tag (which will point toward the last beta release), by explicitly specificying its version on your package.json file(s), or through other related techniques.

A new player state: "FREEZING"

A new player state (gettable either through the playerStateChange event or the getPlayerState method) has been added: "FREEZING".

It's important to note that this new new state does not characterize a new behavior, it only put a better word onto a specific problematic playback state. Previously, it was either reported as a "BUFFERING", "SEEKING", or even "PLAYING" state depending on the situation.

This state appears when playback is temporarily stuck in place, though in opposition to the more usual "BUFFERING" and "SEEKING" state, this is not due to buffer starvation but to another, generally unknown, factor. As such, it can in most cases be handled just like a "BUFFERING" state in your application (e.g. by displaying a spinner on top of the media element) but it may be logged differently to help you pinpoint playback issues.

buffering
Screenshot: A "FREEZING" state can be treated just like a "BUFFERING" one, here with a pink spinner on top of the video.

Under that state, which is generally much rarer than a "BUFFERING" state for example, the RxPlayer will try various tricks to try to un-freeze playback. If they become too frequent or if those tricks don't work, it might be an issue worth investigating.

A more flexible track API

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 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);
}

The new track API, which is still compatible with the old one (meaning the old calls still work), now allows to set the track for any Period:

// Example setting a french audio track for the first Period if found
// and an english track for the second (curious use case, but why not?)
const availablePeriods = rxPlayer.getAvailablePeriods();
if (availablePeriods.length >= 2) {
  const availableAudioTracks1 = rxPlayer.getAvailableAudioTracks(
    availablePeriods[0].id
  );
  const frenchAudioTrack1 = availableAudioTracks.find((track) => {
    return track.language === "fra";
  });

  if (englishAudioTrack1 !== undefined) {
    rxPlayer.setAudioTrack({
      trackId: englishAudioTrack1.id,
      periodId: availablePeriods[0].id,

      // Note: it's now also possible to set the switching mode per-track change
      switchingMode: "direct",

      // It's also possible to only authorize some Representations from being
      // played
      lockedRepresentations: englishAudioTrack1.representations
        .filter((representation) => {
          // Only authorize Dolby Digital+ Representations from this track
          return representation.codec === "ec-3";
        });
    });
  }

  const availableAudioTracks2 = rxPlayer.getAvailableAudioTracks(
    availablePeriods[1].id
  );
  const englishAudioTrack2 = availableAudioTracks.find((track) => {
    return track.language === "eng";
  });

  if (frenchAudioTrack1 !== undefined) {
    rxPlayer.setAudioTrack({
      trackId: frenchAudioTrack1.id,
      periodId: availablePeriods[1].id,
    });
  }
}

As you can see, the newer syntax allows more flexibility than the previous one. However it should be noted that the old syntax still work and still update the track for the currently-playing Period.

Removal of the track preferences API

When associated with new RxPlayer events also added in this version, the new track API make the preferences API re-implementable in its entirety by an application.

Because of this, and after much thinking on our side, we decided to remove the track preference API from our v4.0.0 even if we understand that it implies some work on your side to make the switch.

Don't worry the new track API is both easy to understand and more flexible than the set of methods and options that were part of the track preferences API. We also made a complete preference migration guide here, which includes code to completely replace the old preference API.

Do not hesitate to open an issue if you find that documentation not too clear or even if you're not OK with the removal of the old track preference API.
To be perfectly honest, we're still hesitating and we may bring it back in the future if it proves to have clear advantages. But for now, the new track API just seems more complete and easier to understand for applications (we had in the past several issues from people poorly understanding the behavior of the preferences API), which is why we're orienting you towards it.

Improved Representation selection

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 height (or some Representation with an `undefined`
    // height if none is defined).
    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.

Sadly, we 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

Removal of deprecated options and methods

All options and methods that were previously deprecated have now been removed. This for example includes the defaultTextTrack loadVideo option or the getManifest method.

Some of those API have since been replaced, other have no replacement, you can refer to the migration guide which lists all removed options and methods.

More expressive decryption options

We added and updated several decryption-related options, allowing to here also be more flexible in expressing how to play encrypted contents.

onKeyOutputRestricted / onKeyInternalError

Two string properties imitating the already there onKeyExpiration API have been added:

  • onKeyOutputRestricted: allows to indicate the behavior the RxPlayer should have when encountering the "output-restricted"
    MediaKeyStatus, like fallbacking to another quality or stopping with an error (the default)

  • onKeyInternalError: allows to indicate the behavior the RxPlayer should have when encountering the "internal-error "
    MediaKeyStatus, like here also fallbacking to another quality or stopping with an error (the default)

Because it allows more powerful configuration than the previous fallbackOn option, the latter has been removed.

persistentState / distinctiveIdentifier

The v4.0.0-beta.0 release adds two string properties to the keySystems option of loadVideo:

Because, they allow the easy replacement of respectively the persistentStateRequired and of the distinctiveIdentifierRequired boolean properties of keySystems, both of those have been removed.

videoCapabilitiesConfig / audioCapabilitiesConfig

Two keySystems properties videoCapabilitiesConfig and audioCapabilitiesConfig now allow to configure respectively the videoCapabilities and audioCapabilities properties of the asked MediaKeySystemConfiguration.

Relatively powerful, this option allows to configure the asked codecs, robustnesses or both.
Like the other ones presented here, this option provokes the removal of the less powerful videoRobustnesses and audioRobustnesses undocumented options.

videoResolutionLimit constructor option

This release also introduces the videoResolutionLimit constructor option.

This new option, which replaces the previous limitVideoWidth constructor option, allows an application to indicate that it wants to throttle video Representations either to the media element's resolution or even to the screen's resolution.

This allows to avoid loading bandwidth-heavy video Representations whose resolution won't be in the end discernible.

What videoResolutionLimit brings to the table relative to limitVideoWidth is the possibility to now throttle by the screen's current resolution - thus handling scenarios where the application want to stay ready for times where the user decides to enter some kind of full screen mode (whereas limitVideoWidth might have taken time going from the lower resolution when the video was in a small element on the page to a higher one when set to full screen).

It is unashamedly very inspired from the shaka-player's restrictToScreenSize and restrictToElementSize configs, as I found them to be good ideas!

Forced subtitles

Note: this feature should also be ported to the future v3.30.0 version.

Forced subtitles, also referred as forced narrative or just narrative subtitles are subtitles which are meant to be displayed by default when no other subtitle track is selected.

They allow to clarify audio or visual cues that might not be clear for the user, by providing text translation to:

  • clarification of audio when it is not clearly audible (for example due to a strong accent or due to distorted audio)
  • foreign - or even sometimes invented (e.g. Klingon) - languages spoke in films
  • other types of communication which might not be easily understood (a frequent example would be sign language)
  • text in foreign languages present on the video track

klingon
Screenshot: french forced narrative subtitles translating what the character is saying. The spoken language here is Klingon which few people know how to speak (besides Klingons of course).

In previous RxPlayer versions, forced subtitles were treated as any other type of text track, with no mean to identify them.
This version adds a new forced property to text tracks described through text tracks API (the getAvailableTextTracks and getTextTrack methods, the availableTextTracksChangeandtextTrackChange` events) to help you identify which text track is a forced one, as you most likely don't want to list it with other regular tracks:

const textTracks = rxPlayer.getAvailableTextTracks();
const textTracksToDisplay = textTracks.filter(t => !t.forced);

Also, the RxPlayer will for now automatically select a forced text track by default (instead of no text track) if one is present for the same language than the audio track chosen by default.
This means that you might want to be careful if switching the audio track to also switch the text track if a forced one exist in that new language or if the old one is not adapted anymore.

DASH endNumber attribute handling

Note: this feature should also be ported to the future v3.30.0 version.

The RxPlayer handled the DASH MPD's startNumber attribute around the time it added DASH support, which allowed to properly handle the huge majority of "Number-based" DASH MPD <SegmentTemplate> elements.
For example, let's consider the following MPD:

template-number2

The MPD in this screenshot indicates that for a time period going from the second 0 to the second 51 (respectively the attributes start and duration from the <Period> element), we have a number-based segment requesting scheme ($Number$ in the media property of the <SegmentTemplate> element). Each segment represents 10 seconds of media content (duration attribute, after dividing it by the timescale one) with the exception of maybe the last one which may be shorter, as usual.
Here, we can also see that the first segment holds the number 1 (startNumber attribute) .

Based on all of this, the RxPlayer deduces that there are 6 segments, from the one holding the number 1 to one holding the number 6:

  1. The first, holding the number 1, from 0s to 10s
  2. The second, number 2, from 10s to 20s
  3. from 20s to 30s
  4. from 30s to 40s
  5. from 40s to 50s
  6. from 50s to 51s (the end of the <Period> element)

However, it turns out that some contents do not provide all those assumed segments. For a concrete example, in our current scenario the 6th segment (the 1 second one) may not actually exist. In some other cases, we could even have the actual last segment's end at 45s for example - in the middle of the fifth segment - with no media data from that point on to the end of the Period.

When encountering those exceptions, the RxPlayer would previously still try to request the 6th segment multiple times, following the retry rules communicated through its API.

However, we found out that a endNumber attribute existed in the DASH specification (though it isn't yet in the generally more adopted DASH-IF IOPs). This attribute allows the MPD to communicate to the player the number of the last segment to request.
Taking the previous example, an MPD might indicate that there's only 5 segments to request instead by adding an endNumber attribute to 5, like this:

template-number-endnumber2

This is now automatically handled by the RxPlayer.

Automatic reloading when the content changes

In the v3 releases, we could not always trigger a reloading operation when it could unlock playback, because the corresponding "RELOADING" state was not part of the v3.0.0 release.
As the new major version v4.0.0-beta.0 now does define that state, the RxPlayer is now free to switch to that state if it thinks it can unblock playback.

One of the main advantages is now the ability to automatically reload when a dynamic content actually changed after a refresh, for example to work-around a server-side issue. Previously, such situations could have led to an infinite rebuffering phase.

updateContentUrls API

Note: this feature should also be ported to the future v3.30.0 version.

Some applications recently introduced us to a new need: being able to change the Manifest's URL while the content is playing.
The URL would represent the same content, it's here just a change of URL in itself that is wanted. For example, a usage would be to switch from an overloaded CDN during playback or to change a token present in the URL.

The v4.0.0 gives an answer to these needs by introducing a new method: updateContentUrls.
It allows to update the URL(s) of the Manifest, and even to trigger a manifest refresh directly, through a simple call:

rxPlayer.updateContentUrls([newUrl], {
  // trigger the refresh immediately
  refresh: true,
});

As usual it has been properly documented in its own documentation page.

For encrypted contents: getKeySystemConfiguration API

Note: this feature should also be ported to the future v3.30.0 version.

Encryption-related issues are the most frequent category of issues currently investigated by the RxPlayer team and its associated applications at least made by Canal+ and our partners.

In that context, we missed a crucial API allowing to facilitate encryption-related debugging on various platforms: One that would allow to indicate easily the current key system configuration relied on.

Particularly the robustness level: PlayReady SL3000 or SL2000? Widevine L1, L2 or L3? And so on.

That's why this release adds the getKeySystemConfiguration API which returns both the actual key system string and the
MediaKeySystemConfiguration currently relied on.

I put there an emphasis on "actual" because, in opposition to the getCurrentKeySystem API, which is now removed, it is the name actually reported by the MediaKeySystemAccess that is here reported, whereas getCurrentKeySystem returned the exact same string than the type originally set on the keySystems option - an arguably less useful value when the RxPlayer could have made translations in between.

No dependency on RxJS in the RxPlayer source code anymore

Note: this ""improvement"" should also be ported to the future v3.30.0 version.

This is the end of an era for the RxPlayer's source code.

The RxPlayer previously depended heavily on RxJS, inspiring even its name, for most aspects where asynchronicity and/or message passing is wanted.
This library helped us greatly in building a complex media player with advanced features but it progressively appeared that its abstractions and specificities were also needlessly complexifying our code, making its maintenance more difficult, but also many times creating hard-to-debug issues.

This is not an attack on the RxJS library which is a fantastic piece of work both on the theoretical and on the practical side, but more of a realization that newer RxPlayer versions started to be big enough and complex enough that the opportunity cost of RxJS appeared not worthwile anymore: alternatives started to looked better due to the RxPlayer's evolution.

We're now both using more usual JavaScript abstractions, like Promises and Event Emitters when it is sufficient and our own abstractions, simpler than RxJS Observables (like the AbortController-like TaskCanceller, allowing to cancel asynchronous tasks, and "Shared references", allowing to share and observe a values at several places), only when needed.

And because it's a recurrent question, yes, we for now decided to keep the name!

As for the impact of this removal for applications, it should be relatively minimal. You should in result see better call stacks when debugging issues and it fixes some minor issues, such as unnecessary warnings when using the create-react-app tool to build your application, or uncaught errors displaying in the console in some situations.

πŸ“‘ Changelog

Changes

  • Create "FREEZING" player state for cases where the playback position is currently not advancing due to an unknown reason, to separate it from regular "BUFFERING". [#1146]
  • The RELOADING player state (gettable through the getPlayerState and playerStateChange API) can now happen at any time to unlock playback.
  • Remove bitrate API: getAvailableVideoBitrates, getAvailableAudioBitrates, setAudioBitrate, setVideoBitrate, getAudioBitrate, getVideoBitrate in profit of the Representations lock APIs [#1144]
  • Remove max bitrate API: setMaxVideoBitrate, setMaxAudioBitrate, getMaxVideoBitrate and getMaxAudioBitrate methods as well as the maxVideoBitrate and maxAudioBitrate options in profit of the Representations lock APIs
  • Remove min bitrate API: setMinVideoBitrate, setMinAudioBitrate, getMinVideoBitrate and getMinAudioBitrate methods as well as the minVideoBitrate and minAudioBitrate options in profit of the Representations lock APIs
  • Remove track preferences API (methods: getPreferredAudioTracks, getPreferredVideoTracks, setPreferredAudioTracks and setPreferredVideoTracks, types: IAudioTrackPreference, ITextTrackPreference and IVideoTrackPreference) in profit of the new tracks API
  • Remove getManualVideoBitrate and getManualAudioBitrate in profit of the new Representations lock APIs
  • Replace initialAudioBitrate and initialVideoBitrate constructor options with a single baseBandwidth option, which better translates what this option is actually doing and allows for future optimizations on our side. [#1155]
  • Rename audioTrackSwitchingMode loadVideo option into defaultAudioTrackSwitchingMode [#1030]
  • Remove manualBitrateSwitchingMode loadVideo option to instead rely on the switchingMode property of each lockVideoRepresentations and lockAudioRepresentations calls. [#1030]
  • Remove audioBitrateChange and videoBitrateChange events in profit of the new audioRepresentationChange and videoRepresentationChange events
  • Remove availableAudioBitratesChange and availableVideoBitratesChange events. Those are less needed with the new Representations lock API and can be mostly replicated through the audioTrackChange and videoTrackChange events
  • "Flatten" the transportOptions loadVideo options by putting all its inner properties directly at the top level of loadVideo options, to simplify its documentation and discoverability [#1149]
  • Remove limitVideoWidth constructor option in profit of the more configurable videoResolutionLimit constructor option
  • Rename networkConfig into requestConfig and re-organize its inner properties to pave the way for future request-related APIs.
  • Remove stopAtEnd loadVideo option and don't automatically stop when reaching the end by default. This behavior can be counter-intuitive and can be very easily implemented by the application.
  • Remove decipherabilityUpdate event as it appeared to be not easily exploitable and exposed internal logic too much [#1168]
  • Remove getUrl method in profit of the more powerful getContentUrls
  • Impossibility to play the content due to unsupported audio and/or video tracks now triggers an error with the MANIFEST_INCOMPATIBLE_CODECS_ERROR instead of MANIFEST_PARSE_ERROR
  • Remove methods: getManifest, getCurrentAdaptations and getCurrentRepresentations, as they reveal the RxPlayer's internals too much
  • The "smooth" transport now needs to be communicated the URL of the Manifest directly (previously, it was possible to redirect it to a XML or JSON file first due to Canal+ legacy reasons).
  • Remove the supplementaryTextTracks loadVideo option. You can use the TextTrackRenderer tool if you wish to diplay external subtitles on top of your content.
  • Rename maximumBufferTime in positionUpdate events to maximumPosition
  • Remove getVideoPlayedTime and getVideoLoadedTime methods. Their names was very confusing and can be re-implemented relatively easily using the media element's buffered property.
  • Rename getVideoDuration to getMediaDuration, to avoid confusion with the video track's duration.
  • Rename getVideoBufferGap to `getCurrentBufferGap, to avoid confusion with the "buffer gap" specific to the video track.
  • Remove image-related API: supplementaryImageTracks loadVideo option, imageTrackUpdate event, getImageTrackData method. Those are better handled by an application. The parseBifThumbnails tool is still available.
  • Replace keySystems[].licenseStorage keySystems option (for a loadVideo call) by the better-named persistentLicenseConfig. The persistentLicense boolean (also a keySystems option) has also been removed because it was redundant with it) [#1147]
  • Remove persistentStateRequired API, in profit of the more powerful persistentState API [#1148]
  • Remove distinctiveIdentifierRequired API, in profit of the more powerful distinctiveIdentifier API [#1148]
  • Remove keySystems[].fallbackOn loadVideo property as it's now replaced by the more powerful keySystems[].onKeyOutputRestricted and keySystems[].onKeyInternalError properties.
  • Remove keySystems[].onKeyStatusesChange API as it seems to never be used [#1148]
  • Remove keySystems[].throwOnLicenseExpiration API as it can now be fully replaced by the keySystems[].onKeyExpiration option
  • Remove aggressiveMode from the transportOptions loadVideo option
  • Remove deprecated throttleWhenHidden player option in profit of throttleVideoBitrateWhenHidden
  • Change payload of periodChange events, so they emit only core properties related to a Period.
  • Change arguments given to a transportOptions.segmentLoader function (the loadVideo option): it now doesn't give the full Manifest, Period, Adaptation, Representation and ISegment structures in arguments but only core properties from it [#995]
  • Custom manifestLoader function added to what was previously the loadVideo's transportOptions option now set an object as argument (with an urlproperty), to let us bring improvements on it in the future [#995]
  • A Representation's frameRate is now always a number - in terms of frame per seconds - instead of a string.
  • Update the arguments of the representationFilter API
  • Representations (in methods: getAvailableVideoTracks, getVideoTrack, representationFilter, getAvailableAudioTracks, getAudioTrack and events: audioTrackChange and videoTrackChange) can have an undefined bitrate
  • Remove deprecated fullscreen related APIs (methods: isFullscreen, setFullscreen, exitFullscreen, event: fullscreenChange) as a a UI is much more adapted to that task and can also bring with it things like a progress bar or HTML text tracks
  • Remove deprecated getNativeTextTrack method. If advanced features are wanted, it's better to just use the HTML text track API
  • Remove deprecated nativeTextTracksChange event. Same reason than for getNativeTextTrack
  • Remove deprecated hideNativeSubtitles from loadVideo options. Same reason than for getNativeTextTrack
  • Remove xhr property from a NetworkError. Doing so stop us from using the fetch API
  • Remove deprecated defaultAudioTrack and defaultTextTrackin profit of new track APIs
  • Remove bitrateEstimationChange event as it is poorly understood (it's not always close to the expected bandwidth) and has a very complex relationship with the chosen quality.
  • Remove the notion of environment variables linked to personalized builds (e.g. RXP_DASH) in profit of the minimal RxPlayer.
  • Rename IPersistentSessionStorage type to IPersistentLicenseConfig [#1147]
  • Remove undocumented audioRobustnesses and videoRobustnesses properties of the keySystems option of loadVideo calls, as more powerful solutions now exist: respectively audioCapabilitiesConfig and videoCapabilitiesConfig [#1148]
  • Remove public types ISupplementaryTextTrackOption and ISupplementaryImageTrackOption. Those are the types respectively for supplementaryTextTracks and supplementaryImageTracks which have been removed
  • Remove public types IBitrateEstimate as no API depend on it anymore.
  • Remove public types IManifest, IPeriod, IAdaptation, IRepresentation, IRepresentationInfos, IBifThumbnail, IBifObject and IExposedSegment as no API depend on them anymore.
  • Remove public types IDefaultAudioTrackOption and IDefaultTextTrackOption. Those are the types respectively for defaultAudioTrack and defaultTextTrack loadVideo options which have been removed
  • Remove public types IAudioTrackPreference, ITextTrackPreference and IVideoTrackPreference as the corresponding API do not exist anymore.
  • Stop officially supporting the Internet Explorer 11 browser

Features

  • setAudioTrack, setVideoTrack and setTextTrack now may take an object in argument, with the track's id set as a trackId property, to allow new features
  • Add switchingMode optional property to setVideoTrack and setAudioTrack, to configure the way in which the RxPlayer switches between the previous and new track
  • Add optional periodId property to setAudioTrack, setVideoTrack and setTextTrack, to allow setting the track of another, future or past, Period.
  • getAvailableAudioTracks, getAvailableTextTracks, getAvailableVideoTracks, getAudioTrack, getTextTrack and getVideoTrack can now optionally take a periodId argument to retrieve track information on a specific Period, different than the current one.
  • disableTextTrack, anddisableVideoTrack can now optionally take a periodId argument to disable a track for a specific Period
  • Add optional lockedRepresentations property to setAudioTrack and setVideoTrack, to only filter some allowed Representations (i.e. qualities) after switching to the wanted track.
  • Add getCurrentPeriod method to retrieve information on the Period currently played
  • Add getAvailablePeriods method to retrieve information on all Periods on which a track or Representation choice can be made
  • Add lockVideoRepresentations, lockAudioRepresentations, getLockedVideoRepresentations, getLockedAudioRepresentations, unlockVideoRepresentations and unlockAudioRepresentations methods to allow a complex selection of Representations that are currently allowed to play.
  • Add getVideoRepresentation and getAudioRepresentation method to retrieve information on the currently loaded representations [#1144]
  • Add audioRepresentationChange and videoRepresentationChange events to be notified when the currently-loaded Representation for the current Period changes.
  • Add updateContentUrls API, allowing to update the Manifest's URL during playback [#1182]
  • DASH: implement forced-subtitles, adding the forced property to the audio tracks API and selecting by default a forced text track linked to the audio track's language if present [#1187]
  • Add getContentUrls allowing to retrieve the one or several known URLs through which the current Manifest or content is reachable.
  • Add videoResolutionLimit constructor option allowing to automatically limit a video Representation's resolution.
  • Add newAvailablePeriods event to signal new Period on which a track and/or Representation choice can be made
  • Add brokenRepresentationsLock event for when a Representations lock could not be respected anymore
  • Add trackUpdate event for when a track has been updated for any type and Period
  • Add distinctiveIdentifier property in the keySystems option (given to the loadVideo method) to have full control over the MediaKeySystemConfiguration of the same name in the chosen key system [#1148]
  • Add persistentState property in the keySystems option (given to the loadVideo method) to have full control over the MediaKeySystemConfiguration of the same name in the chosen key system [#1148]
  • Add keySystems[].onKeyOutputRestricted and keySystems[].onKeyInternalError properties to configure the RxPlayer's behavior when a key switches to the status respectively "output-restricted" and "internal-error"
  • Add audioCapabilitiesConfig and videoCapabilitiesConfig properties in the keySystems option (given to the loadVideo method) to allow advanced configuration of respectively the "audioCapabilities" and "videoCapabilities" in the asked MediaKeySystemConfiguration [#1148]
  • Add ISegmentLoaderContext public type for the first argument of the segmentLoader API
  • Add IRepresentationFilterRepresentation public type for the first argument of the representationFilter API
  • Add IRepresentationContext public type for the second argument of the representationFilter API
  • Add IManifestLoaderInfo public type for the first argument of the manifestLoader API
  • Add IPeriodChangeEvent public type to define the properties send through a periodChange event
  • Add IPeriod public type to define a Period object returned by methods like getAvailablePeriods or getCurrentPeriod
  • Add IVideoTrackSwitchingMode public type to define the type of the switchingMode property optionally given to setAudioTrack
  • Add IAudioRepresentationsSwitchingMode public type to define the type of the switchingMode property optionally given to lockAudioRepresentations
  • Add IVideoRepresentationsSwitchingMode public type to define the type of the switchingMode property optionally given to lockAudioRepresentations
  • Add IBrokenRepresentationsLockContext public type to define the type sent as a payload of the brokenRepresentationsLock event
  • Add ITrackUpdateEventPayload public type to define the type sent as a payload of the trackUpdate event
  • Add ILockedVideoRepresentationsSettings public type to define the object that should be given to the new lockVideoRepresentation method
  • Add ILockedAudioRepresentationsSettings public type to define the object that should be given to the new lockAudioRepresentation method
  • Add IAudioTrackSetting public type to define the object that may be given to the setAudioTrack method
  • Add IVideoTrackSetting public type to define the object that may be given to the setVideoTrack method
  • Add ITextTrackSetting public type to define the object that may be given to the setTextTrack method

Bug fixes

  • Fix segment requesting error when playing a DASH content without an url and without BaseURL elements [#1192]
  • API: Stop sending events if the content is stopped due to a side-effect of one of the event handler [#1197]
  • text-tracks/ttml: fix inconsistent line spacing when resizing the textTrackElement [#1191]
  • DRM: Fix race condition leading to a JS error instead of a NO_PLAYABLE_REPRESENTATION [#1201]
  • DRM/Compat: Renew MediaKeys at each loadVideo on all WebOS (LG TV) platforms to work around issues [#1188]

Other improvements

  • Remove dependency to RxJS, improving the debugging experience and preventing some uncaught Error from being thrown