Expo Video (expo-video)
A library that provides an API to implement video playback in apps.
expo-videois a new, experimental library that aims to replace theVideocomponent fromexpo-avwith a more modern and reliable implementation. If you are looking for a more stable API, useexpo-avuntil this library has stabilized.
To provide quicker updates,expo-videois currently unsupported in Expo Go and Snack. To use it, create a development build.
expo-video is a cross-platform, performant video component for React Native and Expo with Web support.
Installation
- npx expo install expo-videoIf you are installing this in an existing React Native app, make sure to install expo in your project.
Usage
Here's a simple example of a video with a play and pause button.
import { useVideoPlayer, VideoView } from 'expo-video'; import { useEffect, useRef, useState } from 'react'; import { PixelRatio, StyleSheet, View, Button } from 'react-native'; const videoSource = 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'; export default function VideoScreen() { const ref = useRef(null); const [isPlaying, setIsPlaying] = useState(true); const player = useVideoPlayer(videoSource, player => { player.loop = true; player.play(); }); useEffect(() => { const subscription = player.addListener('playingChange', isPlaying => { setIsPlaying(isPlaying); }); return () => { subscription.remove(); }; }, [player]); return ( <View style={styles.contentContainer}> <VideoView ref={ref} style={styles.video} player={player} allowsFullscreen allowsPictureInPicture /> <View style={styles.controlsContainer}> <Button title={isPlaying ? 'Pause' : 'Play'} onPress={() => { if (isPlaying) { player.pause(); } else { player.play(); } setIsPlaying(!isPlaying); }} /> </View> </View> ); } const styles = StyleSheet.create({ contentContainer: { flex: 1, padding: 10, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 50, }, video: { width: 350, height: 275, }, controlsContainer: { padding: 10, }, });
API
import { VideoView, useVideoPlayer } from 'expo-video';
Component
Type: React.PureComponent<VideoViewProps>
boolean • Default: trueDetermines whether fullscreen mode is allowed or not.
booleanDetermines whether the player allows Picture in Picture (PiP) mode.
Note: The
supportsPictureInPictureproperty of the config plugin has to be configured for the PiP to work.
boolean • Default: trueSpecifies whether to perform video frame analysis (Live Text in videos). Check official Apple documentation for more details.
VideoContentFit • Default: 'contain'Describes how the video should be scaled to fit in the container.
Options are 'contain', 'cover', and 'fill'.
{
dx: number,
dy: number
}Determines the position offset of the video inside the container.
boolean • Default: trueDetermines whether native controls should be displayed or not.
() => voidA callback to call after the mounted VideoPlayer has rendered the first frame into the VideoView.
This event can be used to hide any cover images that conceal the initial loading of the player.
Note: This event may also be called during playback when the current video track changes (for example when the player switches video quality).
() => voidA callback to call after the video player enters fullscreen mode.
() => voidA callback to call after the video player exits fullscreen mode.
() => voidA callback to call after the video player enters Picture in Picture (PiP) mode.
() => voidA callback to call after the video player exits Picture in Picture (PiP) mode.
booleanDetermines whether a video should be played "inline", that is, within the element's playback area.
boolean • Default: falseDetermines whether the player allows the user to skip media content.
boolean • Default: trueDetermines whether the timecodes should be displayed or not.
boolean • Default: falseDetermines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.
Note: Only one player can be in Picture in Picture (PiP) mode at a time.
Note: The
supportsPictureInPictureproperty of the config plugin has to be configured for the PiP to work.
SurfaceType • Default: 'surfaceView'Determines the type of the surface used to render the video.
This prop should not be changed at runtime.
boolean • Default: trueDetermines whether the player should use the default ExoPlayer shutter that covers the VideoView before the first video frame is rendered.
Setting this property to false makes the Android behavior the same as iOS.
Component Methods
Enters fullscreen mode.
Promise<void>Exits fullscreen mode.
Promise<void>Enters Picture in Picture (PiP) mode. Throws an exception if the device does not support PiP.
Note: Only one player can be in Picture in Picture (PiP) mode at a time.
Note: The
supportsPictureInPictureproperty of the config plugin has to be configured for the PiP to work.
Promise<void>Exits Picture in Picture (PiP) mode.
Promise<void>Hooks
| Parameter | Type | Description |
|---|---|---|
| source | VideoSource | A video source that is used to initialize the player. |
| setup(optional) | (player: VideoPlayer) => void | A function that allows setting up the player. It will run after the player is created. |
Creates a VideoPlayer, which will be automatically cleaned up when the component is unmounted.
VideoPlayerClasses
Type: Class extends SharedObject<VideoPlayerEvents>
A class that represents an instance of the video player.
VideoPlayer Properties
boolean • Default: trueDetermines whether the player should allow external playback.
AudioMixingMode • Default: 'auto'Determines how the player will interact with other audio playing in the system.
SubtitleTrack[]An array of subtitle tracks available for the current video.
VideoTrack[]An array of video tracks available for the current video.
On iOS, when using a HLS source, make sure that the uri contains
.m3u8extension or that thecontentTypeproperty of theVideoSourcehas been set to'hls'. Otherwise, the video tracks will not be available.
numberFloat 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.
BufferOptionsSpecifies buffer options which will be used by the player when buffering the video.
You should provide a
BufferOptionsobject when setting this property. Setting individual buffer properties is not supported.
unionThe 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.
Acceptable values are: null | number
unionFloat value indicating the latency of the live stream in seconds.
If a livestream doesn't have the required metadata, this will return null.
Acceptable values are: null | number
numberFloat 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.
Note that frame accurate seeking may incur additional decoding delay which can impact seeking performance.
Consider using the seekBy function if the time does not have to be set precisely.
numberFloat value indicating the duration of the current video in seconds.
booleanBoolean value indicating whether the player is currently playing a live stream.
boolean • Default: falseDetermines whether the player should automatically replay after reaching the end of the video.
boolean • Default: falseBoolean value whether the player is currently muted.
Setting this property to true/false will mute/unmute the player.
number • Default: 1.0Float value between 0 and 16.0 indicating the current playback speed of the player.
booleanBoolean value whether the player is currently playing.
Use
playandpausemethods to control the playback.
boolean • Default: trueBoolean value indicating if the player should correct audio pitch when the playback speed changes.
boolean • Default: falseBoolean value determining whether the player should show the now playing notification.
boolean • Default: falseDetermines whether the player should continue playing after the app enters the background.
union • Default: nullSpecifies 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
availableSubtitleTracksarray.
Acceptable values are: null | SubtitleTrack
numberFloat value indicating the time offset from the live in seconds.
number • Default: 0Float value indicating the interval in seconds at which the player will emit the timeUpdate event.
When the value is equal to 0, the event will not be emitted.
union • Default: nullSpecifies the video track currently played by the player. null when no video is displayed.
Acceptable values are: null | VideoTrack
VideoPlayer Methods
| Parameter | Type |
|---|---|
| times | number | number[] |
| options(optional) | VideoThumbnailOptions |
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.
Promise<VideoThumbnail[]>| Parameter | Type |
|---|---|
| source | VideoSource |
| disableWarning(optional) | boolean |
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
replaceAsyncto load the asset asynchronously and avoid UI lags.
This method will be deprecated in the future.
void| Parameter | Type |
|---|---|
| source | VideoSource |
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.
Promise<void>| Parameter | Type |
|---|---|
| seconds | number |
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 property.
voidType: Class extends SharedRef<'image'>
Represents a video thumbnail that references a native image.
Instances of this class can be passed as a source to the Image component from expo-image.
VideoThumbnail Properties
numberThe time in seconds at which the thumbnail was actually generated.
numberThe time in seconds at which the thumbnail was to be created.
Methods
Clears all video cache.
This function can be called only if there are no existing
VideoPlayerinstances.
Promise<void>A promise that fulfills after the cache has been cleaned.
| Parameter | Type |
|---|---|
| source | VideoSource |
Creates a direct instance of VideoPlayer that doesn't release automatically.
For most use cases you should use theuseVideoPlayerhook instead. See the Using the VideoPlayer Directly section for more details.
VideoPlayerReturns the space currently occupied by the video cache in bytes.
numberReturns whether the current device supports Picture in Picture (PiP) mode.
booleanA boolean which is true if the device supports PiP mode, and false otherwise.
| Parameter | Type |
|---|---|
| sizeBytes | number |
Sets desired video cache size in bytes. The default video cache size is 1GB. Value set by this function is persistent. The cache size is not guaranteed to be exact and the actual cache size may be slightly larger. The cache is evicted on a least-recently-used basis.
This function can be called only if there are no existing
VideoPlayerinstances.
Promise<void>A promise that fulfills after the cache size has been set.
Types
Literal Type: string
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 whenshowNowPlayingNotificationistruedue 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
doNotMixorautothis feature will not work.
Acceptable values are: 'mixWithOthers' | 'duckOthers' | 'auto' | 'doNotMix'
Specifies buffer options which will be used by the player when buffering the video.
| Property | Type | Description |
|---|---|---|
| maxBufferBytes(optional) | number | null | Only for: Android 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 |
| minBufferForPlayback(optional) | number | Only for: Android Minimum duration of the buffer in seconds required to continue playing after the player has been paused or started buffering.
Default: 2 |
| preferredForwardBufferDuration(optional) | number | Only for: Android iOS The duration in seconds which determines how much media the player should buffer ahead of the current playback time. On iOS when set to Equivalent to Default: Android: 20, iOS: 0 |
| prioritizeTimeOverSizeThreshold(optional) | boolean | Only for: Android A Boolean value which determines whether the player should prioritize time over size when buffering media. Default: false |
| waitsToMinimizeStalling(optional) | boolean | Only for: iOS A Boolean value that indicates whether the player should automatically delay playback in order to minimize stalling. Equivalent to Default: true |
Literal Type: string
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 defaultContentTypewhen 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).
Acceptable values are: 'auto' | 'progressive' | 'hls' | 'dash' | 'smoothStreaming'
Specifies DRM options which will be used by the player while loading the video.
| Property | Type | Description |
|---|---|---|
| base64CertificateData(optional) | string | Only for: iOS Specifies the base64 encoded certificate data for the FairPlay DRM.
When this property is set, the |
| certificateUrl(optional) | string | Only for: iOS Specifies the certificate URL for the FairPlay DRM. |
| contentId(optional) | string | Only for: iOS Specifies the content ID of the stream. |
| headers(optional) | Record<string, string> | Determines headers sent to the license server on license requests. |
| licenseServer | string | Determines the license server URL. |
| multiKey(optional) | boolean | Only for: Android Specifies whether the DRM is a multi-key DRM. |
| type | DRMType | Determines which type of DRM to use. |
Literal Type: string
Specifies which type of DRM to use:
- Android supports ClearKey, PlayReady and Widevine.
- iOS supports FairPlay.
Acceptable values are: 'clearkey' | 'fairplay' | 'playready' | 'widevine'
Data delivered with the mutedChange event.
| Property | Type | Description |
|---|---|---|
| muted | boolean | Boolean value whether the player is currently muted. |
| oldMuted(optional) | boolean | Previous value of the |
Data delivered with the playbackRateChange event.
| Property | Type | Description |
|---|---|---|
| oldPlaybackRate(optional) | number | Previous value of the |
| playbackRate | number | Float value indicating the current playback speed of the player. |
Contains information about any errors that the player encountered during the playback
| Property | Type | Description |
|---|---|---|
| message | string | - |
Data delivered with the playingChange event.
| Property | Type | Description |
|---|---|---|
| isPlaying | boolean | Boolean value whether the player is currently playing. |
| oldIsPlaying(optional) | boolean | Previous value of the |
Data delivered with the sourceChange event.
| Property | Type | Description |
|---|---|---|
| oldSource(optional) | VideoSource | Previous source of the player. |
| source | VideoSource | New source of the player. |
Data delivered with the sourceLoad event, contains information about the video source that has finished loading.
| Property | Type | Description |
|---|---|---|
| availableSubtitleTracks | SubtitleTrack[] | Subtitle tracks available for the loaded video source. |
| availableVideoTracks | VideoTrack[] | Video tracks available for the loaded video source.
|
| duration | number | Duration of the video source in seconds. |
| videoSource | VideoSource | null | The video source that has been loaded. |
Data delivered with the statusChange event.
| Property | Type | Description |
|---|---|---|
| error(optional) | PlayerError | Error object containing information about the error that occurred. |
| oldStatus(optional) | VideoPlayerStatus | Previous status of the player. |
| status | VideoPlayerStatus | New status of the player. |
| Property | Type | Description |
|---|---|---|
| id | string | Only for: Android A string used by |
| label | string | Label of the subtitle track in the language of the device. |
| language | string | Language of the subtitle track. For example, |
Literal Type: string
Describes the type of the surface used to render the video.
surfaceView: Uses theSurfaceViewto render the video. This value should be used in the majority of cases. Provides significantly lower power consumption, better performance, and more features.textureView: Uses theTextureViewto render the video. Should be used in cases where the SurfaceView is not supported or causes issues (for example, overlapping video views).
You can learn more about surface types in the official ExoPlayer documentation.
Acceptable values are: 'textureView' | 'surfaceView'
Data delivered with the timeUpdate event, contains information about the current playback progress.
| Property | Type | Description |
|---|---|---|
| bufferedPosition | number | Only for: Android iOS Float value indicating how far the player has buffered the video in seconds.
Same as the |
| currentLiveTimestamp | number | null | Only for: Android iOS The exact timestamp when the currently displayed video frame was sent from the server,
based on the |
| currentOffsetFromLive | number | null | Only for: Android iOS Float value indicating the latency of the live stream in seconds.
Same as the |
| currentTime | number | Float value indicating the current playback time in seconds. Same as the |
Literal Type: string
Describes how a video should be scaled to fit in a container.
contain: The video maintains its aspect ratio and fits inside the container, with possible letterboxing/pillarboxing.cover: The video maintains its aspect ratio and covers the entire container, potentially cropping some portions.fill: The video stretches/squeezes to completely fill the container, potentially causing distortion.
Acceptable values are: 'contain' | 'cover' | 'fill'
Contains information that will be displayed in the now playing notification when the video is playing.
| Property | Type | Description |
|---|---|---|
| artist(optional) | string | Only for: Android iOS Secondary text that will be displayed under the title. |
| artwork(optional) | string | Only for: Android iOS The uri of the video artwork. |
| title(optional) | string | Only for: Android iOS The title of the video. |
Handlers for events which can be emitted by the player.
| Property | Type | Description |
|---|---|---|
| availableSubtitleTracksChange | (payload: AvailableSubtitleTracksChangeEventPayload) => void | Handler for an event emitted when the available subtitle tracks change. |
| mutedChange | (payload: MutedChangeEventPayload) => void | Handler for an event emitted when the |
| playbackRateChange | (payload: PlaybackRateChangeEventPayload) => void | Handler for an event emitted when the |
| playingChange | (payload: PlayingChangeEventPayload) => void | Handler for an event emitted when the player starts or stops playback. |
| playToEnd | () => void | Handler for an event emitted when the player plays to the end of the current source. |
| sourceChange | (payload: SourceChangeEventPayload) => void | Handler for an event emitted when the current media source of the player changes. |
| sourceLoad | (payload: SourceLoadEventPayload) => void | Handler for an event emitted when the player has finished loading metadata for the current video source.
This event is emitted when the player has finished metadata for a |
| statusChange | (payload: StatusChangeEventPayload) => void | Handler for an event emitted when the status of the player changes. |
| subtitleTrackChange | (payload: SubtitleTrackChangeEventPayload) => void | Handler for an event emitted when the current subtitle track changes. |
| timeUpdate | (payload: TimeUpdateEventPayload) => void | Handler for an event emitted in a given interval specified by the |
| videoTrackChange | (payload: VideoTrackChangeEventPayload) => void | Handler for an event emitted when the current video track changes. |
| volumeChange | (payload: VolumeChangeEventPayload) => void | Handler for an event emitted when the |
Literal Type: string
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 sourcereadyToPlay: 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.
Acceptable values are: 'idle' | 'loading' | 'readyToPlay' | 'error'
Specifies the size of a video track.
| Property | Type | Description |
|---|---|---|
| height | number | Height of the video track in pixels. |
| width | number | Width of the video track in pixels. |
Type: string or number or null or object shaped as below:
| Property | Type | Description |
|---|---|---|
| assetId(optional) | number | The asset ID of a local video asset, acquired with the |
| contentType(optional) | ContentType | Only for: Android iOS Specifies the content type of the video source. When set to 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' |
| drm(optional) | DRMOptions | Specifies the DRM options which will be used by the player while loading the video. |
| headers(optional) | Record<string, string> | Only for: Android iOS Specifies headers sent with the video request.
|
| metadata(optional) | VideoMetadata | Only for: Android iOS Specifies information which will be displayed in the now playing notification. When undefined the player will display information contained in the video metadata. |
| uri(optional) | string | The URI of the video. This property is exclusive with the |
| useCaching(optional) | boolean | Only for: Android iOS Specifies whether the player should use caching for the video.
Default: false |
Additional options for video thumbnails generation.
| Property | Type | Description |
|---|---|---|
| maxHeight(optional) | number | Only for: Android iOS If provided, the generated thumbnail will not exceed this height in pixels, preserving its aspect ratio. |
| maxWidth(optional) | number | Only for: Android iOS If provided, the generated thumbnail will not exceed this width in pixels, preserving its aspect ratio. |
Specifies a VideoTrack loaded from a VideoSource.
| Property | Type | Description |
|---|---|---|
| bitrate | number | null | Specifies the bitrate in bits per second. This is the peak bitrate if known, or else the average bitrate if known, or else null. |
| frameRate | number | null | Specifies the frame rate of the video track in frames per second. |
| id | string | The id of the video track.
|
| isSupported | boolean | Only for: Android Indicates whether the video track format is supported by the device. |
| mimeType | string | null | MimeType of the video track or null if unknown. |
| size | VideoSize | Size of the video track. |
Data delivered with the volumeChange event.
| Property | Type | Description |
|---|---|---|
| oldVolume(optional) | number | Previous value of the |
| volume | number | Float value indicating the current volume of the player. |