import { DOMEvent, EventsTarget, InferEventDetail } from 'maverick.js/std'; import * as maverick_js from 'maverick.js'; import { ViewController, MaybeStopEffect, WriteSignal, ReadSignalRecord, Dispose, Scope, Store, State, Component } from 'maverick.js'; import * as media_captions from 'media-captions'; import { VTTCue as VTTCue$1, VTTRegion, CaptionsFileFormat, CaptionsParserFactory, VTTHeaderMetadata } from 'media-captions'; import * as DASH from 'dashjs'; import DASH__default from 'dashjs'; import * as HLS from 'hls.js'; type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug'; declare const GROUPED_LOG: unique symbol; declare class GroupedLog { readonly logger: Logger; readonly level: LogLevel; readonly title: string; readonly root?: GroupedLog | undefined; readonly parent?: GroupedLog | undefined; readonly [GROUPED_LOG] = true; readonly logs: ({ label?: string; data: any[]; } | GroupedLog)[]; constructor(logger: Logger, level: LogLevel, title: string, root?: GroupedLog | undefined, parent?: GroupedLog | undefined); log(...data: any[]): GroupedLog; labelledLog(label: string, ...data: any[]): GroupedLog; groupStart(title: string): GroupedLog; groupEnd(): GroupedLog; dispatch(): boolean; } declare class Logger { #private; error(...data: any[]): boolean; warn(...data: any[]): boolean; info(...data: any[]): boolean; debug(...data: any[]): boolean; errorGroup(title: string): GroupedLog; warnGroup(title: string): GroupedLog; infoGroup(title: string): GroupedLog; debugGroup(title: string): GroupedLog; setTarget(newTarget: EventTarget | null): void; dispatch(level: LogLevel, ...data: any[]): boolean; } declare const ADD: unique symbol; declare const REMOVE: unique symbol; declare const RESET: unique symbol; declare const SELECT: unique symbol; declare const READONLY: unique symbol; declare const SET_READONLY: unique symbol; declare const ON_RESET: unique symbol; declare const ON_REMOVE: unique symbol; declare const ON_USER_SELECT: unique symbol; /** @internal */ declare const ListSymbol: { readonly add: typeof ADD; readonly remove: typeof REMOVE; readonly reset: typeof RESET; readonly select: typeof SELECT; readonly readonly: typeof READONLY; readonly setReadonly: typeof SET_READONLY; readonly onReset: typeof ON_RESET; readonly onRemove: typeof ON_REMOVE; readonly onUserSelect: typeof ON_USER_SELECT; }; interface ListItem { id: string; } declare class List extends EventsTarget implements Iterable { [index: number]: Item | undefined; protected items: Item[]; /** @internal */ protected [ListSymbol.readonly]: boolean; /** @internal */ protected [ListSymbol.onReset]?(trigger?: Event): void; /** @internal */ protected [ListSymbol.onRemove]?(item: Item, trigger?: Event): void; get length(): number; get readonly(): boolean; /** * Returns the index of the first occurrence of the given item, or -1 if it is not present. */ indexOf(item: Item): number; /** * Returns an item matching the given `id`, or `null` if not present. */ getById(id: string): Item | null; /** * Transform list to an array. */ toArray(): Item[]; [Symbol.iterator](): ArrayIterator; /** @internal */ [ListSymbol.add](item: Item, trigger?: Event): void; /** @internal */ [ListSymbol.remove](item: Item, trigger?: Event): void; /** @internal */ [ListSymbol.reset](trigger?: Event): void; /** @internal */ [ListSymbol.setReadonly](readonly: boolean, trigger?: Event): void; } interface ListEvents { add: ListAddEvent; remove: ListRemoveEvent; 'readonly-change': ListReadonlyChangeEvent; } /** * Fired when an item has been added to the list. * * @detail item */ interface ListAddEvent extends DOMEvent { } /** * Fired when an item has been removed from the list. * * @detail item */ interface ListRemoveEvent extends DOMEvent { } /** * Fired when the readonly state of the list has changed. * * @detail isReadonly */ interface ListReadonlyChangeEvent extends DOMEvent { } interface FullscreenEvents { 'fullscreen-change': FullscreenChangeEvent; 'fullscreen-error': FullscreenErrorEvent; } /** * Fired when an element enters/exits fullscreen. The event detail is a `boolean` indicating * if fullscreen was entered (`true`) or exited (`false`). * * @bubbles * @composed * @detail isFullscreen */ interface FullscreenChangeEvent extends DOMEvent { } /** * Fired when an error occurs either entering or exiting fullscreen. This will generally occur * if the user has not interacted with the page yet. * * @bubbles * @composed * @detail error */ interface FullscreenErrorEvent extends DOMEvent { } declare class FullscreenController extends ViewController<{}, {}, FullscreenEvents> implements FullscreenAdapter { #private; get active(): boolean; get supported(): boolean; protected onConnect(): void; enter(): Promise; exit(): Promise; } declare function canFullscreen(): boolean; interface FullscreenAdapter { /** * Whether the host element is in fullscreen mode. */ readonly active: boolean; /** * Whether the native browser fullscreen API is available, or the current provider can * toggle fullscreen mode. This does not mean that the operation is guaranteed to be successful, * only that it can be attempted. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API} */ readonly supported: boolean; /** * Request to display the current host element in fullscreen. * * @throws Error - if fullscreen API is not available. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen} */ enter(): Promise; /** * Attempt to exit fullscreen on the current host element. * * @throws Error - if fullscreen API is not available. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/exitFullscreen} */ exit(): Promise; } declare global { interface HTMLElementEventMap extends LoggerEvents { } } interface LoggerEvents { 'vds-log': LogEvent; } interface LogEventDetail { /** * The log level. */ level: LogLevel; /** * Data to be logged. */ data?: any[]; } /** * @bubbles * @composed * @detail log */ interface LogEvent extends DOMEvent { } type ScreenOrientationType = /** * Landscape-primary is an orientation where the screen width is greater than the screen height. * If the device's natural orientation is landscape, then it is in landscape-primary when held * in that position. If the device's natural orientation is portrait, the user agent sets * landscape-primary from the two options as shown in the screen orientation values table. */ 'landscape-primary' /** * Landscape-secondary is an orientation where the screen width is greater than the screen * height. If the device's natural orientation is landscape, it is in landscape-secondary when * rotated 180º from its natural orientation. If the device's natural orientation is portrait, * the user agent sets landscape-secondary from the two options as shown in the screen * orientation values table. */ | 'landscape-secondary' /** * Portrait-primary is an orientation where the screen width is less than or equal to the screen * height. If the device's natural orientation is portrait, then it is in portrait-primary when * held in that position. If the device's natural orientation is landscape, the user agent sets * portrait-primary from the two options as shown in the screen orientation values table. */ | 'portrait-primary' /** * Portrait-secondary is an orientation where the screen width is less than or equal to the * screen height. If the device's natural orientation is portrait, then it is in * portrait-secondary when rotated 180º from its natural position. If the device's natural * orientation is landscape, the user agent sets portrait-secondary from the two options as * shown in the screen orientation values table. */ | 'portrait-secondary'; type ScreenOrientationLockType = /** * Any is an orientation that means the screen can be locked to any one of portrait-primary, * portrait-secondary, landscape-primary and landscape-secondary. */ 'any' /** * Landscape is an orientation where the screen width is greater than the screen height and * depending on platform convention locking the screen to landscape can represent * landscape-primary, landscape-secondary or both. */ | 'landscape' /** * Landscape-primary is an orientation where the screen width is greater than the screen height. * If the device's natural orientation is landscape, then it is in landscape-primary when held * in that position. If the device's natural orientation is portrait, the user agent sets * landscape-primary from the two options as shown in the screen orientation values table. */ | 'landscape-primary' /** * Landscape-secondary is an orientation where the screen width is greater than the screen * height. If the device's natural orientation is landscape, it is in landscape-secondary when * rotated 180º from its natural orientation. If the device's natural orientation is portrait, * the user agent sets landscape-secondary from the two options as shown in the screen * orientation values table. */ | 'landscape-secondary' /** * Natural is an orientation that refers to either portrait-primary or landscape-primary * depending on the device's usual orientation. This orientation is usually provided by the * underlying operating system. */ | 'natural' /** * Portrait is an orientation where the screen width is less than or equal to the screen height * and depending on platform convention locking the screen to portrait can represent * portrait-primary, portrait-secondary or both. */ | 'portrait' /** * Portrait-primary is an orientation where the screen width is less than or equal to the screen * height. If the device's natural orientation is portrait, then it is in portrait-primary when * held in that position. If the device's natural orientation is landscape, the user agent sets * portrait-primary from the two options as shown in the screen orientation values table. */ | 'portrait-primary' /** * Portrait-secondary is an orientation where the screen width is less than or equal to the * screen height. If the device's natural orientation is portrait, then it is in * portrait-secondary when rotated 180º from its natural position. If the device's natural * orientation is landscape, the user agent sets portrait-secondary from the two options as * shown in the screen orientation values table. */ | 'portrait-secondary'; interface ScreenOrientationEvents { 'orientation-change': ScreenOrientationChangeEvent; } interface ScreenOrientationChangeEventDetail { orientation: ScreenOrientationType; lock?: ScreenOrientationLockType; } /** * Fired when the current screen orientation changes. * * @detail orientation */ interface ScreenOrientationChangeEvent extends DOMEvent { } declare class ScreenOrientationController extends ViewController<{}, {}, ScreenOrientationEvents> { #private; /** * The current screen orientation type. * * @signal * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation} * @see https://w3c.github.io/screen-orientation/#screen-orientation-types-and-locks */ get type(): ScreenOrientationType | undefined; /** * Whether the screen orientation is currently locked. * * @signal * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation} * @see https://w3c.github.io/screen-orientation/#screen-orientation-types-and-locks */ get locked(): boolean; /** * Whether the viewport is in a portrait orientation. * * @signal */ get portrait(): boolean; /** * Whether the viewport is in a landscape orientation. * * @signal */ get landscape(): boolean; /** * Whether the native Screen Orientation API is available. */ static readonly supported: boolean; /** * Whether the native Screen Orientation API is available. */ get supported(): boolean; protected onConnect(): void; /** * Locks the orientation of the screen to the desired orientation type using the * Screen Orientation API. * * @param lockType - The screen lock orientation type. * @throws Error - If screen orientation API is unavailable. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation} * @see {@link https://w3c.github.io/screen-orientation} */ lock(lockType: ScreenOrientationLockType): Promise; /** * Unlocks the orientation of the screen to it's default state using the Screen Orientation * API. This method will throw an error if the API is unavailable. * * @throws Error - If screen orientation API is unavailable. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation} * @see {@link https://w3c.github.io/screen-orientation} */ unlock(): Promise; } interface MediaRequestEvents { 'media-airplay-request': MediaAirPlayRequestEvent; 'media-audio-track-change-request': MediaAudioTrackChangeRequestEvent; 'media-clip-start-change-request': MediaClipStartChangeRequestEvent; 'media-clip-end-change-request': MediaClipEndChangeRequestEvent; 'media-duration-change-request': MediaDurationChangeRequestEvent; 'media-enter-fullscreen-request': MediaEnterFullscreenRequestEvent; 'media-exit-fullscreen-request': MediaExitFullscreenRequestEvent; 'media-enter-pip-request': MediaEnterPIPRequestEvent; 'media-exit-pip-request': MediaExitPIPRequestEvent; 'media-google-cast-request': MediaGoogleCastRequestEvent; 'media-live-edge-request': MediaLiveEdgeRequestEvent; 'media-loop-request': MediaLoopRequestEvent; 'media-user-loop-change-request': MediaUserLoopChangeRequestEvent; 'media-orientation-lock-request': MediaOrientationLockRequestEvent; 'media-orientation-unlock-request': MediaOrientationUnlockRequestEvent; 'media-mute-request': MediaMuteRequestEvent; 'media-pause-request': MediaPauseRequestEvent; 'media-pause-controls-request': MediaPauseControlsRequestEvent; 'media-play-request': MediaPlayRequestEvent; 'media-quality-change-request': MediaQualityChangeRequestEvent; 'media-rate-change-request': MediaRateChangeRequestEvent; 'media-audio-gain-change-request': MediaAudioGainChangeRequestEvent; 'media-resume-controls-request': MediaResumeControlsRequestEvent; 'media-seek-request': MediaSeekRequestEvent; 'media-seeking-request': MediaSeekingRequestEvent; 'media-start-loading': MediaStartLoadingRequestEvent; 'media-poster-start-loading': MediaPosterStartLoadingRequestEvent; 'media-text-track-change-request': MediaTextTrackChangeRequestEvent; 'media-unmute-request': MediaUnmuteRequestEvent; 'media-volume-change-request': MediaVolumeChangeRequestEvent; } /** * Fired when requesting the AirPlay picker to open. * * @bubbles * @composed */ interface MediaAirPlayRequestEvent extends DOMEvent { } /** * Fired when requesting the media poster to begin loading. This will only take effect if the * `posterLoad` strategy on the player is set to `custom`. * * @bubbles * @composed */ interface MediaPosterStartLoadingRequestEvent extends DOMEvent { } /** * Fired when requesting to change the `mode` on a text track at the given index in the * `TextTrackList` on the player. * * @bubbles * @composed */ interface MediaTextTrackChangeRequestEvent extends DOMEvent<{ index: number; mode: TextTrackMode; }> { } /** * Fired when requesting the media to be muted. * * @bubbles * @composed */ interface MediaMuteRequestEvent extends DOMEvent { } /** * Fired when requesting the media to be unmuted. * * @bubbles * @composed */ interface MediaUnmuteRequestEvent extends DOMEvent { } /** * Whether to request fullscreen on the media (i.e., ``). The `prefer-media` option * will first see if the native fullscreen API is available, if not it'll try the media provider. */ type MediaFullscreenRequestTarget = 'prefer-media' | 'media' | 'provider'; /** * Fired when requesting to change the current audio track to the given index in the * `AudioTrackList` on the player. * * @bubbles * @composed */ interface MediaAudioTrackChangeRequestEvent extends DOMEvent { } /** * Fired when requesting to change the clip start time. The event `detail` specifies the new start * time in seconds. * * @bubbles * @composed */ interface MediaClipStartChangeRequestEvent extends DOMEvent { } /** * Fired when requesting to change the clip end time. The event `detail` specifies the new end * time in seconds. * * @bubbles * @composed */ interface MediaClipEndChangeRequestEvent extends DOMEvent { } /** * Fired when requesting to change the length of the media. The event `detail` specifies the * new length in seconds. * * @bubbles * @composed */ interface MediaDurationChangeRequestEvent extends DOMEvent { } /** * Fired when requesting media to enter fullscreen. The event `detail` can specify the * fullscreen target, which can be the media or provider (defaults to `prefer-media`). * * @bubbles * @composed */ interface MediaEnterFullscreenRequestEvent extends DOMEvent { } /** * Fired when requesting media to exit fullscreen. The event `detail` can specify the fullscreen * target, which can be the media or provider (defaults to `prefer-media`). * * @bubbles * @composed */ interface MediaExitFullscreenRequestEvent extends DOMEvent { } /** * Fired when requesting media to enter picture-in-picture mode. * * @bubbles * @composed */ interface MediaEnterPIPRequestEvent extends DOMEvent { } /** * Fired when requesting media to exit picture-in-picture mode. * * @bubbles * @composed */ interface MediaExitPIPRequestEvent extends DOMEvent { } /** * Fired when requesting Google Cast. * * @bubbles * @composed */ interface MediaGoogleCastRequestEvent extends DOMEvent { } /** * Fired when requesting media to seek to the live edge (i.e., set the current time to the current * live time). */ interface MediaLiveEdgeRequestEvent extends DOMEvent { } /** * Fired when requesting media playback to begin/resume. * * @bubbles * @composed */ interface MediaPlayRequestEvent extends DOMEvent { } /** * Fired when requesting to change the current video quality to the given index in the * `VideoQualityList` on the player. * * @bubbles * @composed * @detail qualityIndex */ interface MediaQualityChangeRequestEvent extends DOMEvent { } /** * Fired when requesting to change the current playback rate. * * @bubbles * @composed * @detail rate */ interface MediaRateChangeRequestEvent extends DOMEvent { } /** * Fired when requesting to change the current audio gain. * * @bubbles * @composed * @detail gain */ interface MediaAudioGainChangeRequestEvent extends DOMEvent { } /** * Fired when requesting media playback to temporarily stop. * * @bubbles * @composed */ interface MediaPauseRequestEvent extends DOMEvent { } /** * Fired when requesting a time change. In other words, moving the play head to a new position. * * @bubbles * @composed * @detail seekTo */ interface MediaSeekRequestEvent extends DOMEvent { } /** * Fired when seeking/scrubbing to a new playback position. * * @bubbles * @composed * @detail time */ interface MediaSeekingRequestEvent extends DOMEvent { } /** * Fired when requesting media to begin loading. This will only take effect if the `load` * strategy on the player is set to `custom`. * * @bubbles * @composed */ interface MediaStartLoadingRequestEvent extends DOMEvent { } /** * Fired when requesting the media volume to be set to a new level. * * @bubbles * @composed * @detail volume */ interface MediaVolumeChangeRequestEvent extends DOMEvent { } /** * Fired when controls visibility tracking may resume. This is typically called after requesting * tracking to pause via `media-pause-controls-request`. * * @bubbles * @composed */ interface MediaResumeControlsRequestEvent extends DOMEvent { } /** * Fired when controls visibility tracking should pause. This is typically used when a control * is being actively interacted with, and we don't want the controls to be hidden before * the interaction is complete (eg: scrubbing, or settings is open). * * @bubbles * @composed */ interface MediaPauseControlsRequestEvent extends DOMEvent { } /** * Fired when requesting the poster _should_ be rendered by the media provider. This should be * fired if a custom poster is _not_ being used. * * @bubbles * @composed */ interface MediaShowPosterRequestEvent extends DOMEvent { } /** * Fired when requesting the poster should _not_ be rendered by the media provider. This * should be fired if a custom poster element is being used (e.g., `media-poster`). * * @bubbles * @composed */ interface MediaHidePosterRequestEvent extends DOMEvent { } /** * Internal event that is fired by a media provider when requesting media playback to restart after * reaching the end. This event also helps notify the player that media will be looping. * * @internal * @bubbles * @composed */ interface MediaLoopRequestEvent extends DOMEvent { } /** * Fired when the user loop preference changes. * * @bubbles * @composed */ interface MediaUserLoopChangeRequestEvent extends DOMEvent { } /** * Fired when requesting the screen orientation to be locked to a certain type. * * @bubbles * @composed */ interface MediaOrientationLockRequestEvent extends DOMEvent { } /** * Fired when requesting the screen orientation to be unlocked. * * @bubbles * @composed */ interface MediaOrientationUnlockRequestEvent extends DOMEvent { } /** * The current media type. */ type MediaType = 'unknown' | 'audio' | 'video'; /** * The current media stream type. */ type MediaStreamType = 'unknown' | 'on-demand' | 'live' | 'live:dvr' | 'll-live' | 'll-live:dvr'; type MediaCrossOrigin = '' | 'anonymous' | 'use-credentials'; type RemotePlaybackType = 'airplay' | 'google-cast' | 'none'; interface RemotePlaybackInfo { deviceName?: string; } /** * Indicates the current view type which determines how the media will be presented. */ type MediaViewType = 'unknown' | 'audio' | 'video'; /** * Indicates the type of strategy that should be used to initiate the loading process. * * @docs {@see https://www.vidstack.io/docs/player/core-concepts/loading#load-strategies} */ type MediaLoadingStrategy = 'eager' | 'idle' | 'visible' | 'custom' | 'play'; /** * Indicates the type of strategy that should be used to initiate the poster loading process. * * @docs {@see https://www.vidstack.io/docs/player/core-concepts/loading#load-strategies} */ type MediaPosterLoadingStrategy = 'eager' | 'idle' | 'visible' | 'custom'; /** * A number which represents the general type of error that occurred. * * - *Abort Error Code (1):* The fetching of the associated resource was aborted by the user's * request. * * - *Network Error Code (2):* Some kind of network error occurred which prevented the media from * being successfully fetched, despite having previously been available. * * - *Decode Error Code (3):* Despite having previously been determined to be usable, an error * occurred while trying to decode the media resource, resulting in an error. * * - *Invalid Resource Error Code (4):* The associated resource or media provider object (such as * a `MediaStream`) has been found to be unsuitable. * * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaError * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaError/code */ type MediaErrorCode = 1 | 2 | 3 | 4; interface MediaErrorDetail { message: string; code?: MediaErrorCode; error?: Error; mediaError?: MediaError; } declare global { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged. interface SymbolConstructor { readonly observable: symbol; } } /** Returns a boolean for whether the two given types are equal. @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796 Use-cases: - If you want to make a conditional branch based on the result of a comparison of two types. @example ``` import type {IsEqual} from 'type-fest'; // This type returns a boolean for whether the given array includes the given item. // `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal. type Includes = Value extends readonly [Value[0], ...infer rest] ? IsEqual extends true ? true : Includes : false; ``` @category Type Guard @category Utilities */ type IsEqual = (() => G extends A ? 1 : 2) extends (() => G extends B ? 1 : 2) ? true : false; /** Filter out keys from an object. Returns `never` if `Exclude` is strictly equal to `Key`. Returns `never` if `Key` extends `Exclude`. Returns `Key` otherwise. @example ``` type Filtered = Filter<'foo', 'foo'>; //=> never ``` @example ``` type Filtered = Filter<'bar', string>; //=> never ``` @example ``` type Filtered = Filter<'bar', 'foo'>; //=> 'bar' ``` @see {Except} */ type Filter = IsEqual extends true ? never : (KeyType extends ExcludeType ? never : KeyType); type ExceptOptions = { /** Disallow assigning non-specified properties. Note that any omitted properties in the resulting type will be present in autocomplete as `undefined`. @default false */ requireExactProps?: boolean; }; /** Create a type from an object type without certain keys. We recommend setting the `requireExactProps` option to `true`. This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically. This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)). @example ``` import type {Except} from 'type-fest'; type Foo = { a: number; b: string; }; type FooWithoutA = Except; //=> {b: string} const fooWithoutA: FooWithoutA = {a: 1, b: '2'}; //=> errors: 'a' does not exist in type '{ b: string; }' type FooWithoutB = Except; //=> {a: number} & Partial> const fooWithoutB: FooWithoutB = {a: 1, b: '2'}; //=> errors at 'b': Type 'string' is not assignable to type 'undefined'. ``` @category Object */ type Except = { [KeyType in keyof ObjectType as Filter]: ObjectType[KeyType]; } & (Options['requireExactProps'] extends true ? Partial> : {}); /** Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. @example ``` import type {Simplify} from 'type-fest'; type PositionProps = { top: number; left: number; }; type SizeProps = { width: number; height: number; }; // In your editor, hovering over `Props` will show a flattened object with all the properties. type Props = Simplify; ``` Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface. If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify` if you can't re-declare the `value`. @example ``` import type {Simplify} from 'type-fest'; interface SomeInterface { foo: number; bar?: string; baz: number | undefined; } type SomeType = { foo: number; bar?: string; baz: number | undefined; }; const literal = {foo: 123, bar: 'hello', baz: 456}; const someType: SomeType = literal; const someInterface: SomeInterface = literal; function fn(object: Record): void {} fn(literal); // Good: literal object type is sealed fn(someType); // Good: type is sealed fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened fn(someInterface as Simplify); // Good: transform an `interface` into a `type` ``` @link https://github.com/microsoft/TypeScript/issues/15300 @category Object */ type Simplify = {[KeyType in keyof T]: T[KeyType]} & {}; /** Create a type that strips `readonly` from all or some of an object's keys. Inverse of `Readonly`. This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are writable. @example ``` import type {Writable} from 'type-fest'; type Foo = { readonly a: number; readonly b: readonly string[]; // To show that only the mutability status of the properties, not their values, are affected. readonly c: boolean; }; const writableFoo: Writable = {a: 1, b: ['2'], c: true}; writableFoo.a = 3; writableFoo.b[0] = 'new value'; // Will still fail as the value of property "b" is still a readonly type. writableFoo.b = ['something']; // Will work as the "b" property itself is no longer readonly. type SomeWritable = Writable; // type SomeWritable = { // readonly a: number; // b: readonly string[]; // It's now writable. The type of the property remains unaffected. // c: boolean; // It's now writable. // } ``` @category Object */ type Writable = Simplify< // Pick just the keys that are not writable from the base type. Except & // Pick the keys that should be writable from the base type and make them writable by removing the `readonly` modifier from the key. {-readonly [KeyType in keyof Pick]: Pick[KeyType]} >; /** Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type. Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required. @example ``` import type {SetRequired} from 'type-fest'; type Foo = { a?: number; b: string; c?: boolean; } type SomeRequired = SetRequired; // type SomeRequired = { // a?: number; // b: string; // Was already required and still is. // c: boolean; // Is now required. // } ``` @category Object */ type SetRequired = // `extends unknown` is always going to be the case and is used to convert any // union into a [distributive conditional // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types). BaseType extends unknown ? Simplify< // Pick just the keys that are optional from the base type. Except & // Pick the keys that should be required from the base type and make them required. Required> > : never; type MediaSrc = string | AudioSrc | VideoSrc | HLSSrc | DASHSrc | YouTubeSrc | VimeoSrc; type MediaSrcObject = MediaStream | MediaSource | Blob; type HTMLMediaSrc = string | MediaSrcObject; interface Src { src: T; type: string; } interface AudioSrc extends AudioSrcMeta { src: HTMLMediaSrc; type: AudioMimeType; } type AudioMimeType = 'audio/mpeg' | 'audio/ogg' | 'audio/3gp' | 'audio/mp3' | 'audio/webm' | 'audio/flac' | 'audio/object'; interface AudioSrcMeta { id?: string; bitrate?: number; channels?: number; } interface VideoSrc extends VideoSrcMeta { src: HTMLMediaSrc; type: VideoMimeType; } type VideoMimeType = 'video/mp4' | 'video/webm' | 'video/3gp' | 'video/ogg' | 'video/avi' | 'video/mpeg' | 'video/object'; interface VideoSrcMeta { id?: string; width?: number; height?: number; bitrate?: number; framerate?: number; codec?: string; } interface HLSSrc { src: string; type: HLSMimeType; } type HLSMimeType = 'application/vnd.apple.mpegurl' | 'audio/mpegurl' | 'audio/x-mpegurl' | 'application/x-mpegurl' | 'video/x-mpegurl' | 'video/mpegurl' | 'application/mpegurl'; interface DASHSrc { src: string; type: DASHMimeType; } type DASHMimeType = 'application/dash+xml'; interface YouTubeSrc { src: string; type: 'video/youtube'; } interface VimeoSrc { src: string; type: 'video/vimeo'; } declare function isVideoQualitySrc(src: Src): src is SetRequired; /** * A simple facade for dispatching media requests to the nearest media player element. * * @docs {@link https://www.vidstack.io/docs/player/core-concepts/state-management#updating} * */ declare class MediaRemoteControl { #private; constructor(logger?: Logger | undefined); /** * Set the target from which to dispatch media requests events from. The events should bubble * up from this target to the player element. * * @example * ```ts * const button = document.querySelector('button'); * remote.setTarget(button); * ``` */ setTarget(target: EventTarget | null): void; /** * Returns the current player element. This method will attempt to find the player by * searching up from either the given `target` or default target set via `remote.setTarget`. * * @example * ```ts * const player = remote.getPlayer(); * ``` */ getPlayer(target?: EventTarget | null): MediaPlayer | null; /** * Set the current player element so the remote can support toggle methods such as * `togglePaused` as they rely on the current media state. */ setPlayer(player: MediaPlayer | null): void; /** * Dispatch a request to start the media loading process. This will only work if the media * player has been initialized with a custom loading strategy `load="custom">`. * * @docs {@link https://www.vidstack.io/docs/player/core-concepts/loading#load-strategies} */ startLoading(trigger?: Event): void; /** * Dispatch a request to start the poster loading process. This will only work if the media * player has been initialized with a custom poster loading strategy `posterLoad="custom">`. * * @docs {@link https://www.vidstack.io/docs/player/core-concepts/loading#load-strategies} */ startLoadingPoster(trigger?: Event): void; /** * Dispatch a request to connect to AirPlay. * * @see {@link https://www.apple.com/au/airplay} */ requestAirPlay(trigger?: Event): void; /** * Dispatch a request to connect to Google Cast. * * @see {@link https://developers.google.com/cast/docs/overview} */ requestGoogleCast(trigger?: Event): void; /** * Dispatch a request to begin/resume media playback. */ play(trigger?: Event): void; /** * Dispatch a request to pause media playback. */ pause(trigger?: Event): void; /** * Dispatch a request to set the media volume to mute (0). */ mute(trigger?: Event): void; /** * Dispatch a request to unmute the media volume and set it back to it's previous state. */ unmute(trigger?: Event): void; /** * Dispatch a request to enter fullscreen. * * @docs {@link https://www.vidstack.io/docs/player/api/fullscreen#remote-control} */ enterFullscreen(target?: MediaFullscreenRequestTarget, trigger?: Event): void; /** * Dispatch a request to exit fullscreen. * * @docs {@link https://www.vidstack.io/docs/player/api/fullscreen#remote-control} */ exitFullscreen(target?: MediaFullscreenRequestTarget, trigger?: Event): void; /** * Dispatch a request to lock the screen orientation. * * @docs {@link https://www.vidstack.io/docs/player/screen-orientation#remote-control} */ lockScreenOrientation(lockType: ScreenOrientationLockType, trigger?: Event): void; /** * Dispatch a request to unlock the screen orientation. * * @docs {@link https://www.vidstack.io/docs/player/api/screen-orientation#remote-control} */ unlockScreenOrientation(trigger?: Event): void; /** * Dispatch a request to enter picture-in-picture mode. * * @docs {@link https://www.vidstack.io/docs/player/api/picture-in-picture#remote-control} */ enterPictureInPicture(trigger?: Event): void; /** * Dispatch a request to exit picture-in-picture mode. * * @docs {@link https://www.vidstack.io/docs/player/api/picture-in-picture#remote-control} */ exitPictureInPicture(trigger?: Event): void; /** * Notify the media player that a seeking process is happening and to seek to the given `time`. */ seeking(time: number, trigger?: Event): void; /** * Notify the media player that a seeking operation has completed and to seek to the given `time`. * This is generally called after a series of `remote.seeking()` calls. */ seek(time: number, trigger?: Event): void; seekToLiveEdge(trigger?: Event): void; /** * Dispatch a request to update the length of the media in seconds. * * @example * ```ts * remote.changeDuration(100); // 100 seconds * ``` */ changeDuration(duration: number, trigger?: Event): void; /** * Dispatch a request to update the clip start time. This is the time at which media playback * should start at. * * @example * ```ts * remote.changeClipStart(100); // start at 100 seconds * ``` */ changeClipStart(startTime: number, trigger?: Event): void; /** * Dispatch a request to update the clip end time. This is the time at which media playback * should end at. * * @example * ```ts * remote.changeClipEnd(100); // end at 100 seconds * ``` */ changeClipEnd(endTime: number, trigger?: Event): void; /** * Dispatch a request to update the media volume to the given `volume` level which is a value * between 0 and 1. * * @docs {@link https://www.vidstack.io/docs/player/api/audio-gain#remote-control} * @example * ```ts * remote.changeVolume(0); // 0% * remote.changeVolume(0.05); // 5% * remote.changeVolume(0.5); // 50% * remote.changeVolume(0.75); // 70% * remote.changeVolume(1); // 100% * ``` */ changeVolume(volume: number, trigger?: Event): void; /** * Dispatch a request to change the current audio track. * * @example * ```ts * remote.changeAudioTrack(1); // track at index 1 * ``` */ changeAudioTrack(index: number, trigger?: Event): void; /** * Dispatch a request to change the video quality. The special value `-1` represents auto quality * selection. * * @example * ```ts * remote.changeQuality(-1); // auto * remote.changeQuality(1); // quality at index 1 * ``` */ changeQuality(index: number, trigger?: Event): void; /** * Request auto quality selection. */ requestAutoQuality(trigger?: Event): void; /** * Dispatch a request to change the mode of the text track at the given index. * * @example * ```ts * remote.changeTextTrackMode(1, 'showing'); // track at index 1 * ``` */ changeTextTrackMode(index: number, mode: TextTrackMode, trigger?: Event): void; /** * Dispatch a request to change the media playback rate. * * @example * ```ts * remote.changePlaybackRate(0.5); // Half the normal speed * remote.changePlaybackRate(1); // Normal speed * remote.changePlaybackRate(1.5); // 50% faster than normal * remote.changePlaybackRate(2); // Double the normal speed * ``` */ changePlaybackRate(rate: number, trigger?: Event): void; /** * Dispatch a request to change the media audio gain. * * @example * ```ts * remote.changeAudioGain(1); // Disable audio gain * remote.changeAudioGain(1.5); // 50% louder * remote.changeAudioGain(2); // 100% louder * ``` */ changeAudioGain(gain: number, trigger?: Event): void; /** * Dispatch a request to resume idle tracking on controls. */ resumeControls(trigger?: Event): void; /** * Dispatch a request to pause controls idle tracking. Pausing tracking will result in the * controls being visible until `remote.resumeControls()` is called. This method * is generally used when building custom controls and you'd like to prevent the UI from * disappearing. * * @example * ```ts * // Prevent controls hiding while menu is being interacted with. * function onSettingsOpen() { * remote.pauseControls(); * } * * function onSettingsClose() { * remote.resumeControls(); * } * ``` */ pauseControls(trigger?: Event): void; /** * Dispatch a request to toggle the media playback state. */ togglePaused(trigger?: Event): void; /** * Dispatch a request to toggle the controls visibility. */ toggleControls(trigger?: Event): void; /** * Dispatch a request to toggle the media muted state. */ toggleMuted(trigger?: Event): void; /** * Dispatch a request to toggle the media fullscreen state. * * @docs {@link https://www.vidstack.io/docs/player/api/fullscreen#remote-control} */ toggleFullscreen(target?: MediaFullscreenRequestTarget, trigger?: Event): void; /** * Dispatch a request to toggle the media picture-in-picture mode. * * @docs {@link https://www.vidstack.io/docs/player/api/picture-in-picture#remote-control} */ togglePictureInPicture(trigger?: Event): void; /** * Show captions. */ showCaptions(trigger?: Event): void; /** * Turn captions off. */ disableCaptions(trigger?: Event): void; /** * Dispatch a request to toggle the current captions mode. */ toggleCaptions(trigger?: Event): void; userPrefersLoopChange(prefersLoop: boolean, trigger?: Event): void; } type MediaKeyTarget = 'document' | 'player'; interface MediaKeyShortcuts { [keys: string]: MediaKeyShortcut | undefined; togglePaused?: MediaKeyShortcut; toggleMuted?: MediaKeyShortcut; toggleFullscreen?: MediaKeyShortcut; togglePictureInPicture?: MediaKeyShortcut; toggleCaptions?: MediaKeyShortcut; seekBackward?: MediaKeyShortcut; seekForward?: MediaKeyShortcut; speedUp?: MediaKeyShortcut; slowDown?: MediaKeyShortcut; volumeUp?: MediaKeyShortcut; volumeDown?: MediaKeyShortcut; } type MediaKeyShortcut = MediaKeysCallback | string | string[] | null; interface MediaKeysCallback { keys: string | string[]; /** @deprecated - use `onKeyUp` or `onKeyDown` */ callback?(event: KeyboardEvent, remote: MediaRemoteControl): void; onKeyUp?(context: { event: KeyboardEvent; player: MediaPlayer; remote: MediaRemoteControl; }): void; onKeyDown?(context: { event: KeyboardEvent; player: MediaPlayer; remote: MediaRemoteControl; }): void; } interface SelectListItem extends ListItem { selected: boolean; } declare class SelectList> extends List { get selected(): Item | null; get selectedIndex(): number; /** @internal */ protected [ListSymbol.onRemove](item: Item, trigger?: Event): void; /** @internal */ protected [ListSymbol.onUserSelect]?(): void; /** @internal */ [ListSymbol.add](item: Omit, trigger?: Event): void; /** @internal */ [ListSymbol.select](item: Item | undefined, selected: boolean, trigger?: Event): void; } interface SelectListEvents extends ListEvents { change: SelectListChangeEvent; } /** * @detail change */ interface SelectListChangeEvent extends DOMEvent> { } interface SelectListChangeEventDetail { prev: Item | null; current: Item | null; } interface VideoQualityListEvents { add: VideoQualityAddEvent; remove: VideoQualityRemoveEvent; change: VideoQualityChangeEvent; 'auto-change': VideoQualityAutoChangeEvent; 'readonly-change': ListReadonlyChangeEvent; } interface VideoQualityListEvent extends DOMEvent { target: VideoQualityList; } /** * Fired when a video quality has been added to the list. * * @detail newQuality */ interface VideoQualityAddEvent extends VideoQualityListEvent { } /** * Fired when a video quality has been removed from the list. * * @detail removedQuality */ interface VideoQualityRemoveEvent extends VideoQualityListEvent { } /** * Fired when the selected video quality has changed. * * @detail change */ interface VideoQualityChangeEvent extends VideoQualityListEvent { } interface VideoQualityChangeEventDetail { prev: VideoQuality | null; current: VideoQuality; } /** * Fired when auto quality selection is enabled or disabled. */ interface VideoQualityAutoChangeEvent extends VideoQualityListEvent { } declare const SET_AUTO: unique symbol; declare const ENABLE_AUTO: unique symbol; /** @internal */ declare const QualitySymbol: { readonly setAuto: typeof SET_AUTO; readonly enableAuto: typeof ENABLE_AUTO; }; /** * @see {@link https://vidstack.io/docs/player/core-concepts/video-quality#quality-list} */ declare class VideoQualityList extends SelectList { #private; /** * Configures quality switching: * * - `current`: Trigger an immediate quality level switch. This will abort the current fragment * request if any, flush the whole buffer, and fetch fragment matching with current position * and requested quality level. * * - `next`: Trigger a quality level switch for next fragment. This could eventually flush * already buffered next fragment. * * - `load`: Set quality level for next loaded fragment. * * @see {@link https://www.vidstack.io/docs/player/api/video-quality#switch} * @see {@link https://github.com/video-dev/hls.js/blob/master/docs/API.md#quality-switch-control-api} */ switch: 'current' | 'next' | 'load'; /** * Whether automatic quality selection is enabled. */ get auto(): boolean; /** @internal */ [QualitySymbol.enableAuto]?: (trigger?: Event) => void; /** @internal */ protected [ListSymbol.onUserSelect](): void; /** @internal */ protected [ListSymbol.onReset](trigger?: Event): void; /** * Request automatic quality selection (if supported). This will be a no-op if the list is * `readonly` as that already implies auto-selection. */ autoSelect(trigger?: Event): void; getBySrc(src: unknown): VideoQuality | undefined; /** @internal */ [QualitySymbol.setAuto](auto: boolean, trigger?: Event): void; } interface VideoQuality extends SelectListItem { readonly id: string; readonly src?: unknown; readonly width: number; readonly height: number; readonly bitrate: number | null; readonly codec: string | null; } declare class MediaPlayerDelegate { #private; constructor(handle: (event: Event) => void, media: MediaContext); notify(type: Type, ...init: InferEventDetail extends void | undefined | never ? [detail?: never, trigger?: Event] : [detail: InferEventDetail, trigger?: Event]): void; ready(info?: { duration: number; seekable: TimeRanges; buffered: TimeRanges; }, trigger?: Event): Promise; } interface MediaStorage { getVolume(): Promise; setVolume?(volume: number): Promise; getMuted(): Promise; setMuted?(muted: boolean): Promise; getTime(): Promise; setTime?(time: number, ended?: boolean): Promise; getLang(): Promise; setLang?(lang: string | null): Promise; getCaptions(): Promise; setCaptions?(captions: boolean): Promise; getPlaybackRate(): Promise; setPlaybackRate?(rate: number): Promise; getVideoQuality(): Promise; setVideoQuality?(quality: SerializedVideoQuality | null): Promise; getAudioGain(): Promise; setAudioGain?(gain: number | null): Promise; /** * Called when media is ready for playback and new data can be loaded. */ onLoad?(src: Src): void | Promise; /** * Called when the `mediaId` has changed. This method can return a function to be called * before the next change. * * - The `mediaId` is computed from the current source and clip times. It will be `null` if * there is no source. * * - The `playerId` is the string provided to the player `storage` prop (if set), or the `id` * set on the player element, otherwise `undefined`. */ onChange?(src: Src, mediaId: string | null, playerId?: string): MaybeStopEffect; /** * Called when storage is being destroyed either because the `storage` property on the player * has changed, or the player is being destroyed. */ onDestroy?(): void; } interface SerializedVideoQuality { id: string; width: number; height: number; bitrate?: number | null; } declare class LocalMediaStorage implements MediaStorage { #private; protected playerId: string; protected mediaId: string | null; getVolume(): Promise; setVolume(volume: number): Promise; getMuted(): Promise; setMuted(muted: boolean): Promise; getTime(): Promise; setTime(time: number, ended: boolean): Promise; getLang(): Promise; setLang(lang: string | null): Promise; getCaptions(): Promise; setCaptions(enabled: boolean): Promise; getPlaybackRate(): Promise; setPlaybackRate(rate: any): Promise; getAudioGain(): Promise; setAudioGain(gain: number | null): Promise; getVideoQuality(): Promise; setVideoQuality(quality: SerializedVideoQuality | null): Promise; onChange(src: Src, mediaId: string | null, playerId?: string): void; protected save(): void; protected saveTimeThrottled: (() => void) & { cancel: () => void; flush: () => void; }; private saveTime; } interface AudioTrackListEvents { add: AudioTrackAddEvent; remove: AudioTrackRemoveEvent; change: AudioTrackChangeEvent; 'readonly-change': ListReadonlyChangeEvent; } interface AudioTrackListEvent extends DOMEvent { target: AudioTrackList; } /** * Fired when an audio track has been added to the list. * * @detail newTrack */ interface AudioTrackAddEvent extends AudioTrackListEvent { } /** * Fired when an audio track has been removed from the list. * * @detail removedTrack */ interface AudioTrackRemoveEvent extends AudioTrackListEvent { } /** * Fired when the selected audio track has changed. * * @detail change */ interface AudioTrackChangeEvent extends AudioTrackListEvent { } interface ChangeAudioTrackEventDetail { prev: AudioTrack | null; current: AudioTrack; } /** * @see {@link https://vidstack.io/docs/player/api/audio-tracks} */ declare class AudioTrackList extends SelectList { } /** * @see {@link https://vidstack.io/docs/player/api/audio-tracks} */ interface AudioTrack extends SelectListItem { /** * A string which uniquely identifies the track within the media. */ readonly id: string; /** * A human-readable label for the track, or an empty string if unknown. */ readonly label: string; /** * A string specifying the audio track's primary language, or an empty string if unknown. The * language is specified as a BCP 47 (RFC 5646) language code, such as "en-US" or "pt-BR". */ readonly language: string; /** * A string specifying the category into which the track falls. For example, the main audio * track would have a kind of "main". * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioTrack/kind} */ readonly kind: string; } interface TextTrackEvents { 'load-start': TextTrackLoadStartEvent; load: TextTrackLoadEvent; error: TextTrackErrorEvent; 'add-cue': TextTrackAddCueEvent; 'remove-cue': TextTrackRemoveCueEvent; 'cue-change': TextTrackCueChangeEvent; 'mode-change': TextTrackModeChangeEvent; } interface TextTrackEvent extends DOMEvent { target: TextTrack; } /** * Fired when the text track begins the loading/parsing process. */ interface TextTrackLoadStartEvent extends TextTrackEvent { } /** * Fired when the text track has finished loading/parsing. */ interface TextTrackLoadEvent extends TextTrackEvent { } /** * Fired when loading or parsing the text track fails. */ interface TextTrackErrorEvent extends TextTrackEvent { } /** * Fired when a cue is added to the text track. */ interface TextTrackAddCueEvent extends TextTrackEvent { } /** * Fired when a cue is removed from the text track. */ interface TextTrackRemoveCueEvent extends TextTrackEvent { } /** * Fired when the active cues for the current text track have changed. */ interface TextTrackCueChangeEvent extends TextTrackEvent { } /** * Fired when the text track mode (showing/hidden/disabled) has changed. */ interface TextTrackModeChangeEvent extends TextTrackEvent { } declare const CROSS_ORIGIN: unique symbol; declare const READY_STATE: unique symbol; declare const UPDATE_ACTIVE_CUES: unique symbol; declare const CAN_LOAD: unique symbol; declare const ON_MODE_CHANGE: unique symbol; declare const NATIVE: unique symbol; declare const NATIVE_HLS: unique symbol; declare const TextTrackSymbol: { readonly crossOrigin: typeof CROSS_ORIGIN; readonly readyState: typeof READY_STATE; readonly updateActiveCues: typeof UPDATE_ACTIVE_CUES; readonly canLoad: typeof CAN_LOAD; readonly onModeChange: typeof ON_MODE_CHANGE; readonly native: typeof NATIVE; readonly nativeHLS: typeof NATIVE_HLS; }; /** * - 0: Not Loading * - 1: Loading * - 2: Ready * - 3: Error */ type TextTrackReadyState = 0 | 1 | 2 | 3; interface VTTCueInit extends Omit, 'startTime' | 'endTime' | 'text'>, Pick { } interface VTTRegionInit extends Omit, 'id'>, Pick { } interface VTTContent { cues?: VTTCueInit[]; regions?: VTTRegionInit[]; } declare class TextTrack extends EventsTarget { #private; static createId(track: TextTrack | TextTrackInit): string; readonly src?: string; readonly content?: TextTrackInit['content']; readonly type?: 'json' | CaptionsFileFormat | CaptionsParserFactory; readonly encoding?: string; readonly id = ""; readonly label = ""; readonly language = ""; readonly kind: TextTrackKind; readonly default = false; /** @internal */ [TextTrackSymbol.readyState]: TextTrackReadyState; /** @internal */ [TextTrackSymbol.crossOrigin]?: () => string | null; /** @internal */ [TextTrackSymbol.onModeChange]: (() => void) | null; /** @internal */ [TextTrackSymbol.native]: { default?: boolean; managed?: boolean; track: { mode: TextTrackMode; addCue(cue: any): void; removeCue(cue: any): void; }; remove?(): void; } | null; get metadata(): Readonly; get regions(): ReadonlyArray; get cues(): ReadonlyArray; get activeCues(): ReadonlyArray; /** * - 0: Not Loading * - 1: Loading * - 2: Ready * - 3: Error */ get readyState(): TextTrackReadyState; get mode(): TextTrackMode; set mode(mode: TextTrackMode); constructor(init: TextTrackInit & { fetch?: typeof fetch; }); addCue(cue: VTTCue$1, trigger?: Event): void; removeCue(cue: VTTCue$1, trigger?: Event): void; setMode(mode: TextTrackMode, trigger?: Event): void; /** @internal */ [TextTrackSymbol.updateActiveCues](currentTime: number, trigger?: Event): void; /** @internal */ [TextTrackSymbol.canLoad](): void; } interface TextTrackInit { /** * A unique identifier. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextTrack/id} */ id?: string; /** * URL of the text track resource. This attribute must be specified and its URL value must have * the same origin as the document — unless the