loadVideo options
Overview
This page describes the options given to the loadVideo
method, which is the
method to use to load a new video.
These options take the form of a single objects with multiple properties, like this:
// Setting the only two mandatory keys for a clear content (without DRM).
const options = {
transport: "dash",
url: myManifestUrl
};
player.loadVideo(options);
Properties
transport
type: string|undefined
The transport protocol used for this content.
Can be either:
-
"dash"
- for DASH contents -
"smooth"
- for Microsoft Smooth Streaming contents -
"directfile"
- for loading a video in DirectFile mode, which allows to directly play media files (example:.mp4
or.webm
files) without using a transport protocol.⚠️ In that mode, multiple APIs won’t have any effect. This is documented in the documentation of each concerned method, option or event in the API.
This property is mandatory.
url
type: string|undefined
For Smooth or DASH contents, the URL to the Manifest.
For DirectFile mode contents, the URL of the content (the supported contents depends on the current browser).
This property is mandatory.
keySystems
type: Array.<Object>|undefined
This property is mandatory if the content uses DRM. It is here that is defined every options relative to the encryption of your content.
This property is an array of objects with the following properties (only
type
and getLicense
are mandatory here):
-
type
(string
): name of the DRM system used. Can be either"widevine"
,"playready"
orclearkey
or the type (reversed domain name) of the keySystem (e.g."com.widevine.alpha"
,"com.microsoft.playready"
…). -
getLicense
(Function
): Callback which will be triggered everytime a message is sent by the Content Decryption Module (CDM), usually to fetch/renew the license.Gets two arguments when called:
- the message (
Uint8Array
): The message, formatted to an Array of bytes. - the messageType (
string
): String describing the type of message received. There is only 4 possible message types, all defined in the w3c specification.
This function should return either synchronously the license,
null
to not set a license for thismessage
event or a Promise which should either: - resolves if the license was fetched, with the licence in argument - resolve withnull
if you do not want to set a license for thismessage
event - reject if an error was encounteredIn any case, the license provided by this function should be of a
BufferSource
type (example: anUint8Array
or anArrayBuffer
).Note: We set a 10 seconds timeout on this request. If the returned Promise do not resolve or reject under this limit, the player will stop with an error. If this limit is problematic for you, please open an issue.
- the message (
-
serverCertificate
(BufferSource|undefined
): Eventual certificate used to encrypt messages to the license server. If set, we will try to set this certificate on the CDM. If it fails, we will still continue to try deciphering the content (albeit a warning will be emitted in that case with the code"LICENSE_SERVER_CERTIFICATE_ERROR"
). -
persistentLicense
(Boolean|undefined
): Set it totrue
if you want the ability to persist the license for later retrieval. In that case, you will also need to set thelicenseStorage
attribute to be able to persist the license through your preferred method. This is not needed for most usecases. -
licenseStorage
(Object|undefined
): Required only ifpersistentLicense
has been set totrue
. It’s an object containing two functionsload
andsave
:save
: take into argument anArray.<Object>
which will be the set of sessionId to save. No return value needed.load
: take no argument and returns the storedArray.<Object>
(the last given tosave
) synchronously.
-
persistentStateRequired
(Boolean|undefined
): Set it totrue
if the chosen CDM should have the ability to persist a license,false
if you don’t care. This is not needed for most usecases.false
by default. You do not have to set it totrue
if thepersistentLicense
option is set. -
distinctiveIdentifierRequired
(Boolean|undefined
): When set totrue
, the use of Distinctive Indentifier(s) or Distinctive Permanent Identifier(s) will be required. This is not needed for most usecases.false
if you do not care.false
by default. -
throwOnLicenseExpiration
(Boolean|undefined
):true
by default.If set to
true
or not set, the playback will be interrupted as soon as one of the current licenses expires. In that situation, you will be warned with anerror
event with, as a payload, an error with the codeKEY_STATUS_CHANGE_ERROR
.If set to
false
, the playback of the current content will not be interrupted even if one of the current licenses is expired. It might however stop decoding in that situation. It’s then up to you to update the problematic license, usually through the usualgetLicense
callback.You may want to set this value to
false
if a session expiration leads to a license renewal. In that case, content may continue to play once the license has been updated. -
onKeyStatusesChange
: (Function|undefined
): Not needed for most usecases.Triggered each time the key statuses of the current session changes, except for the following statuses (which throws immediately):
expired
if (and only if)throwOnLicenseExpiration
is not set tofalse
internal-error
Takes 2 arguments:
- The keystatuseschange event
{Event}
- The session associated with the event
{MediaKeySession}
Like
getLicense
, this function should return a promise which emit a license ornull
(for no license) when resolved. It can also return directly the license ornull
if it can be done synchronously. -
closeSessionsOnStop
(Boolean|undefined
): If set totrue
, theMediaKeySession
created for a content will be immediately closed when the content stops its playback. This might be required by your key system implementation (most often, it is not).If set to
false
or not set, theMediaKeySession
can be reused if the same content needs to be re-decrypted.
Example
Example of a simple DRM configuration for widevine and playready DRMs:
player.loadVideo({
url: manifestURL,
transport: "dash",
keySystems: [{
type: "widevine",
getLicense(challenge) {
// ajaxPromise is here an AJAX implementation doing a POST request on the
// widevineLicenseServer with the challenge in its body.
return ajaxPromise(widevineLicenseServer, challenge);
}
}, {
type: "playready",
getLicense(challenge) {
// idem
// Note: you may need to format the challenge before doing the request
// depending on the server configuration.
return ajaxPromise(playreadyLicenseServer, challenge);
}
}]
})
autoPlay
type: Boolean|undefined
defaults: false
If set to true
, the video will play immediately after being loaded.
Note: On some browsers, auto-playing a media without user interaction is blocked
due to the browser’s policy.
In that case, the player won’t be able to play (it will stay in a "LOADED"
state) and you will receive a warning event containing a
MEDIA_ERROR
with the code: MEDIA_ERR_BLOCKED_AUTOPLAY
.
A solution in that case would be to propose to your users an UI element to
trigger the play with an interaction.
startAt
type: Object|undefined
startAt
allows to define a starting position in the played content whether
it is a live content or not.
This option is only defining the starting position, not the beginning of the
content. The user will then be able to navigate anywhere in the content through
the seekTo
API.
If defined, this property must be an object containing a single key. This key can be either:
-
position
(Number
): The starting position, in seconds. -
wallClockTime
(Number|Date
): The starting wall-clock time (re-scaled position from Manifest informations to obtain a timestamp on live contents), in seconds. Useful to use the type of time returned by thegetWallClockTime
API for live contents. If a Date object is given, it will automatically be converted into seconds. -
fromFirstPosition
(Number
): relative position from the minimum possible one, in seconds. That is:- for live contents, from the beginning of the buffer depth (as defined by the Manifest).
- for non-live contents, from the position
0
(this option should be equivalent toposition
)
-
fromLastPosition
(Number
): relative position from the maximum possible one, in seconds. Should be a negative number:- for live contents, it is the difference between the starting position and the live edge (as defined by the manifest)
- for non-live contents, it is the difference between the starting position and the end position of the content.
-
percentage
(Number
): percentage of the wanted position.0
being the minimum position possible (0 for static content, buffer depth for live contents) and100
being the maximum position possible (duration
for static content, live edge for live contents).
Note: Only one of those properties will be considered, in the same order of priority they are written here.
If the value set is inferior to the minimum possible position, the minimum possible position will be used instead. If it is superior to the maximum possible position, the maximum will be used instead as well.
Notes for live contents
For live contents, startAt
could work not as expected:
-
Depending on the type of Manifest, it will be more or less precize to guess the live edge of the content. This will mostly affect the
fromLastPosition
option. -
If the Manifest does not allow to go far enough in the past (not enough buffer, server-side) to respect the position wanted, the maximum buffer depth will be used as a starting time instead.
-
If the Manifest does not allow to go far enough in the future (live edge sooner) to respect the position wanted, the live edge will be used to define the starting time instead.
If startAt
is not set on live contents, the time suggested by the Manifest
will be considered. If it is also not set, the initial position will be based on
the real live edge.
Example
// using position
player.loadVideo({
// ...
startAt: {
position: 10 // start at position == 10 (in seconds)
}
});
// using wall-clock time
player.loadVideo({
// ...
startAt: {
wallClockTime: Date.now() / 1000 - 60 // 1 minute before what's broadcasted
// now
}
});
// using fromFirstPosition
player.loadVideo({
// ...
startAt: {
fromFirstPosition: 30 // 30 seconds after the beginning of the buffer
}
})
// using fromLastPosition
player.loadVideo({
// ...
startAt: {
fromLastPosition: -60 // 1 minute before the end (before the live edge
// for live contents)
}
})
transportOptions
type: Object|undefined
⚠️ This option is not available in DirectFile mode (see transport option).
Options concerning the “transport”.
That is, the part of the code:
- performing Manifest and segment requests
- parsing the Manifest
- parsing/updating/creating segments
This Object can contain multiple properties. Only those documented here are considered stable:
-
segmentLoader
(Function
): defines a custom segment loader. More info on it can be found here. -
manifestLoader
(Function
): defines a custom Manifest loader. More info on it can be found here. -
representationFilter
(Function
): allows to filter outRepresentation
s (i.e. media qualities) from the Manifest to avoid playing them. More infos on it can be found here.
defaultAudioTrack
type: Object|string|undefined
⚠️ This option is not available in DirectFile mode (see transport option).
The starting default audio track.
This can be under the form of an object with the following properties:
const defaultAudioTrack = {
language: "fra", // {string} The wanted language
// (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
audioDescription: false // {Boolean} Whether the audio track should be an
// audio description for the visually impaired
};
or under the form of the language string directly, in which case the
"audioDescription"
option is inferred to be false.
// equivalent to the previous example
const defaultAudioTrack = "fra";
If the corresponding audio track is not found, the first track defined will be taken instead.
defaultTextTrack
type: Object|string|undefined
⚠️ This option is not available in DirectFile mode (see transport option).
The starting default text track.
This can be under the form of an object with the following properties:
const defaultTextTrack = {
language: "fra", // {string} The wanted language
// (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
closedCaption: false // {Boolean} Whether the text track should be a closed
// caption for the hard of hearing
};
or under the form of the language string directly, in which case the
"closedCaption"
option is inferred to be false:
// equivalent to the previous example
const defaultTextTrack = "fra";
If the corresponding text track is not found, the first track defined will be taken instead.
textTrackMode
type: string
defaults: "native"
⚠️ This option is not available in DirectFile mode (see transport option).
This option allows to specify how the text tracks should be displayed.
There is two possible values:
"native"
"html"
In the default "native"
mode, a <track>
element will be created on the
video and the subtitles will be displayed by it, with a minimal style.
There is no action on your side, the subtitles will be correctly displayed at
the right time.
In "html"
mode, the text tracks will be displayed on a specific HTML
element. This mode allows us to do much more stylisation, such as the one
defined by TTML styling attributes or SAMI’s CSS. It is particularly useful to
correctly manage complex closed captions (with multiple colors, positionning
etc.).
With this mode, you will need to provide a wrapper HTML element with the
textTrackElement option.
All text track formats supported in "native"
mode also work in "html"
mode.
More infos on supported text tracks can be found in the text track documentation.
textTrackElement
type: HTMLElement
⚠️ This option is not available in DirectFile mode (see transport option).
textTrackElement
is only required and used if you provided a "html"
textTrackMode.
This property will be the element on which text tracks will be set, as child elements, at the right time. We expect that this element is the exact same size than the media element it applies to (this allows us to properly place the subtitles position without polling where the video is in your UI). You can however re-size or update the style of it as you wish, to better suit your UI needs.
manualBitrateSwitchingMode
type: string
defaults: "seamless"
⚠️ This option is not available in DirectFile mode (see transport option).
Strategy you want to adopt when updating “manually” the video and audio quality
through respectively the setVideoBitrate
and setAudioBitrate
API while
the content is playing.
There is two possible values:
-
"seamless"
: Manual quality updates will be only visible after a little time. This gives the advantage of a very smooth “seamless” transition.In this mode, you will have the following behavior:
- there will be no visual “cut” between the previous and new quality
- parts of the content with a better (or the same) quality won’t be replaced.
- parts of the content with a lower quality will be only replaced when the better quality is downloaded.
-
"direct"
: Manual quality updates will be visible more directly, but with a complete reload of the current content. You might encounter a black screen while the player go through the"RELOADING"
state [1].In this mode, you will have the following behavior:
- there will be a black screen between the previous and new quality
- the previous content will be entirely removed
- you will only have content with the new quality
[1] More informations about the
"RELOADING"
state can be found in the player states documentation.
supplementaryTextTracks
type: Array.<Object>|Object|undefined
defaults: []
⚠️ This option is not available in DirectFile mode (see transport option).
This option allows to specify informations about supplementary text tracks you might want to add to those already declared in the Manifest.
This only work under the following conditions:
-
the text track is not fragmented
-
the text track can be retrieved by fetching a single URL
-
the text track is in an understood format and enough informations has been given to infer it.
Each of those can have the following properties:
const supplementaryTextTracks = [{
url: textTrackURL, // {string} The url on which the complete text track can be
// obtained
language: "eng", // {string} The language the text track is in
// (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
// Note for SAMI subtitles:
// For SAMI subtitles, you have to provide the same language
// string than the one indicated in the CSS and p elements.
// It usually follows the ISO639-ISO3166 naming conventions
// (e.g. en-US or fr-FR).
// If we cannot find the provided language in the downloaded
// SAMI text track, it won't be displayed.
closedCaption: false // {Boolean} Whether the text track is a closed caption
// for the hard of hearing
mimeType: "application/mp4", // {string} A mimeType used to describe
// the text format. Can be "application/mp4" when
// encapsulated in an mp4 file. In that case, the
// "codecs" argument will be needed.
codecs: "stpp" // {string|undefined} Depending on the mimeType,
// you might need to add codec information.
// Here the mimeType is too generic, the codec
// helps us understand this is ttml in an mp4
// container
}];
To know which type of formats are supported and how to add them, you can read the text track documentation.
supplementaryImageTracks
type: Array.<Object>|Object|undefined
defaults: []
⚠️ This option is not available in DirectFile mode (see transport option).
This option allows to specify informations about supplementary image tracks you might want to add to those already declared in the Manifest.
This only work under the following conditions:
-
the image track is not fragmented
-
the image track can be retrieved by fetching a single URL
-
the image track is in an understood format and enough informations has been given to infer it.
Each of those can have the following properties:
const supplementaryImageTracks = [{
url: ImageTrackURL, // {string} The url on which the complete image track can
// be obtained
mimeType: "application/bif", // {string} A mimeType used to describe
// the image format.
}];
hideNativeSubtitle
type: Boolean
defaults: false
⚠️ This option is not available in DirectFile mode (see transport option).
If set to true
, the eventual
This has an effect only if:
-
the current
textTrackMode
is equal to"native"
(see textTrackMode option) -
a text track is currently active
-
the text track format is understood by the rx-player
networkConfig
type: Object
defaults: {}
⚠️ This option is not available in DirectFile mode (see transport option).
Configuration linked to Manifest and segment requests. This object can take the following properties (all are optional):
-
segmentRetry
(Number
): Maximum number of times a segment request will be retried when an error happen - only on some condition [1].Those retry will be done with a progressive delay, to avoid overloading a CDN. When this count is reached, the player will stop and throw a fatal error.
Defaults to
4
. -
manifestRetry
(Number
): Maximum number of times a Manifest request will be retried when a request error happen - only on some condition [1]. Defaults to4
.Those retry will be done with a progressive delay, to avoid overloading a CDN. When this count is reached, the player will stop and throw a fatal error.
Defaults to
4
. -
offlineRetry
(Number
): Maximum number of times a request will be retried when the request fails because the user is offline.Those retry will be done with a progressive delay, to avoid overloading the user’s ressources. When this count is reached, the player will stop and throw a fatal error.
Defaults to
Infinity
.
[1] To retry a request, one of the following condition should be met:
-
The request failed because of a
404
HTTP code -
The request failed because of an HTTP code in the
500
family -
The request failed because of a timeout
-
the request failed because of an unknown XHR error (might be a parsing/interface error)