A library that provides an API to implement video playback in apps.
expo-video
is a new, experimental library that aims to replace theVideo
component fromexpo-av
with a more modern and reliable implementation. If you are looking for a more stable API, useexpo-av
until this library has stabilized.
To provide quicker updates,expo-video
is 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.
-
npx expo install expo-video
If you are installing this in an existing React Native app, start by installing expo
in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
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,
},
});
import { VideoView, useVideoPlayer } from 'expo-video';
VideoView
Type: React.PureComponent<VideoViewProps>
allowsFullscreen
boolean
• Default: true
Determines whether fullscreen mode is allowed or not.
allowsPictureInPicture
boolean
• Default: false
Determines whether the player allows Picture in Picture (PiP) mode.
Note: The
supportsPictureInPicture
property of the config plugin has to be configured for the PiP to work.
allowsVideoFrameAnalysis
boolean
• Default: true
Specifies whether to perform video frame analysis (Live Text in videos). Check official Apple documentation for more details.
contentFit
VideoContentFit
• Default: 'contain'
Describes how the video should be scaled to fit in the container. Options are 'contain', 'cover', and 'fill'.
contentPosition
{
dx: number,
dy: number
}
Determines the position offset of the video inside the container.
nativeControls
boolean
• Default: true
Determines whether native controls should be displayed or not.
onFullscreenEnter
() => void
A callback to call after the video player enters fullscreen mode.
onFullscreenExit
() => void
A callback to call after the video player exits fullscreen mode.
onPictureInPictureStart
() => void
A callback to call after the video player enters Picture in Picture (PiP) mode.
onPictureInPictureStop
() => void
A callback to call after the video player exits Picture in Picture (PiP) mode.
requiresLinearPlayback
boolean
• Default: false
Determines whether the player allows the user to skip media content.
showsTimecodes
boolean
• Default: true
Determines whether the timecodes should be displayed or not.
startsPictureInPictureAutomatically
boolean
• Default: false
Determines 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
supportsPictureInPicture
property of the config plugin has to be configured for the PiP to work.
startPictureInPicture()
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
supportsPictureInPicture
property of the config plugin has to be configured for the PiP to work.
void
useVideoPlayer(source, setup)
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.
VideoPlayer
Type: Class extends _default<VideoPlayerEvents>
A class that represents an instance of the video player.
VideoPlayer Properties
currentLiveTimestamp
null | 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
.
This property is read-only.
currentOffsetFromLive
null | number
Float value indicating the latency of the live stream in seconds.
If a livestream doesn't have the required metadata, this will return null
.
This property is get-only
currentTime
number
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.
duration
number
Float value indicating the duration of the current video in seconds.
This property is get-only
isLive
boolean
Boolean value indicating whether the player is currently playing a live stream.
This property is get-only
loop
boolean
• Default: false
Determines whether the player should automatically replay after reaching the end of the video.
muted
boolean
• Default: false
Boolean value whether the player is currently muted.
Setting this property to true
/false
will mute/unmute the player.
playbackRate
number
• Default: 1.0
Float value between 0 and 16 indicating the current playback speed of the player.
playing
boolean
Boolean value whether the player is currently playing.
This property is get-only, use
play
andpause
methods to control the playback.
preservesPitch
boolean
• Default: true
Boolean value indicating if the player should correct audio pitch when the playback speed changes.
On web, changing this property is not supported, the player will always correct the pitch.
showNowPlayingNotification
boolean
• Default: false
Boolean value determining whether the player should show the now playing notification.
staysActiveInBackground
boolean
• Default: false
Determines whether the player should continue playing after the app enters the background.
targetOffsetFromLive
number
Float value indicating the time offset from the live in seconds.
volume
number
• Default: 1.0
Float value between 0 and 1 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.
VideoPlayer Methods
replace(source)
Parameter | Type |
---|---|
source | VideoSource |
Replaces the current source with a new one.
void
seekBy(seconds)
Parameter | Type |
---|---|
seconds | number |
Seeks the playback by the given number of seconds.
void
Video.isPictureInPictureSupported()
Returns whether the current device supports Picture in Picture (PiP) mode.
boolean
A boolean
which is true
if the device supports PiP mode, and false
otherwise.
DRMOptions
Specifies DRM options which will be used by the player while loading the video.
Name | 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) | undefined | 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. |
DRMType
Literal Type: string
Specifies which type of DRM to use. Android supports Widevine, PlayReady and ClearKey, iOS supports FairPlay.
Acceptable values are: 'clearkey'
| 'fairplay'
| 'playready'
| 'widevine'
PlayerError
Contains information about any errors that the player encountered during the playback
Name | Type | Description |
---|---|---|
message | string | - |
VideoContentFit
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'
VideoMetadata
Contains information that will be displayed in the now playing notification when the video is playing.
Name | Type | Description |
---|---|---|
artist (optional) | string | Secondary text that will be displayed under the title. |
title (optional) | string | The title of the video. |
VideoPlayerEvents
Handlers for events which can be emitted by the player.
Name | Type | Description |
---|---|---|
playToEnd | () => void | Handler for an event emitted when the player plays to the end of the current source. |
playbackRateChange | (newPlaybackRate: number, oldPlaybackRate: number) => void | Handler for an event emitted when the |
playingChange | (newIsPlaying: boolean, oldIsPlaying: boolean) => void | Handler for an event emitted when the player starts or stops playback. |
sourceChange | (newSource: VideoSource, previousSource: VideoSource) => void | Handler for an event emitted when the current media source of the player changes. |
statusChange | (newStatus: VideoPlayerStatus, oldStatus: VideoPlayerStatus, error?: PlayerError) => void | Handler for an event emitted when the status of the player changes. |
volumeChange | (newVolume: VolumeEvent, oldVolume: VolumeEvent) => void | Handler for an event emitted when the |
VideoPlayerStatus
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'
VideoSource
Type: string
or number
or null
or object shaped as below:
Name | Type | Description |
---|---|---|
assetId (optional) | number | The asset ID of a local video asset, acquired with the |
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 | 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 |
VolumeEvent
Contains information about the current volume and whether the player is muted.
Name | Type | Description |
---|---|---|
isMuted | boolean | - |
volume | number | - |