UNPKG

expo-video

Version:

A cross-platform, performant video component for React Native and Expo with Web support

835 lines (735 loc) 26 kB
import { SharedObject } from 'expo'; import type { VideoPlayerEvents } from './VideoPlayerEvents.types'; import type { VideoThumbnail } from './VideoThumbnail'; /** * A class that represents an instance of the video player. */ export declare class VideoPlayer extends SharedObject<VideoPlayerEvents> { /** * Boolean value whether the player is currently playing. * > Use `play` and `pause` methods to control the playback. */ readonly playing: boolean; /** * Determines whether the player should automatically replay after reaching the end of the video. * @default false */ loop: boolean; /** * Determines whether the player should allow external playback. * @default true * @platform ios */ allowsExternalPlayback: boolean; /** * Determines how the player will interact with other audio playing in the system. * * @default 'auto' * @platform android * @platform ios */ audioMixingMode: AudioMixingMode; /** * Boolean value whether the player is currently muted. * Setting this property to `true`/`false` will mute/unmute the player. * @default false */ muted: boolean; /** * Float value indicating the current playback time in seconds. * * If the player is not yet playing, this value indicates the time position * at which playback will begin once the `play()` method is called. * * Setting `currentTime` to a new value seeks the player to the given time. * Check out the [`seekTolerance`](#seektolerance) property to configure the seeking precision. */ currentTime: number; /** * The exact timestamp when the currently displayed video frame was sent from the server, * based on the `EXT-X-PROGRAM-DATE-TIME` tag in the livestream metadata. * If this metadata is missing, this property will return `null`. * @platform android * @platform ios */ readonly currentLiveTimestamp: number | null; /** * Float value indicating the latency of the live stream in seconds. * If a livestream doesn't have the required metadata, this will return `null`. * @platform android * @platform ios */ readonly currentOffsetFromLive: number | null; /** * Float value indicating the time offset from the live in seconds. * @platform ios */ targetOffsetFromLive: number; /** * Float value indicating the duration of the current video in seconds. */ readonly duration: number; /** * Float value between `0` and `1.0` representing the current volume. * Muting the player doesn't affect the volume. In other words, when the player is muted, the volume is the same as * when unmuted. Similarly, setting the volume doesn't unmute the player. * @default 1.0 */ volume: number; /** * Boolean value indicating if the player should correct audio pitch when the playback speed changes. * @default true */ preservesPitch: boolean; /** * Float value indicating the interval in seconds at which the player will emit the [`timeUpdate`](#videoplayerevents) event. * When the value is equal to `0`, the event will not be emitted. * * @default 0 */ timeUpdateEventInterval: number; /** * Float value between `0` and `16.0` indicating the current playback speed of the player. * @default 1.0 */ playbackRate: number; /** * Boolean indicating if the player should keep the screen on while playing. * * > On Android, this property has an effect only when a [`VideoView`](#videoview) is visible. If you want to keep the screen awake at all times use [`expo-keep-awake`](./keep-awake/). * * @default true * @platform android * @platform ios */ keepScreenOnWhilePlaying: boolean; /** * Boolean value indicating whether the player is currently playing a live stream. */ readonly isLive: boolean; /** * Indicates the current status of the player. */ readonly status: VideoPlayerStatus; /** * Boolean value determining whether the player should show the now playing notification. * * > **Note**: On Android, `supportsBackgroundPlayback` property of the [config plugin](#configuration-in-app-config) * > has to be `true` for the now playing notification to work. * @default false * @platform android * @platform ios */ showNowPlayingNotification: boolean; /** * Determines whether the player should continue playing after the app enters the background. * * > **Note**: The `supportsBackgroundPlayback` property of the [config plugin](#configuration-in-app-config) * > has to be `true` for the background playback to work. * @default false * @platform ios * @platform android */ staysActiveInBackground: boolean; /** * Float value indicating how far the player has buffered the video in seconds. * * This value is 0 when the player has not buffered up to the current playback time. * When it's impossible to determine the buffer state (for example, when the player isn't playing any media), this value is -1. */ readonly bufferedPosition: number; /** * Specifies buffer options which will be used by the player when buffering the video. * * > You should provide a `BufferOptions` object when setting this property. Setting individual buffer properties is not supported. * @platform android * @platform ios */ bufferOptions: BufferOptions; /** * Specifies the subtitle track which is currently displayed by the player. `null` when no subtitles are displayed. * * > To ensure a valid subtitle track, always assign one of the subtitle tracks from the [`availableSubtitleTracks`](#availablesubtitletracks) array. * * @default null * @platform android * @platform ios */ subtitleTrack: SubtitleTrack | null; /** * Specifies the audio track currently played by the player. `null` when no audio is played. * * @default null * @platform android * @platform ios */ audioTrack: AudioTrack | null; /** * An array of audio tracks available for the current video. * * @platform android * @platform ios */ readonly availableAudioTracks: AudioTrack[]; /** * An array of subtitle tracks available for the current video. * * @platform android * @platform ios */ readonly availableSubtitleTracks: SubtitleTrack[]; /** * Specifies the video track currently played by the player. `null` when no video is displayed. * * @default null * @platform android * @platform ios */ readonly videoTrack: VideoTrack | null; /** * An array of video tracks available for the current video. * * > On iOS, when using a HLS source, make sure that the uri contains `.m3u8` extension or that the [`contentType`](#contenttype) property of the [`VideoSource`](#videosource) has been set to `'hls'`. Otherwise, the video tracks will not be available. * * @platform android * @platform ios */ readonly availableVideoTracks: VideoTrack[]; /** * Indicates whether the player is currently playing back the media to an external device via AirPlay. * * @platform ios */ readonly isExternalPlaybackActive: boolean; /** * Determines the time that the actual position seeked to may precede or exceed the requested seek position. * * This property affects the precision of setting the [`currentTime`](#currenttime) property and the [`seekBy`](#seekbyseconds) method, and on Android, it also affects the accuracy of the scrubber from the default native controls. * * By default, the player seeks to the exact requested time. * * > If you are trying to optimize for scrubbing (many frequent seeks), also see [`ScrubbingModeOptions`](#scrubbingmodeoptions-1). */ seekTolerance: SeekTolerance; /** * Determines whether the scrubbing mode is enabled and what scrubbing optimizations should be enabled. * * > See [`SeekTolerance`](#seektolerance) to set the seeking tolerance, which can also affect the scrubbing performance. * */ scrubbingModeOptions: ScrubbingModeOptions; /** * Initializes a new video player instance with the given source. * * @param source The source of the video to be played. * @param useSynchronousReplace Optional parameter, when `true` `source` from the first parameter will be loaded on the main thread. * @param playerBuilderOptions Options to apply to the player builder before the native constructor is invoked. * @hidden */ constructor( source: VideoSource, useSynchronousReplace?: boolean, playerBuilderOptions?: PlayerBuilderOptions ); /** * Resumes the player. */ play(): void; /** * Pauses the player. */ pause(): void; /** * Replaces the current source with a new one. * * > On iOS, this method loads the asset data synchronously on the UI thread and can block it for extended periods of time. * > Use `replaceAsync` to load the asset asynchronously and avoid UI lags. * * > This method will be deprecated in the future. */ replace(source: VideoSource, disableWarning?: boolean): void; /** * Replaces the current source with a new one, while offloading loading of the asset to a different thread. * * > On Android and Web, this method is equivalent to `replace`. */ replaceAsync(source: VideoSource): Promise<void>; /** * Seeks the playback by the given number of seconds. The time to which the player seeks may differ from the specified requested time for efficiency, * depending on the encoding and what is currently buffered by the player. Use this function to implement playback controls that seek by specific amount of time, * in which case, the actual time usually does not have to be precise. For frame accurate seeking, use the [`currentTime`](#currenttime) property. */ seekBy(seconds: number): void; /** * Seeks the playback to the beginning. */ replay(): void; /** * Generates thumbnails from the currently played asset. The thumbnails are references to native images, * thus they can be used as a source of the `Image` component from `expo-image`. * @platform android * @platform ios */ generateThumbnailsAsync( times: number | number[], options?: VideoThumbnailOptions ): Promise<VideoThumbnail[]>; } /** * Additional options for video thumbnails generation. */ export type VideoThumbnailOptions = { /** * If provided, the generated thumbnail will not exceed this width in pixels, preserving its aspect ratio. * @platform android * @platform ios */ maxWidth?: number; /** * If provided, the generated thumbnail will not exceed this height in pixels, preserving its aspect ratio. * @platform android * @platform ios */ maxHeight?: number; }; /** * Describes the current status of the player. * - `idle`: The player is not playing or loading any videos. * - `loading`: The player is loading video data from the provided source * - `readyToPlay`: The player has loaded enough data to start playing or to continue playback. * - `error`: The player has encountered an error while loading or playing the video. */ export type VideoPlayerStatus = 'idle' | 'loading' | 'readyToPlay' | 'error'; export type VideoSource = string | number | null | VideoSourceObject; export type VideoSourceObject = { /** * The URI of the video. * * On iOS, `PHAsset` URIs are supported, but can only be loaded using the [`replaceAsync`](#replaceasyncsource) method or the default [`VideoPlayer`](#videoplayer) constructor. * * This property is exclusive with the `assetId` property. When both are present, the `assetId` will be ignored. */ uri?: string; /** * The asset ID of a local video asset, acquired with the `require` function. * This property is exclusive with the `uri` property. When both are present, the `assetId` will be ignored. */ assetId?: number; /** * Specifies the DRM options which will be used by the player while loading the video. */ drm?: DRMOptions; /** * Specifies information which will be displayed in the now playing notification. * When undefined the player will display information contained in the video metadata. * @platform android * @platform ios */ metadata?: VideoMetadata; /** * Specifies headers sent with the video request. * > For DRM license headers use the `headers` field of [`DRMOptions`](#drmoptions). * @platform android * @platform ios */ headers?: Record<string, string>; /** * Specifies whether the player should use caching for the video. * > Due to platform limitations, the cache cannot be used with HLS video sources on iOS. Caching DRM-protected videos is not supported on Android and iOS. * @default false * @platform android * @platform ios */ useCaching?: boolean; /** * Specifies the content type of the video source. When set to `'auto'`, the player will try to automatically determine the content type. * * You should use this property when playing HLS, SmoothStreaming or DASH videos from an uri, which does not contain a standardized extension for the corresponding media type. * @default 'auto' * @platform android * @platform ios */ contentType?: ContentType; }; /** * Contains information about any errors that the player encountered during the playback */ export type PlayerError = { message: string; }; /** * Contains information that will be displayed in the now playing notification when the video is playing. * @platform android * @platform ios */ export type VideoMetadata = { /** * The title of the video. * @platform android * @platform ios */ title?: string; /** * Secondary text that will be displayed under the title. * @platform android * @platform ios */ artist?: string; /** * The uri of the video artwork. * @platform android * @platform ios */ artwork?: string; }; /** * Specifies which type of DRM to use: * - Android supports ClearKey, PlayReady and Widevine. * - iOS supports FairPlay. */ export type DRMType = 'clearkey' | 'fairplay' | 'playready' | 'widevine'; /** * Specifies DRM options which will be used by the player while loading the video. */ export type DRMOptions = { /** * Determines which type of DRM to use. */ type: DRMType; /** * Determines the license server URL. */ licenseServer: string; /** * Determines headers sent to the license server on license requests. */ headers?: Record<string, string>; /** * Specifies whether the DRM is a multi-key DRM. * @platform android */ multiKey?: boolean; /** * Specifies the content ID of the stream. * @platform ios */ contentId?: string; /** * Specifies the certificate URL for the FairPlay DRM. * @platform ios */ certificateUrl?: string; /** * Specifies the base64 encoded certificate data for the FairPlay DRM. * When this property is set, the `certificateUrl` property is ignored. * @platform ios */ base64CertificateData?: string; }; /** * Specifies buffer options which will be used by the player when buffering the video. * * @platform android * @platform ios */ export type BufferOptions = { /** * The duration in seconds which determines how much media the player should buffer ahead of the current playback time. * * On iOS when set to `0` the player will automatically decide appropriate buffer duration. * * Equivalent to [`AVPlayerItem.preferredForwardBufferDuration`](https://developer.apple.com/documentation/avfoundation/avplayeritem/1643630-preferredforwardbufferduration). * @default Android: 20, iOS: 0 * @platform android * @platform ios */ readonly preferredForwardBufferDuration?: number; /** * A Boolean value that indicates whether the player should automatically delay playback in order to minimize stalling. * * Equivalent to [`AVPlayer.automaticallyWaitsToMinimizeStalling`](https://developer.apple.com/documentation/avfoundation/avplayer/1643482-automaticallywaitstominimizestal). * @default true * @platform ios */ readonly waitsToMinimizeStalling?: boolean; /** * Minimum duration of the buffer in seconds required to continue playing after the player has been paused or started buffering. * * > This property will be ignored if `preferredForwardBufferDuration` is lower. * @default 2 * @platform android */ readonly minBufferForPlayback?: number; /** * The maximum number of bytes that the player can buffer from the network. * When 0 the player will automatically decide appropriate buffer size. * * @default 0 * @platform android */ readonly maxBufferBytes?: number | null; /** * A Boolean value which determines whether the player should prioritize time over size when buffering media. * * @default false * @platform android */ readonly prioritizeTimeOverSizeThreshold?: boolean; }; /** * Specifies the content type of the source. * * - `auto`: The player will automatically determine the content type of the video. * - `progressive`: The player will use progressive download content type. This is the default `ContentType` when the uri does not contain an extension. * - `hls`: The player will use HLS content type. * - `dash`: The player will use DASH content type (Android-only). * - `smoothStreaming`: The player will use SmoothStreaming content type (Android-only). * * @default `auto` */ export type ContentType = 'auto' | 'progressive' | 'hls' | 'dash' | 'smoothStreaming'; /** * Specifies the audio mode that the player should use. Audio mode is set on per-app basis, if there are multiple players playing and * have different a `AudioMode` specified, the highest priority mode will be used. Priority order: 'doNotMix' > 'auto' > 'duckOthers' > 'mixWithOthers'. * * - `mixWithOthers`: The player will mix its audio output with other apps. * - `duckOthers`: The player will lower the volume of other apps if any of the active players is outputting audio. * - `auto`: The player will allow other apps to keep playing audio only when it is muted. On iOS it will always interrupt other apps when `showNowPlayingNotification` is `true` due to system requirements. * - `doNotMix`: The player will pause playback in other apps, even when it's muted. * * > On iOS, the Now Playing notification is dependent on the audio mode. If the audio mode is different from `doNotMix` or `auto` this feature will not work. */ export type AudioMixingMode = 'mixWithOthers' | 'duckOthers' | 'auto' | 'doNotMix'; export type SubtitleTrack = { /** * A string used by `expo-video` to identify the subtitle track. * * @platform android */ id?: string; /** * Language of the subtitle track. For example, `en`, `pl`, `de`. */ language: string; /** * Label of the subtitle track in the language of the device. */ label: string; /** * Name of the subtitle track as specified in the media source. * @platform android * @platform ios */ name?: string; /** * Indicates whether this is the default subtitle track. * @platform android * @platform ios */ isDefault?: boolean; /** * Indicates whether this track should be auto-selected based on user preferences. * @platform android * @platform ios */ autoSelect?: boolean; }; /** * Specifies a VideoTrack loaded from a [`VideoSource`](#videosource). */ export type VideoTrack = { /** * The id of the video track. * * > This field is platform-specific and may return different depending on the operating system. */ id: string; /** * The URL of the `VideoTrack` for HLS video sources. `null` for other source types. */ url: string | null; /** * Size of the video track. */ size: VideoSize; /** * MimeType of the video track or null if unknown. */ mimeType: string | null; /** * Indicates whether the video track format is supported by the device. * * @platform android */ isSupported: boolean; /** * Specifies the bitrate in bits per second. This is the peak bitrate if known, or else the average bitrate if known, or else null. * * @deprecated Use `peakBitrate` or `averageBitrate` instead. */ bitrate: number | null; /** * Specifies the average bitrate in bits per second or null if the value is unknown. * */ averageBitrate: number | null; /** * Specifies the average bitrate in bits per second or null if the value is unknown. */ peakBitrate: number | null; /** * Specifies the frame rate of the video track in frames per second. */ frameRate: number | null; /** * Specifies the video range of the video track. */ videoRange: VideoRange; }; /** * Specifies the size of a video track. */ export type VideoSize = { /** * Width of the video track in pixels. */ width: number; /** * Height of the video track in pixels. */ height: number; }; export type AudioTrack = { /** * A string used by expo-video to identify the audio track. * @platform android */ id?: string; /** * Language of the audio track. For example, 'en', 'pl', 'de'. */ language: string; /** * Label of the audio track in the language of the device. */ label: string; /** * Name of the audio track as specified in the media source. * @platform android * @platform ios */ name?: string; /** * Indicates whether this is the default audio track. * @platform android * @platform ios */ isDefault?: boolean; /** * Indicates whether this track should be auto-selected based on user preferences. * @platform android * @platform ios */ autoSelect?: boolean; }; /** * Determines the time that the actual position seeked to may precede or exceed the requested seek position. * Larger tolerance will usually result in faster seeking. * This property affects the precision of setting the [`currentTime`](#currenttime) property and the [`seekBy`](#seekbyseconds) method, and on Android, it also affects the accuracy of the scrubber from the default native controls. * * > If you are trying to optimize for scrubbing (many frequent seeks), also see [`ScrubbingModeOptions`](#scrubbingmodeoptions-1). * * @platform android * @platform ios */ export type SeekTolerance = { /** * The maximum time that the actual position seeked to may precede the requested seek position, in seconds. Must be non-negative. * @default 0 */ toleranceBefore?: number; /** * The maximum time that the actual position seeked to may exceed the requested seek position, in seconds. Must be non-negative. * @default 0 */ toleranceAfter?: number; }; /** * Defines scrubbing mode options used by a [`VideoPlayer`](#videoplayer). */ export type ScrubbingModeOptions = { /** * Whether the codec operating rate should be increased in scrubbing mode. * * You should only enable this when the player is receiving a large number of seeks in a short period of time. For less frequent seeks, fine-tuning the [`SeekTolerance`](#seektolerance-1) may be sufficient. * * On Android, the player may consume more resources in this mode, so it should only be used for short periods of time in response to user interaction (for example, dragging on a progress bar UI element). * * On Android, when `scrubbingModeEnabled` is `true`, the playback is suppressed. You should set this property back to `false` when the user interaction ends to allow the playback to resume. * For best results, on iOS you should pause the playback when scrubbing. * * > For best scrubbing performance, consider also increasing the seeking tolerance using the [`SeekTolerance`](#seektolerance-1) property. * * > Other scrubbing mode options will have no effect when this is `false`. * @default false * @platform android * @platform ios */ scrubbingModeEnabled?: boolean; /** * Whether the codec operating rate should be increased in scrubbing mode. * * @platform android * @default true */ increaseCodecOperatingRate?: boolean; /** * Sets whether ExoPlayer's dynamic scheduling should be enabled in scrubbing mode. * This can result in available output buffers being handled more quickly when seeking. * * @platform android * @default true */ enableDynamicScheduling?: boolean; /** * Sets whether to use `MediaCodec.BUFFER_FLAG_DECODE_ONLY` in scrubbing mode. * When playback is using MediaCodec on API 34+, this flag can speed up seeking by signalling that the decoded output of buffers between the previous keyframe and the target frame is not needed by the player. * * @platform android * @default true */ useDecodeOnlyFlag?: boolean; /** * Sets whether to avoid flushing the decoder (where possible) in scrubbing mode. * When `true`, avoids flushing the decoder when a new seek starts decoding from a key-frame in compatible content. * * @platform android * @default true */ allowSkippingMediaCodecFlush?: boolean; }; /** * Options to apply to the player builder before the native constructor is invoked * @platform android */ export type PlayerBuilderOptions = { /** * Seek backward increment in seconds. * Values will be clamped between 0.001 and 999 seconds. * @platform android */ seekBackwardIncrement?: number; /** * Seek forward increment in seconds. * Values will be clamped between 0.001 and 999 seconds. * @platform android */ seekForwardIncrement?: number; }; /** * Specifies the dynamic range of the video content. * - `sdr`: Standard Dynamic Range video. * - `hlg`: Hybrid Log-Gamma - HDR backward-compatible with SDR displays * - `pq`: Perceptual Quantizer - Formats like HDR10 and Dolby Vision */ export type VideoRange = 'sdr' | 'hlg' | 'pq';