UNPKG

rx-player

Version:
1,207 lines 52.7 kB
/** * This file defines and exports types we want to expose to library users. * Those types are considered as part of the API. */ import type { IPreferredEmeApiType } from "./compat/eme"; import type { EncryptedMediaError, MediaError, NetworkError, OtherError } from "./errors"; import type { IPersistentSessionInfoV0, IPersistentSessionInfoV1, IPersistentSessionInfoV2, IPersistentSessionInfoV3, IPersistentSessionInfoV4 } from "./main_thread/decrypt"; import type { IManifest, ITaggedTrack } from "./manifest"; import type { ILocalManifest } from "./parsers/manifest/local"; import type { IMetaPlaylist } from "./parsers/manifest/metaplaylist/metaplaylist_parser"; export type { ITaggedTrack as IMediaErrorTrackContext }; export type { IPreferredEmeApiType }; /** `mode` option for the `loadVideo` method */ export type IRxPlayerMode = "auto" | "main" | "multithread"; /** Argument of the `attachWorker` method. */ export interface IWorkerSettings { workerUrl: string | Blob; dashWasmUrl?: string | ArrayBuffer | undefined; } /** Object that defines Common Media Client Data (CMCD) options. */ export interface ICmcdOptions { /** * Content ID delivered by CMCD metadata for that content. * If not specified, a default one will be generated. */ contentId?: string; /** * Session ID delivered by CMCD metadata. * If not specified, a default one will be generated. */ sessionId?: string; /** * Allow to force the way in which the CMCD payload should be communicated. * * If not set, the most appropriate type will be relied on. */ communicationType?: "headers" | "query"; } /** Every options that can be given to the RxPlayer's constructor. */ export interface IConstructorOptions { maxBufferAhead?: number; maxBufferBehind?: number; wantedBufferAhead?: number; maxVideoBufferSize?: number; videoResolutionLimit?: "videoElement" | "screen" | "none"; throttleVideoBitrateWhenHidden?: boolean; videoElement?: HTMLMediaElement; baseBandwidth?: number; } /** Every options that can be given to the RxPlayer's `loadVideo` method. */ export interface ILoadVideoOptions { /** * Streaming protocol used (e.g. "dash" or "smooth"). * * It is a mandatory property. */ transport: string; /** Main URL to the content (Manifest or video file for directfile contents. */ url?: string; /** If `true` the Content will automatically play once loaded. */ autoPlay?: boolean; /** * Decryption-related options. * Can be left to undefined if no decryption is wanted. */ keySystems?: IKeySystemOption[]; /** * If set to `true`, and if the content is compatible, it will be played in a * special mode where the latency is greatly reduced. * * Should only be set for known to be compatible contents. */ lowLatencyMode?: boolean; requestConfig?: IRequestConfig; /** Indicate the position the RxPlayer should start at on the loaded content. */ startAt?: IStartAtOption; /** * The "mode" in which the text tracks will be displayed. * * The default `"native"` mode will use HTMLMediaElement's `track`elements and * poor stylization capabilities. * * The `"html"` mode use the `textTrackElement` option to display subtitles * with rich stylization capabilities inside that `HTMLElement`. */ textTrackMode?: "native" | "html"; /** * The HTMLElement in which text track will be pushed in a `"html"` * `textTrackMode`. * * Mandatory if `textTrackMode` is set to `"html"`. * * Has no effect when `textTrackMode` is not set or set to `"native"`. */ textTrackElement?: HTMLElement; /** * `true` by default. * * If set to `false`, the RxPlayer won't use the "fast-switching" optimization * that allows to see raise in qualities quicker. * * You might want to set to `false` when the current device does not support * segment replacement well. */ enableFastSwitching?: boolean; /** Default behavior when switching to a different audio track. */ defaultAudioTrackSwitchingMode?: IAudioTrackSwitchingMode; /** * Behavior when a audio or video codec just switched to another * non-compatible one. * * This value might depend on the device's capabilities. */ onCodecSwitch?: "continue" | "reload"; /** * Specifies the behavior when all audio tracks are not playable. * * - If set to `"continue"`, the player will proceed to play the content without audio. * - If set to `"error"`, an error will be thrown to indicate that the audio tracks could not be played. * * Note: If neither the audio nor the video tracks are playable, an error will be thrown regardless of this setting. */ onAudioTracksNotPlayable?: "continue" | "error"; /** * Specifies the behavior when all video tracks are not playable. * * - If set to `"continue"`, the player will proceed to play the content without video. * - If set to `"error"`, an error will be thrown to indicate that the video tracks could not be played. * * Note: If neither the audio nor the video tracks are playable, an error will be thrown regardless of this setting. */ onVideoTracksNotPlayable?: "continue" | "error"; /** * Whether we should check that an obtain segment is truncated and retry the * request if that's the case. */ checkMediaSegmentIntegrity?: boolean; /** * Whether we should check that an obtained Manifest is truncated and retry * the request if that's the case. */ checkManifestIntegrity?: boolean | undefined; /** Manifest object that may be used initially. */ initialManifest?: IInitialManifest; /** Custom implementation for performing Manifest requests. */ manifestLoader?: IManifestLoader; /** Minimum bound for Manifest updates, in milliseconds. */ minimumManifestUpdateInterval?: number; /** Custom implementation for performing segment requests. */ segmentLoader?: ISegmentLoader; /** Custom logic to filter out unwanted qualities. */ representationFilter?: IRepresentationFilter | string; /** Base time for the segments in case it is not found in the Manifest. */ referenceDateTime?: number; /** Allows to synchronize the server's time with the client's. */ serverSyncInfos?: IServerSyncInfos; /** * Allows to force the RxPlayer to run in a specific "mode" (e.g. * in "multithread" mode) for that content. */ mode?: IRxPlayerMode | undefined; /** * When set to an object, enable "Common Media Client Data", or "CMCD". */ cmcd?: ICmcdOptions | undefined; /** * Options which may be removed or updated at any RxPlayer release. * * Most of those are options which we temporarily test before making * them part of the RxPlayer API. */ experimentalOptions?: { /** * If `true`, the RxPlayer can enable its "Representation avoidance" * mechanism, where it avoid loading Representation that it suspect * have issues being decoded on the current device. */ enableRepresentationAvoidance: boolean | undefined; } | undefined; } /** Value of the `serverSyncInfos` transport option. */ export interface IServerSyncInfos { /** The server timestamp at a given time. */ serverTimestamp: number; /** The client's monotonic clock at which `serverTimestamp` was valid. */ clientTime: number; } /** Format of a loaded Manifest before parsing. */ export type IInitialManifest = Document | string | ArrayBuffer | IMetaPlaylist | ILocalManifest | IManifest; /** Type for the `representationFilter` API. */ export type IRepresentationFilter = (representation: IRepresentationFilterRepresentation, context: IRepresentationContext) => boolean; /** Representation object given to the `representationFilter` API. */ export interface IRepresentationFilterRepresentation { /** String identifying the Representation, unique per Adaptation. */ id: string; bitrate?: number | undefined; /** * Codec(s) relied on by the media segments of that Representation. * * For the great majority of cases, this value will be set to either * `undefined` (meaning the codec is unknown) or to an array with a * single element which will be the actual codec relied on when the * corresponding Representation will be played. * * However in some very rare scenarios, this value might be set to an array * with multiple codecs, itself being a list of its candidate codecs from the * most wanted to the most compatible. * The conditions for this more complex format are very specific: * * - It can only happen if the `representationFilter` callback is called in * an environment where it hasn't yet been possible for the RxPlayer to * check for codec support (mainly when running through the RxPlayer's * `MULTI_THREAD` feature in a browser without MSE-in-worker * capabilities). * * - The corresponding Representation is compatible to a restrictive codec * yet also retro-compatible to a less restrictive one. * * The main example being Dolby Vision Representations which are * retro-compatible to HDR10 HEVC codecs. * In that very specific case, we could have an array with two elements: * 1. The Dolby Vision codec * 2. The base HDR10 codec */ codecs?: string[] | undefined; /** * This property makes the most sense for video Representations. * It defines the height of the video, in pixels. */ height?: number | undefined; /** * This property makes the most sense for video Representations. * It defines the height of the video, in pixels. */ width?: number | undefined; /** The frame rate for this Representation, in frame per seconds. */ frameRate?: number | undefined; /** If the track is HDR, gives the HDR characteristics of the content */ hdrInfo?: IHDRInformation | undefined; /** * Encryption information linked to this content. * If set to an Object, the Representation is known to be encrypted. * If unset or set to `undefined` the Representation is either unencrypted or * we don't know if it is. */ contentProtections?: { /** Known key ids linked to that Representation. */ keyIds?: Uint8Array[] | undefined; } | undefined; } export interface IHDRInformation { /** * It is the bit depth used for encoding color for a pixel. * * It is used to ask to the user agent if the color depth is supported by the * output device. */ colorDepth?: number | undefined; /** * It is the HDR eotf. It is the transfer function having the video signal as * input and converting it into the linear light output of the display. The * conversion is done within the display device. * * It may be used here to ask the MediaSource if it supported. */ eotf?: string | undefined; /** * It is the video color space used for encoding. An HDR content may not have * a wide color gamut. * * It may be used to ask about output device color space support. */ colorSpace?: string | undefined; } /** Possible values for the `startAt` option of the `loadVideo` method. */ export type IStartAtOption = { /** If set, we should begin at this position, in seconds. */ position: number; } | { /** If set, we should begin at this unix timestamp, in seconds. */ wallClockTime: Date | number; } | { /** * If set, we should begin at this position relative to the whole duration of * the content, in percentage. */ percentage: number; } | { /** * If set, we should begin at this position relative to the content's maximum * seekable position, in seconds. */ fromLastPosition: number; } | { /** * If set, we should begin at this position relative to the content's live * edge if it makes sense, in seconds. * * If the live edge is unknown or if it does not make sense for the current * content, that position is relative to the content's maximum position * instead. */ fromLivePosition: number; } | { /** * If set, we should begin at this position relative to the content's start, * in seconds. */ fromFirstPosition: number; }; export interface RequestRetryParameters { /** * The amount of time maximum we should retry a request before failing on Error. * Set to `Infinity` for an infinite number of requests. */ maxRetry?: number | undefined; /** * Amount of time, in milliseconds, after which a request should be * aborted and optionally retried, depending on the maxRetry configuration. * * Setting it to `-1` allows to disable any timeout. * `undefined` means that a default, large, timeout will be used instead. */ timeout?: number | undefined; /** * Amount of time, in milliseconds, after which a request that hasn't receive * the headers and status code should be aborted and optionnaly retried, * depending on the maxRetry configuration. */ connectionTimeout?: number | undefined; } /** Value for the `requestConfig` option of the `loadVideo` method. */ export interface IRequestConfig { /** * Defines the retry parameters when requesting manifest */ manifest?: RequestRetryParameters | undefined; /** * Defines the retry parameters when requesting a segment */ segment?: RequestRetryParameters | undefined; } export type ISegmentLoader = ( /** Information on the segment to request */ context: ISegmentLoaderContext, callbacks: { resolve: (rArgs: { data: ArrayBuffer | Uint8Array; sendingTime?: number | undefined; receivingTime?: number | undefined; size?: number | undefined; duration?: number | undefined; }) => void; reject: (err?: unknown) => void; fallback: () => void; progress: (info: { duration: number; size: number; totalSize?: number | undefined; }) => void; }) => (() => void) | void; /** Context given to a segment loader. */ export interface ISegmentLoaderContext { /** URL where the segment should be loaded. */ url: string | undefined; /** * Indicative request timeout as configured on the RxPlayer. */ timeout: number | undefined; /** * If true, this segment is an initialization segment with no decodable data. * * Those types of segment contain no decodable data and are only there for * initialization purposes, such as giving initial infos to the decoder on * subsequent media segments that will be pushed. * * Note that if `isInit` is false, it only means that the segment contains * decodable media, it can also contain important initialization information. * * Also, a segment which would contain both all initialization data and the * decodable data would have `isInit` set to `false` as it is not purely an * initialization segment. * * Segments which are not purely an initialization segment are called "media * segments" in the RxPlayer. */ isInit: boolean | undefined; /** * If set, only the corresponding byte-ranges, which are subsets in bytes of * the loaded data, should be loaded. * If multiple non-contiguous byte-ranges are given, the result should be * the concatenation of those byte-ranges, in the same order. * * For example `[[0, 100], [150, 180]]` means that the bytes of both 0 to 100 * (included) and from 150 to 180 (included) should be requested. * The communicated result should then be a concatenation of both in the same * order. */ byteRanges?: Array<[number, number]> | undefined; /** Type of the corresponding track. */ trackType: ITrackType; /** * Optional "Common Media Client Data" (CMCD) payload that may be added to * the request. */ cmcdPayload?: ICmcdPayload | undefined; } /** Every possible value for the Adaptation's `type` property. */ export type ITrackType = "video" | "audio" | "text"; /** * Payload to add to a request to provide CMCD metadata through HTTP request * headers. * * This is an object where keys are header names and values are header contents. */ export type ICmcdHeadersData = Record<string, string>; /** * Payload to add to a request to provide CMCD metadata through an URL's query * string. * * This is an array of all fields and corresponding values that should be * added to the query string, the order should be kept. * * `null` indicates that the field has no value and should be added as is. */ export type ICmcdQueryData = Array<[string, string | null]>; /** * Type when CMCD metadata should be added through headers to the HTTP request * for the corresponding resource. */ export interface ICmcdHeadersPayload { type: "headers"; value: ICmcdHeadersData; } /** * Type when CMCD metadata should be added through the query string to the HTTP * request for the corresponding resource. */ export interface ICmcdQueryPayload { type: "query"; value: ICmcdQueryData; } /** * Type to indicate that CMCD metadata should be added to the request for the * corresponding resource. */ export type ICmcdPayload = ICmcdHeadersPayload | ICmcdQueryPayload; export type ILoadedManifestFormat = IInitialManifest; export type IManifestLoader = ( /** Information on the wanted Manifest. */ info: IManifestLoaderInfo, callbacks: { resolve: (args: { data: ILoadedManifestFormat; url?: string | undefined; sendingTime?: number | undefined; receivingTime?: number | undefined; size?: number | undefined; duration?: number | undefined; }) => void; reject: (err?: Error) => void; fallback: () => void; }) => (() => void) | void; export interface IManifestLoaderInfo { /** URL at which the wanted Manifest can be accessed. */ url: string | undefined; timeout: number | undefined; /** * Optional "Common Media Client Data" (CMCD) payload that may be added to * the request. */ cmcdPayload: ICmcdPayload | undefined; } /** Options related to a single key system. */ export interface IKeySystemOption { /** * Key system wanted. * * Either as a canonical name (like "widevine" or "playready") or as the * complete reverse domain name denomination (e.g. "com.widevine.alpha"). */ type: string; /** Logic used to fetch the license */ getLicense: (message: Uint8Array<ArrayBuffer>, messageType: string) => Promise<BufferSource | null> | BufferSource | null; /** Supplementary optional configuration for the getLicense call. */ getLicenseConfig?: { retry?: number | undefined; timeout?: number | undefined; } | undefined; /** * Optional `serverCertificate` we will try to set to speed-up the * license-fetching process. * `null` or `undefined` indicates that no serverCertificate should be * set. */ serverCertificate?: BufferSource | null; /** Storage mechanism used to store and retrieve information on stored licenses. */ persistentLicenseConfig?: IPersistentLicenseConfig; /** * Wanted value for the `persistentState` property of this * `MediaKeySystemConfiguration` according to the EME API. */ persistentState?: MediaKeysRequirement | undefined; /** * Wanted value for the `distinctiveIdentifier` property of this * `MediaKeySystemConfiguration` according to the EME API. */ distinctiveIdentifier?: MediaKeysRequirement | undefined; /** * Force a `sessionTypes` value for the corresponding * `MediaKeySystemConfiguration` asked when creating a * `MediaKeySystemAccess` (the EME API concept). * * If not set, the RxPlayer will automatically ask for the most adapted * `sessionTypes` based on your configuration for the current content. As * such, this option is only needed for very specific usages. * * A case where you might want to set this value is if for example you want * the ability to be able to load both temporary and persistent licenses, * regardless of the configuration applied to the current content. * Setting in that case `wantedSessionTypes` to * `["temporary", "persistent-license"]` will lead, if compatible, to the * creation of a `MediaKeySystemAccess` able to handle both: * - contents relying on temporary licenses, and: * - contents relying on persistent licenses * * The RxPlayer will then be able to keep that same `MediaKeySystemAccess` on * future `loadVideo` calls as long as they rely on either all or a subset of * those session types - and as long as the rest of the new wanted * configuration is also considered compatible with that `MediaKeySystemAccess`. * * Moreover, because our `MediaKeySession` cache (see `maxSessionCacheSize`) * is linked to a `MediaKeySystemAccess`, keeping the same one allows the * RxPlayer to also keep the same cache (whereas changing * `MediaKeySystemAccess` when changing contents resets that cache). * * Note that the current device has to be compatible to _ALL_ `sessionTypes` * for that configuration to go through. * * Notes * ----- * * If this value is set to an array which does not contain * `"persistent-license"`, we will assume that no persistent license will be * requested for the current content, regardless of the * `persistentLicenseConfig` option. * * If this value only contains `"persistent-license"` but the * `persistentLicenseConfig` option is not set, we will load persistent * licenses yet not persist them. */ wantedSessionTypes?: string[] | undefined; /** * If true, all open `MediaKeySession` (JavaScript Objects linked to the keys * used to decrypt the content) will be closed when the current playback * stops. * * By default, we keep `MediaKeySession` from previous contents (up to * `maxSessionCacheSize` `MediaKeySession`) to speed-up playback and avoid * round-trips to the license server if the user ever decide to go back to * those contents or to other contents relying to the same keys. * * However we found that some devices poorly handle that optimization. * * Note that if setting that property to `true` fixes your issue, it may be * that it's just the `maxSessionCacheSize` which is for now too high. * * However if your problem doesn't disappear after setting * `closeSessionsOnStop` to `true`, you may try `reuseMediaKeys` next. */ closeSessionsOnStop?: boolean; /** * If set to `true` or if not set, we might rely on the previous `MediaKeys` * if a compatible one is already set on the media element, allowing to * potentially speed-up content playback. * * If set to `false`, we will create a new `MediaKeys` instance (a * JavaScript object needed to decrypt contents) if needed for that content. * * We noticed that reusing a previous MediaKeys had led to errors on a few * devices. For example some smart TVs had shown errors after playing several * encrypted contents, errors which disappeared if we renewed the * `MediaKeys` for each content. * * We should already be able to detect most of those cases in the RxPlayer * logic. However, it is still possible that we don't know yet of a device * which also has problem with that optimization. * * If you have issues appearing only after playing multiple encrypted * contents: * * - First, try setting the `closeSessionsOnStop` option which is less * destructive. * * If it fixes your issue, it may be that it's just the number of * `MediaKeySession` cached by the RxPlayer that is here too high. * * In that case you can instead update the `maxSessionCacheSize` option * to still profit from a `MediaKeySession` cache (which avoid making * license requests for already-played contents). * * If that second option doesn't seem to have an effect, you can just set * `closeSessionsOnStop`. * * - If none of the precedent work-arounds work however, you can try setting * `reuseMediaKeys` to `false`. If it fixes your problem, please open an * RxPlayer issue so we can add your device to our list. */ reuseMediaKeys?: boolean | undefined; singleLicensePer?: "content" | "periods" | "init-data"; /** * Maximum number of `MediaKeySession` that should be created on the same * MediaKeys. */ maxSessionCacheSize?: number; videoCapabilitiesConfig?: IVideoCapabilitiesConfiguration; audioCapabilitiesConfig?: IAudioCapabilitiesConfiguration; /** * If set to `true`, we will not wait until the MediaKeys instance is attached * to the media element before pushing segments to it. * Setting it to `true` might be needed on some targets to work-around a * deadlock in the browser-side logic (or most likely the CDM implementation) * but it can also break playback of contents with both encrypted and * unencrypted data, most especially on Chromium and Chromium-derived browsers. */ disableMediaKeysAttachmentLock?: boolean; /** * Behavior the RxPlayer should have when one of the key has the * `MediaKeyStatus` `"internal-error"`. * * `onKeyInternalError` can be set to a string, each describing a different * behavior, the default one if not is defined being `"error"`: * * - `"error"`: The RxPlayer will stop on an error. * This is the default behavior. * * - `"continue"`: The RxPlayer will not do anything. * This may lead in many cases to infinite rebuffering. * * - `"fallback"`: The Representation(s) linked to those key(s) will * be fallbacked from, meaning the RxPlayer will switch to other * representation. * * - `"close-session"`: The RxPlayer will close and re-create a DRM session * (and thus re-download the corresponding license). */ onKeyInternalError?: "error" | "continue" | "fallback" | "close-session"; /** * Behavior the RxPlayer should have when one of the key has the * `MediaKeyStatus` `"output-restricted"`. * * `onKeyOutputRestricted` can be set to a string, each describing a different * behavior, the default one if not is defined being `"error"`: * * - `"error"`: The RxPlayer will stop on an error. * This is the default behavior. * * - `"continue"`: The RxPlayer will not do anything. * This may lead in many cases to infinite rebuffering. * * - `"fallback"`: The Representation(s) linked to those key(s) will * be fallbacked from, meaning the RxPlayer will switch to other * representation. */ onKeyOutputRestricted?: "error" | "continue" | "fallback"; /** * Behavior the RxPlayer should have when one of the key is known to be * expired. * * `onKeyExpiration` can be set to a string, each describing a different * behavior, the default one if not is defined being `"error"`: * * - `"error"`: The RxPlayer will stop on an error when any key is expired. * This is the default behavior. * * - `"continue"`: The RxPlayer will not do anything when a key expires. * This may lead in many cases to infinite rebuffering. * * - `"fallback"`: The Representation(s) linked to the expired key(s) will * be fallbacked from, meaning the RxPlayer will switch to other * representation without expired keys. * * - `"close-session"`: The RxPlayer will close and re-create a DRM session * (and thus re-download the corresponding license) if any of the key * associated to this session expired. */ onKeyExpiration?: "error" | "continue" | "fallback" | "close-session"; } /** Values that can be given to the `videoCapabilitiesConfig` `keySystems`'s property. */ export type IVideoCapabilitiesConfiguration = IRobustnessMediaKeySystemCapabilities | IContentTypeMediaKeySystemCapabilities | IFullMediaKeySystemCapabilities; /** Values that can be given to the `audioCapabilitiesConfig` `keySystems`'s property. */ export type IAudioCapabilitiesConfiguration = IRobustnessMediaKeySystemCapabilities | IContentTypeMediaKeySystemCapabilities | IFullMediaKeySystemCapabilities; /** * Value that can be given to either the `audioCapabilitiesConfig` or to the * `videoCapabilitiesConfig` `keySystems`'s property when the application only * wants to specify the "robustness" part of the `MediaKeySystemMediaCapability` * sent through the corresponding `MediaKeySystemConfiguration` used to decrypt * the content. * * In this case, the RxPlayer will define potentially default values for * other capability-related properties (such as the "contentType"). */ export interface IRobustnessMediaKeySystemCapabilities { type: "robustness"; value: Array<string | undefined>; } /** * Value that can be given to either the `audioCapabilitiesConfig` or to the * `videoCapabilitiesConfig` `keySystems`'s property when the application only * wants to specify the "contentType" part of the * `MediaKeySystemMediaCapability` sent through the corresponding * `MediaKeySystemConfiguration` used to decrypt the content. * * In this case, the RxPlayer will define potentially default values for * other capability-related properties (such as the "robustness"). */ export interface IContentTypeMediaKeySystemCapabilities { type: "contentType"; value: string[]; } /** * Value that can be given to either the `audioCapabilitiesConfig` or to the * `videoCapabilitiesConfig` `keySystems`'s property when the application wants * to specify the full `MediaKeySystemMediaCapability` object sent through the * corresponding `MediaKeySystemConfiguration` used to decrypt the content. */ export interface IFullMediaKeySystemCapabilities { type: "full"; value: MediaKeySystemMediaCapability[]; } /** * Data stored in a persistent MediaKeySession storage. * Has to be versioned to be able to play MediaKeySessions persisted in an old * RxPlayer version when in a new one. */ export type IPersistentSessionInfo = IPersistentSessionInfoV4 | IPersistentSessionInfoV3 | IPersistentSessionInfoV2 | IPersistentSessionInfoV1 | IPersistentSessionInfoV0; /** Persistent MediaKeySession storage interface. */ export interface IPersistentLicenseConfig { /** Load persistent MediaKeySessions previously saved through the `save` callback. */ load(): IPersistentSessionInfo[] | undefined | null; /** * Save new persistent MediaKeySession information. * The given argument should be returned by the next `load` call. */ save(x: IPersistentSessionInfo[]): void; /** * By default, MediaKeySessions persisted through an older version of the * RxPlayer will still be available under this version. * * By setting this value to `true`, we can disable that condition in profit of * multiple optimizations (to load a content faster, use less CPU resources * etc.). * * As such, if being able to load MediaKeySession persisted via older version * is not important to you, we recommend setting that value to `true`. */ disableRetroCompatibility?: boolean; } /** Payload emitted with a `positionUpdate` event. */ export interface IPositionUpdate { /** current position the player is in, in seconds. */ position: number; /** Last position set for the current media currently, in seconds. */ duration: number; /** Playback rate (i.e. speed) at which the current media is played. */ playbackRate: number; /** Amount of buffer available for now in front of the current position, in seconds. */ bufferGap: number; /** Current maximum seekable position. */ maximumPosition?: number | undefined; wallClockTime?: number | undefined; /** * Only for live contents. Difference between the "live edge" and the current * position, in seconds. */ liveGap?: number | undefined; } export type IPlayerState = "STOPPED" | "LOADED" | "LOADING" | "PLAYING" | "PAUSED" | "ENDED" | "BUFFERING" | "FREEZING" | "SEEKING" | "RELOADING"; export interface IPeriodChangeEvent { start: number; id: string; end?: number | undefined; } export type IStreamEvent = { data: IStreamEventData; start: number; end: number; onExit?: () => void; } | { data: IStreamEventData; start: number; }; export interface IStreamEventData { type: "dash-event-stream"; value: { schemeIdUri: string; timescale: number; element: Element; }; } export type IPlayerError = EncryptedMediaError | MediaError | OtherError | NetworkError; /** * Information describing a single Representation from an Adaptation, to be used * in the `representationFilter` API. */ export interface IRepresentationContext { trackType: string; language?: string | undefined; isAudioDescription?: boolean | undefined; isClosedCaption?: boolean | undefined; isDub?: boolean | undefined; isSignInterpreted?: boolean | undefined; normalizedLanguage?: string | undefined; } /** * Definition of a single audio Representation as represented by the * RxPlayer. */ export interface IAudioRepresentation { /** * Identifier for that Representation. * Might e.g. be used with the `lockVideoRepresentation` API. */ id: string | number; /** Optional maximum bitrate, in bits per seconds, for this Representation. */ bitrate?: number | undefined; /** Codec(s) relied on by the media segments of that Representation. */ codec?: string | undefined; /** * If `true`, this Representation is linked to "spatial audio" technology, such as * Dolby Atmos. * If `false`, it is not linked to such technology. * * If `undefined`, we don't if it is linked to a spatial audio technology or not. */ isSpatialAudio?: boolean | undefined; /** * If `true`, the codec is known to be supported on the current device. * If `false`, it is known to be unsupported. * * If `undefined`, we don't know yet if it is supported or not. */ isCodecSupported?: boolean | undefined; /** * If `true`, this Representation is known to be decipherable. * If `false`, it is known to be encrypted and not decipherable. * * If `undefined`, we don't know yet if it is decipherable or not (or if it is * encrypted or not in some cases). */ decipherable?: boolean | undefined; /** * Encryption information linked to this content. * If set to an Object, the Representation is known to be encrypted. * If unset or set to `undefined` the Representation is either unencrypted or * we don't know if it is. */ contentProtections?: { /** Known key ids linked to that Representation. */ keyIds?: Uint8Array[] | undefined; } | undefined; } /** Audio track returned by the RxPlayer. */ export interface IAudioTrack { /** The language the audio track is in, as it is named in the Manifest. */ language: string; /** * An attempt to translate `language` into a valid ISO639-3 language code. * Kept equal to `language` if the attempt failed. */ normalized: string; audioDescription: boolean; dub?: boolean | undefined; id: string; label?: string | undefined; representations: IAudioRepresentation[]; } /** Text track returned by the RxPlayer. */ export interface ITextTrack { /** The language the text track is in, as it is named in the Manifest. */ language: string; /** * An attempt to translate `language` into a valid ISO639-3 language code. * Kept equal to `language` if the attempt failed. */ normalized: string; forced: boolean | undefined; closedCaption: boolean; label?: string | undefined; id: number | string; } /** * Definition of a single video Representation as represented by the * RxPlayer. */ export interface IVideoRepresentation { /** * Identifier for that Representation. * Might e.g. be used with the `lockVideoRepresentation` API. */ id: string; /** Optional maximum bitrate, in bits per seconds, for this Representation. */ bitrate?: number | undefined; /** Defines the width of the Representation in pixels. */ width?: number | undefined; /** Defines the height of the Representation in pixels. */ height?: number | undefined; /** Codec(s) relied on by the media segments of that Representation. */ codec?: string | undefined; /** The frame rate for this Representation, in frame per seconds. */ frameRate?: number | undefined; /** If the track is HDR, gives the HDR characteristics of the content */ hdrInfo?: IHDRInformation | undefined; /** * If `true`, the codec is known to be supported on the current device. * If `false`, it is known to be unsupported. * * If `undefined`, we don't know yet if it is supported or not. */ isCodecSupported?: boolean | undefined; /** * If `true`, this Representation is known to be decipherable. * If `false`, it is known to be encrypted and not decipherable. * * If `undefined`, we don't know yet if it is decipherable or not (or if it is * encrypted or not in some cases). */ decipherable?: boolean | undefined; /** * Encryption information linked to this content. * If set to an Object, the Representation is known to be encrypted. * If unset or set to `undefined` the Representation is either unencrypted or * we don't know if it is. */ contentProtections?: { /** Known key ids linked to that Representation. */ keyIds?: Uint8Array[] | undefined; } | undefined; } /** Video track returned by the RxPlayer. */ export interface IVideoTrack { id: string; signInterpreted?: boolean | undefined; isTrickModeTrack?: boolean | undefined; trickModeTracks?: IVideoTrack[] | undefined; label?: string | undefined; representations: IVideoRepresentation[]; } /** Output of the `getKeySystemConfiguration` method. */ export interface IKeySystemConfigurationOutput { /** Key system string. */ keySystem: string; /** `MediaKeySystemConfiguration` actually used by the key system. */ configuration: MediaKeySystemConfiguration; } /** Period from a list of Periods as returned by the RxPlayer. */ export interface IPeriod { /** Start time in seconds at which the Period starts. */ start: number; /** * End time in seconds at which the Period ends. * `undefined` if that end is unknown for now. */ end: number | undefined; /** Identifier for this Period allowing to perform track modification for it. */ id: string; } /** Audio track from a list of audio tracks returned by the RxPlayer. */ export interface IAvailableAudioTrack extends IAudioTrack { active: boolean; } /** Text track from a list of text tracks returned by the RxPlayer. */ export interface IAvailableTextTrack extends ITextTrack { active: boolean; } /** Video track from a list of video tracks returned by the RxPlayer. */ export interface IAvailableVideoTrack extends IVideoTrack { active: boolean; } /** * Type of a single object from the optional `EncryptedMediaError`'s * `keyStatuses` property. */ export interface IEncryptedMediaErrorKeyStatusObject { /** Corresponding keyId which encountered the problematic MediaKeyStatus. */ keyId: ArrayBuffer; /** Problematic MediaKeyStatus encountered. */ keyStatus: MediaKeyStatus; } /** * Behavior wanted when replacing an audio track / Adaptation by another: * * - direct: Switch audio track immediately by removing all the previous * track's data. * * This might interrupt playback while data for any of the new * track wanted is loaded. * * - seamless: Switch audio track without interrupting playback by still * keeping data from the previous track around the current * position. * * This could have the disadvantage of still playing the previous * track during a short time (not more than a few seconds in * most cases). * * - reload: Reload content to provide an immediate interruption of the * previous audio track before switching to the new one. * * Some targets might not handle "direct" mode properly. The "reload" * mode is kind of a more compatible attempt of immediately switching the * audio track. */ export type IAudioTrackSwitchingMode = "direct" | "seamless" | "reload"; /** * Behavior wanted when replacing a video track / Adaptation by another: * * - direct: Switch video track immediately by removing all the previous * track's data. * * This might interrupt playback while data for any of the new * track wanted is loaded. * Moreover, the previous video frame at the time of the switch will * probably still be on display while this is happening. If this is * not something you want, you might prefer the "reload" mode. * * - seamless: Switch video track without interrupting playback by still * keeping data from the previous track around the current * position. * This could have the disadvantage of still playing the previous * track during a short time (not more than a few seconds in * most cases). * * - reload: Reload content to provide an immediate interruption of the * previous video track before switching to the new one. * * This can be seen like the "direct" mode with two differences: * * - The "direct" mode might rebuffer for a time with the previous * frame displaying. With "reload" a black screen will probably be shown * instead. * * - some targets might not handle "direct" mode properly. The "reload" * mode is kind of a more compatible attempt of immediately switching the * Adaptation. */ export type IVideoTrackSwitchingMode = "direct" | "seamless" | "reload"; export type IVideoRepresentationsSwitchingMode = IRepresentationsSwitchingMode; export type IAudioRepresentationsSwitchingMode = IRepresentationsSwitchingMode; /** * Behavior wanted when replacing active Representations by others: * * - direct: Switch Representation immediately by removing all the previous * Representations's data. * This might interrupt playback while data for any of the new * Representations wanted is loaded. * * If talking about video Representations, the previous video frame at the * time of the switch will probably still be on display while this is * happening. * If this is not something you want, you might prefer the "reload" mode. * * - seamless: Switch Representation without interrupting playback by still * keeping data from the previous Representations around the current * position. * This could have the disadvantage of still playing the previous * Representations during a short time (not more than a few seconds in * most cases). * * - reload: Reload `MediaSource` to provide an immediate interruption of the * previous interruption before switching to the new Representation. * * This can be seen like the "direct" mode with two differences: * * - in case of video contents, the "direct" mode might rebuffer for a * time with the previous frame displaying. With "reload" a black screen * will probably be shown instead. * * - some targets might not handle "direct" mode properly. The "reload" * mode is kind of a more compatible attempt of immediately switching the * Representation. * * - lazy: Keep data from the previous Representation in the buffer. * It still might eventually be replaced by Representation of a better * quality when depending on future playback condition. */ type IRepresentationsSwitchingMode = "direct" | "seamless" | "reload" | "lazy"; export interface IBrokenRepresentationsLockContext { period: IPeriod; trackType: ITrackType; } export interface ITrackUpdateEventPayload { period: IPeriod; trackType: ITrackType; reason: "missing" | "manual" | "trickmode-enabled" | "trickmode-disabled" | "no-playable-representation" | string; } export interface INoPlayableTrackEventPayload { trackType: ITrackType; period: { id: string; start: number; end: number | undefined; }; } export interface IRepresentationListUpdateContext { period: IPeriod; trackType: ITrackType; reason: "decipherability-update" | string; } export interface ILockedVideoRepresentationsSettings { representations: string[]; periodId?: string | undefined; switchingMode?: IVideoRepresentationsSwitchingMode | undefined; } export interface ILockedAudioRepresentationsSettings { representations: string[]; periodId?: string | undefined; switchingMode?: IAudioRepresentationsSwitchingMode | undefined; } export interface IAudioTrackSetting { /** `id` of the audio track you want to set. */ trackId: string; /** * `id` of the Period for which you want that setting applied. * Keeping it undefined means it will apply to the currently-playing Period. */ periodId?: string | undefined; /** * Behavior wanted when replacing an audio track / Adaptation by another. * @see IAudioTrackSwitchingMode * * Keeping it undefined means that the RxPlayer will automatically select * the most adapted choice. */ switchingMode?: IAudioTrackSwitchingMode | undefined; /** * Representations (a.k.a. qualities) you want to play in that new track. * Keeping it undefined means that all compatible qualities may be played. */ lockedRepresentations?: string[] | undefined; /** * This only has an effect if the track switching operation lead to a small * playback interruption (which can only happen if `switchingMode` is either * set to `"reload"` or in some cases when it is undefined). * * `relativeResumingPosition` corresponds to the relative time in seconds at * which we will resume playback with the new track. * * For example if switching from an audio track `A` to an audio track `B` at * position `20` (seconds) and setting `relativeResumingPosition` to `-1`, we * will resume playback with the audio track `B` at position `19`. * * You might want to set this value generally either because you want to * replay some audio content after switching the audio track to give back * context (e.g. picking back at the same sentence in the language of the new * audio track) or to ensure the exact same position is played by setting it * to `0`. * * If not set or set to `undefined`, the RxPlayer will automatically choose * a suitable default value instead. */ relativeResumingPosition?: number | undefined; } export interface IVideoTrackSetting { /** `id` of the video track you want to set. */ trackId: string; /** * `id` of the Period for which you want that setting applied. * Keeping it undefined means it will apply to the currently-playing Period. */ periodId?: string | undefined; /** * Behavior wanted when replacing an video track / Adaptation by another. * @see IVideoTrackSwitchingMode * * Keeping it undefined means that the RxPlayer will automatically select * the most adapted choice. */ switchingMode?: IVideoTrackSwitchingMode | undefined; /** * Representations (a.k.a. qualities) you want to play in that new track. * Keeping it undefined means that all compatible qualities may be played. */ lockedRepresentations?: string[] | undefined; /** * This only has an effect if the track switching operation lead to a small * playback interruption (which can only happen if `switchingMode` is either * set to `"reload"`, `"flush"` or in some cases when it is undefined). * * `relativeResumingPosition` corresponds to the relative time in seconds at * which we will resume playback with the new track. * * For example if switching from a video track `A` to a video track `B` at * position `20` (seconds) and setting `relativeResumingPosition` to `-1`, we * will resume playback with the video track `B` at position `19` (only if the * track switch operation led to a playback interruption, see top of comment). * * You might want to set this value generally either because you want to * replay some video content after switching the video track to give back * context or to ensure the exact same position is played by setting it to * `0`. * * If not set or set to `undefined`, the RxPlayer will automatically choose * a suitable default value instead. */ relativeResumingPosition?: number | undefined; } export interface ITextTrackSetting { /** `id` of the text track you