HomeGuidesReferenceLearn

Reference version

ArchiveExpo SnackDiscord and ForumsNewsletter
This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 51).

Expo Video

GitHub

npm

A library that provides an API to implement video playback in apps.

Android
iOS
Web

expo-video is a new, experimental library that aims to replace the Video component from expo-av with a more modern and reliable implementation. If you are looking for a more stable API, use expo-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.

Installation

Terminal
- npx expo install expo-video

If you are installing this in an existing React Native app (bare workflow), start by installing expo in your project. Then, follow the additional instructions as mentioned by library's README under "Installation in bare React Native projects" section.

Configuration in app config

You can configure expo-video using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. If your app does not use EAS Build, then you'll need to manually configure the package.

Example app.json with config plugin

app.json
{
  "expo": {
    "plugins": [
      [
        "expo-video",
        {
          "supportsBackgroundPlayback": true,
          "supportsPictureInPicture": true
        }
      ]
    ],
  }
}

Configurable properties

NameDefaultDescription
supportsBackgroundPlaybackundefined
Only for: 
iOS

A boolean value to enable background playback on iOS. If true, the audio key is added to the UIBackgroundModes array in the Info.plist file. If false, the key is removed. When undefined, the key is not modified.

supportsPictureInPictureundefined

A boolean value to enable Picture-in-Picture on Android and iOS. Configures the android:supportsPictureInPicture property on Android and the UIBackgroundModes array in the Info.plist file on iOS. When undefined, the configuration is not modified.

Usage

Here's a simple example of a video with a play and pause button.

Video
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

VideoView

Type: React.PureComponent<VideoViewProps>

VideoViewProps

Android
iOS
Web

allowsFullscreen

Optional • Type: boolean • Default: true

Determines whether fullscreen mode is allowed or not.

iOS 14+

allowsPictureInPicture

Optional • Type: 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.

iOS 16.0+

allowsVideoFrameAnalysis

Optional • Type: boolean • Default: true

Specifies whether to perform video frame analysis (Live Text in videos). Check official Apple documentation for more details.

Android
iOS
Web

contentFit

Optional • Type: VideoContentFit • Default: 'contain'

Describes how the video should be scaled to fit in the container. Options are 'contain', 'cover', and 'fill'.

iOS

contentPosition

Optional • Type: { dx: number, dy: number }

Determines the position offset of the video inside the container.

Android
iOS
Web

nativeControls

Optional • Type: boolean • Default: true

Determines whether native controls should be displayed or not.

Android
iOS 14+

onPictureInPictureStart

Optional • Type: () => void

A callback to call after the video player enters Picture in Picture (PiP) mode.

Android
iOS 14+

onPictureInPictureStop

Optional • Type: () => void

A callback to call after the video player exits Picture in Picture (PiP) mode.

Android
iOS
Web

player

Type: VideoPlayer

A player instance – use useVideoPlayer() to create one.

Android
iOS

requiresLinearPlayback

Optional • Type: boolean • Default: false

Determines whether the player allows the user to skip media content.

iOS

showsTimecodes

Optional • Type: boolean • Default: true

Determines whether the timecodes should be displayed or not.

Android 12+
iOS 14.2+

startsPictureInPictureAutomatically

Optional • Type: 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.

Inherited Props

  • ViewProps

Component Methods

Android
iOS
Web

enterFullscreen()

Enters fullscreen mode.

Returns:

void

Android
iOS
Web

exitFullscreen()

Exits fullscreen mode.

Returns:

void

Android
iOS 14+

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.

Returns:

void

Android
iOS 14+

stopPictureInPicture()

Exits Picture in Picture (PiP) mode.

Returns:

void

Hooks

Android
iOS
Web

useVideoPlayer(source, setup)

NameTypeDescription
sourceVideoSource

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.

Returns:

VideoPlayer

Classes

Android
iOS
Web

VideoPlayer

Type: Class extends SharedObject<VideoPlayerEvents>

A class that represents an instance of the video player.

VideoPlayer Properties

Android
iOS
Web

currentTime

Type: 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.

Android
iOS
Web

duration

Type: number

Float value indicating the duration of the current video in seconds.

This property is get-only

Android
iOS
Web

isLive

Type: boolean

Boolean value indicating whether the player is currently playing a live stream.

This property is get-only

Android
iOS
Web

loop

Type: boolean

Determines whether the player should automatically replay after reaching the end of the video.

Android
iOS
Web

muted

Type: boolean

Boolean value whether the player is currently muted. Setting this property to true/false will mute/unmute the player.

Android
iOS
Web

playbackRate

Type: number

Float value between 0 and 16 indicating the current playback speed of the player.

Android
iOS
Web

playing

Type: boolean

Boolean value whether the player is currently playing.

This property is get-only, use play and pause methods to control the playback.

Android
iOS

preservesPitch

Type: boolean

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.

Android
iOS
Web

showNowPlayingNotification

Type: boolean

Boolean value determining whether the player should show the now playing notification.

Android
iOS
Web

status

Type: VideoPlayerStatus

Indicates the current status of the player.

This property is get-only

iOS
Android

staysActiveInBackground

Type: boolean

Determines whether the player should continue playing after the app enters the background.

Android
iOS
Web

volume

Type: number

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

Android
iOS
Web

pause()

Pauses the player.

Returns:

void

Android
iOS
Web

play()

Resumes the player.

Returns:

void

Android
iOS
Web

replace(source)

NameType
sourceVideoSource

Replaces the current source with a new one.

Returns:

void

Android
iOS
Web

replay()

Seeks the playback to the beginning.

Returns:

void

Android
iOS
Web

seekBy(seconds)

NameType
secondsnumber

Seeks the playback by the given number of seconds.

Returns:

void

Methods

Android
iOS

Video.isPictureInPictureSupported()

Returns whether the current device supports Picture in Picture (PiP) mode.

Returns:

boolean

A boolean which is true if the device supports PiP mode, and false otherwise.

Types

Android
iOS
Web

DRMOptions

Specifies DRM options which will be used by the player while loading the video.

NameTypeDescription
base64CertificateData
(optional)
string
Only for: 
iOS

Specifies the base64 encoded certificate data for the FairPlay DRM. When this property is set, the certificateUrl property is ignored.

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.

licenseServerstring

Determines the license server URL.

multiKey
(optional)
boolean
Only for: 
Android

Specifies whether the DRM is a multi-key DRM.

typeDRMType

Determines which type of DRM to use.

Android
iOS
Web

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'

Android
iOS
Web

PlayerError

Contains information about any errors that the player encountered during the playback

NameTypeDescription
messagestring-
Android
iOS
Web

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'

Android
iOS
Web

VideoMetadata

Contains information that will be displayed in the now playing notification when the video is playing.

NameTypeDescription
artist
(optional)
string

Secondary text that will be displayed under the title.

title
(optional)
string

The title of the video.

Android
iOS
Web

VideoPlayerEvents

Handlers for events which can be emitted by the player.

NameTypeDescription
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 playbackRate property of the player changes.

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 volume property of the player changes.

Android
iOS
Web

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 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.

Acceptable values are: 'idle' | 'loading' | 'readyToPlay' | 'error'

Android
iOS
Web

VideoSource

Type: string or object shaped as below:


NameTypeDescription
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.

For DRM license headers use the headers field of DRMOptions.

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.

uristring

The URI of the video.

Android
iOS
Web

VolumeEvent

Contains information about the current volume and whether the player is muted.

NameTypeDescription
isMutedboolean-
volumenumber-