This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo AV
A universal library that provides separate APIs for Audio and Video playback.
Deprecated: The
VideoandAudioAPIs fromexpo-avhave now been deprecated and replaced by improved versions inexpo-videoandexpo-audio. We recommend using those libraries instead.expo-avis not receiving patches and will be removed in SDK 55.
The Audio.Sound objects and Video components share a unified imperative API for media playback.
Note that for Video, all of the operations are also available via props on the component. However, we recommend using this imperative playback API for most applications where finer control over the state of the video playback is needed.
See the playlist example app for an example on the playback API for both Audio.Sound and Video.
Audio recording APIs are not available on tvOS (Apple TV).
Installation
If you are installing this in an existing React Native app, make sure to install expo in your project.
Configuration in app config
You can configure expo-av using its built-in config plugin if you use config plugins in your project (Continuous Native Generation (CNG)). 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 CNG, then you'll need to manually configure the library.
Example app.json with config plugin
Configurable properties
Are you using this library in an existing React Native app?
If you're not using Continuous Native Generation (CNG) (you're using native android and ios projects manually), then you need to configure following permissions in your native projects:
-
For Android, add
android.permission.RECORD_AUDIOpermission to your project's android/app/src/main/AndroidManifest.xml:<uses-permission android:name="android.permission.RECORD_AUDIO" /> -
For iOS, add
NSMicrophoneUsageDescriptionto your project's ios/[app]/Info.plist:<key>NSMicrophoneUsageDescription</key> <string>Allow $(PRODUCT_NAME) to access your microphone</string>
Usage
On this page, we reference operations on playbackObject. Here is an example of obtaining access to the reference for both sound and video:
Example: Audio.Sound
await Audio.setAudioModeAsync({ playsInSilentModeIOS: true }); const playbackObject = new Audio.Sound(); // OR const { sound: playbackObject } = await Audio.Sound.createAsync( { uri: 'http://foo/bar.mp3' }, { shouldPlay: true } );
See the audio documentation for further information on Audio.Sound.createAsync().
Example: Video
%%placeholder-start%%... %%placeholder-end%% _handleVideoRef = component => { const playbackObject = component; ... } %%placeholder-start%%... %%placeholder-end%% render() { return ( <Video ref={this._handleVideoRef} /> %%placeholder-start%%... %%placeholder-end%% ) }
See the video documentation for further information.
Example: setOnPlaybackStatusUpdate()
_onPlaybackStatusUpdate = playbackStatus => { if (!playbackStatus.isLoaded) { // Update your UI for the unloaded state if (playbackStatus.error) { console.log(`Encountered a fatal error during playback: ${playbackStatus.error}`); // Send Expo team the error on Slack or the forums so we can help you debug! } } else { // Update your UI for the loaded state if (playbackStatus.isPlaying) { // Update your UI for the playing state } else { // Update your UI for the paused state } if (playbackStatus.isBuffering) { // Update your UI for the buffering state } if (playbackStatus.didJustFinish && !playbackStatus.isLooping) { // The player has just finished playing and will stop. Maybe you want to play something else? } %%placeholder-start%%... %%placeholder-end%% } }; // Load the playbackObject and obtain the reference. playbackObject.setOnPlaybackStatusUpdate(this._onPlaybackStatusUpdate);
Example: Loop media exactly 20 times
const N = 20; %%placeholder-start%%... %%placeholder-end%% _onPlaybackStatusUpdate = playbackStatus => { if (playbackStatus.didJustFinish) { if (this.state.numberOfLoops == N - 1) { playbackObject.setIsLooping(false); } this.setState({ numberOfLoops: this.state.numberOfLoops + 1 }); } }; %%placeholder-start%%... %%placeholder-end%% this.setState({ numberOfLoops: 0 }); // Load the playbackObject and obtain the reference. playbackObject.setOnPlaybackStatusUpdate(this._onPlaybackStatusUpdate); playbackObject.setIsLooping(true);
What is seek tolerance and why would I want to use it iOS
When asked to seek an A/V item, native player in iOS sometimes may seek to a slightly different time. This technique, mentioned in Apple documentation, is used to shorten the time of the seekTo call (the player may decide to play immediately from a different time than requested, instead of decoding the exact requested part and playing it with the decoding delay).
If precision is important, you can specify the tolerance with which the player will seek. However, this will result in an increased delay.
API
import { Audio, Video } from 'expo-av';
Constants
Type: AVPlaybackStatusToSet
The default initial AVPlaybackStatusToSet of all Audio.Sound objects and Video components is as follows:
{ progressUpdateIntervalMillis: 500, positionMillis: 0, shouldPlay: false, rate: 1.0, shouldCorrectPitch: false, volume: 1.0, isMuted: false, isLooping: false, }
This default initial status can be overwritten by setting the optional initialStatus in loadAsync() or Audio.Sound.createAsync().
Interfaces
Gets the AVPlaybackStatus of the playbackObject.
Promise<AVPlaybackStatus>A Promise that is fulfilled with the AVPlaybackStatus of the playbackObject.
Sets a new AVPlaybackStatusToSet on the playbackObject. This method can only be called if the media has been loaded.
Promise<AVPlaybackStatus>A Promise that is fulfilled with the AVPlaybackStatus of the playbackObject once the new status has been set successfully,
or rejects if setting the new status failed. See below for details on AVPlaybackStatus.
Extends: AV
On the playbackObject reference, the following API is provided.
Loads the media from source into memory and prepares it for playing. This must be called before calling setStatusAsync()
or any of the convenience set status methods. This method can only be called if the playbackObject is in an unloaded state.
Promise<AVPlaybackStatus>A Promise that is fulfilled with the AVPlaybackStatus of the playbackObject once it is loaded, or rejects if loading failed.
The Promise will also reject if the playbackObject was already loaded. See below for details on AVPlaybackStatus.
This is equivalent to playbackObject.setStatusAsync({ shouldPlay: false }).
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ shouldPlay: true }).
Playback may not start immediately after calling this function for reasons such as buffering. Make sure to update your UI based
on the isPlaying and isBuffering properties of the AVPlaybackStatus.
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ shouldPlay: true, positionMillis, seekMillisToleranceAfter: tolerances.seekMillisToleranceAfter, seekMillisToleranceBefore: tolerances.seekMillisToleranceBefore }).
Playback may not start immediately after calling this function for reasons such as buffering. Make sure to update your UI based
on the isPlaying and isBuffering properties of the AVPlaybackStatus.
Promise<AVPlaybackStatus>Replays the playback item. When using playFromPositionAsync(0) the item is seeked to the position at 0 ms.
On iOS this method uses internal implementation of the player and is able to play the item from the beginning immediately.
Promise<AVPlaybackStatus>A Promise that is fulfilled with the AVPlaybackStatus of the playbackObject once the new status has been set successfully,
or rejects if setting the new status failed.
This is equivalent to playbackObject.setStatusAsync({ isLooping }).
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ positionMillis }).
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ progressUpdateIntervalMillis }).
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ rate, shouldCorrectPitch, pitchCorrectionQuality }).
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ volume, audioPan }).
Note: audioPan is currently only supported on Android using androidImplementation: 'MediaPlayer'
Promise<AVPlaybackStatus>This is equivalent to playbackObject.setStatusAsync({ shouldPlay: false, positionMillis: 0 }).
Promise<AVPlaybackStatus>Unloads the media from memory. loadAsync() must be called again in order to be able to play the media.
This cleanup function will be automatically called in the
Videocomponent'scomponentWillUnmount.
Promise<AVPlaybackStatus>A Promise that is fulfilled with the AVPlaybackStatus of the playbackObject once it is unloaded, or rejects if unloading failed.
Types
Literal type: union
The following forms of source are supported:
- A dictionary of the form
AVPlaybackSourceObject. TheoverrideFileExtensionAndroidproperty may come in handy if the player receives an URL likeexample.com/playwhich redirects toexample.com/player.m3u8. Setting this property tom3u8would allow the Android player to properly infer the content type of the media and use proper media file reader. require('path/to/file')for a media file asset in the source code directory.- An
Assetobject for a media file asset.
The iOS developer documentation lists the audio and video formats supported on iOS.
There are two sets of audio and video formats supported on Android: formats supported by ExoPlayer
and formats supported by Android's MediaPlayer.
Expo uses ExoPlayer implementation by default. To use MediaPlayer, add androidImplementation: 'MediaPlayer' to the initial status of the AV object.
Acceptable values are: number | AVPlaybackSourceObject | Asset
Literal type: union
This is the structure returned from all playback API calls and describes the state of the playbackObject at that point in time.
It can take a form of AVPlaybackStatusSuccess or AVPlaybackStatusError based on the playbackObject load status.
Acceptable values are: AVPlaybackStatusError | AVPlaybackStatusSuccess
This is the structure passed to setStatusAsync() to modify the state of the playbackObject.
Enums
Check official Apple documentation for more information.
Permissions
Android
You must add the following permissions to your app.json inside the expo.android.permissions array.
iOS
The following usage description keys are used by this library: