Audio.Sound
objects and Video
components share a unified imperative API for media playback.Video
, all of these operations are also available via props on the component, but we recommend using this imperative playback API for most applications where finer control over the state of the video playback is needed.Audio.Sound
and Video
.Android Device | Android Emulator | iOS Device | iOS Simulator | Web |
---|---|---|---|---|
expo install expo-av
If you're installing this in a bare React Native app, you should also follow these additional installation instructions.
import { Audio, Video } from 'expo-av';
playbackObject
s. Here is an example of obtaining access to the reference for both sound and video:const playbackObject = new Audio.Sound(); // OR const { sound: playbackObject } = await Audio.Sound.createAsync( { uri: 'http://foo/bar.mp3' }, { shouldPlay: true } ); ...
Audio.Sound.createAsync()
.... _handleVideoRef = component => { const playbackObject = component; ... } ... render() { return ( ... <Video ref={this._handleVideoRef} ... /> ... ) } ...
playbackObject
reference, the following API is provided:playbackObject.loadAsync(source, initialStatus = {}, downloadFirst = true)
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.{ uri: string, headers?: { [string]: string }, overrideFileExtensionAndroid?: string }
with a network URL pointing to a media file on the web, an optional headers object passed in a network request to the uri
and an optional Android-specific overrideFileExtensionAndroid
string overriding extension inferred from the URL.overrideFileExtensionAndroid
property may come in handy if the player receives an URL like example.com/play
which redirects to example.com/player.m3u8
. Setting this property to m3u8
would 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.Asset
object for a media file asset.MediaPlayer
, add androidImplementation: 'MediaPlayer'
to the initial status of the AV object.AVPlaybackStatusToSet
of the playbackObject
, whose values will override the default initial playback status. This value defaults to {}
if no parameter is passed. See below for details on AVPlaybackStatusToSet
and the default initial playback status.true
. Note that at the moment, this will only work for source
s of the form require('path/to/file')
or Asset
objects.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
.playbackObject.unloadAsync()
loadAsync()
must be called again in order to be able to play the media.Promise
that is fulfilled with the AVPlaybackStatus
of the playbackObject
once it is unloaded, or rejects if unloading failed. See below for details on AVPlaybackStatus
.playbackObject.getStatusAsync()
AVPlaybackStatus
of the playbackObject
.Promise
that is fulfilled with the AVPlaybackStatus
of the playbackObject
. See below for details on AVPlaybackStatus
.playbackObject.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate)
AVPlaybackStatus
of the playbackObject
. See below for details on AVPlaybackStatus
and an example use case of this function.onPlaybackStatusUpdate
will be called whenever a call to the API for this playbackObject
completes (such as setStatusAsync()
, getStatusAsync()
, or unloadAsync()
), and will also be called at regular intervals while the media is in the loaded state. Set progressUpdateIntervalMillis
via setStatusAsync()
or setProgressUpdateIntervalAsync()
to modify the interval with which onPlaybackStatusUpdate
is called while loaded.AVPlaybackStatus
(a dictionary, described below).playbackObject.replayAsync(statusToSet)
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.AVPlaybackStatusToSet
of the playbackObject
, whose values will override the current playback status. See below for details on AVPlaybackStatusToSet
. positionMillis
and shouldPlay
properties will be overriden with respectively 0
and true
.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
.playbackObject.setStatusAsync(statusToSet)
AVPlaybackStatusToSet
on the playbackObject
. This method can only be called if the media has been loaded.AVPlaybackStatusToSet
of the playbackObject
, whose values will override the current playback status. See below for details on AVPlaybackStatusToSet
.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
.setStatusAsync()
are also provided. Each has the same return value as setStatusAsync()
.playbackObject.playAsync()
playbackObject.setStatusAsync({ shouldPlay: true })
.isPlaying
and isBuffering
properties of the AVPlaybackStatus
(described below).playbackObject.playFromPositionAsync(millis)
playbackObject.setStatusAsync({ shouldPlay: true, positionMillis: millis })
.isPlaying
and isBuffering
properties of the AVPlaybackStatus
(described below).playbackObject.playFromPositionAsync(millis, { toleranceMillisBefore, toleranceMillisAfter })
playbackObject.setStatusAsync({ shouldPlay: true, positionMillis: millis, seekMillisToleranceBefore: toleranceMillisBefore, seekMillisToleranceAfter: toleranceMillisAfter })
. The tolerances are used only on iOS (more details).isPlaying
and isBuffering
properties of the AVPlaybackStatus
(described below).playbackObject.pauseAsync()
playbackObject.setStatusAsync({ shouldPlay: false })
.playbackObject.stopAsync()
playbackObject.setStatusAsync({ shouldPlay: false, positionMillis: 0 })
.playbackObject.setPositionAsync(millis)
playbackObject.setStatusAsync({ positionMillis: millis })
.playbackObject.setPositionAsync(millis, { toleranceMillisBefore, toleranceMillisAfter })
playbackObject.setStatusAsync({ positionMillis: millis, seekMillisToleranceBefore: toleranceMillisBefore, seekMillisToleranceAfter: toleranceMillisAfter })
. The tolerances are used only on iOS (more details).playbackObject.setRateAsync(value, shouldCorrectPitch, pitchCorrectionQuality)
playbackObject.setStatusAsync({ rate: value, shouldCorrectPitch: shouldCorrectPitch, pitchCorrectionQuality: pitchCorrectionQuality })
.0.0
and 32.0
. Only available on Android API version 23 and later and iOS.true
, the pitch of the audio will be corrected (so a rate different than 1.0
will timestretch the audio).Audio.PitchCorrectionQuality.Low
. Available values:Low
- equivalent to AVAudioTimePitchAlgorithmLowQualityZeroLatency
Medium
- equivalent to AVAudioTimePitchAlgorithmTimeDomain
High
- equivalent to AVAudioTimePitchAlgorithmSpectral
playbackObject.setVolumeAsync(value)
playbackObject.setStatusAsync({ volume: value })
.0.0
(silence) and 1.0
(maximum volume).playbackObject.setIsMutedAsync(value)
playbackObject.setStatusAsync({ isMuted: value })
.playbackObject.setIsLoopingAsync(value)
playbackObject.setStatusAsync({ isLooping: value })
.false
) or loop indefinitely (true
).playbackObject.setProgressUpdateIntervalAsync(millis)
playbackObject.setStatusAsync({ progressUpdateIntervalMillis: millis })
.onPlaybackStatusUpdate
. See setOnPlaybackStatusUpdate()
for details.playbackObject
.AVPlaybackStatus
playbackObject
at that point in time. It is a dictionary with the following key-value pairs.playbackObject
is not loaded, it will contain the following key-value pairs:isLoaded
: a boolean set to false
.error
: a string only present if the playbackObject
just encountered a fatal error and forced unload.isLoaded
: a boolean set to true
.uri
: the location of the media source.progressUpdateIntervalMillis
: the minimum interval in milliseconds between calls of onPlaybackStatusUpdate
. See setOnPlaybackStatusUpdate()
for details.durationMillis
: the duration of the media in milliseconds. This is only present if the media has a duration (note that in some cases, a media file's duration is readable on Android, but not on iOS).positionMillis
: the current position of playback in milliseconds.playableDurationMillis
: the position until which the media has been buffered into memory. Like durationMillis
, this is only present in some cases.shouldPlay
: a boolean describing if the media is supposed to play.isPlaying
: a boolean describing if the media is currently playing.isBuffering
: a boolean describing if the media is currently buffering.rate
: the current rate of the media.shouldCorrectPitch
: a boolean describing if we are correcting the pitch for a changed rate.pitchCorrectionQuality
: iOS time pitch algorithm setting. See setRateAsync
for details.volume
: the current volume of the audio for this media.isMuted
: a boolean describing if the audio of this media is currently muted.isLooping
: a boolean describing if the media is currently looping.didJustFinish
: a boolean describing if the media just played to completion at the time that this status was received. When the media plays to completion, the function passed in setOnPlaybackStatusUpdate()
is called exactly once with didJustFinish
set to true
. didJustFinish
is never true
in any other case.AVPlaybackStatusToSet
setStatusAsync()
to modify the state of the playbackObject
. It is a dictionary with the following key-value pairs, all of which are optional.progressUpdateIntervalMillis
: the new minimum interval in milliseconds between calls of onPlaybackStatusUpdate
. See setOnPlaybackStatusUpdate()
for details.positionMillis
: the desired position of playback in milliseconds.seekMillisToleranceBefore
: the tolerance in milliseconds with which seek will be applied to the player. [iOS only, details]seekMillisToleranceAfter
: the tolerance in milliseconds with which seek will be applied to the player. [iOS only, details]shouldPlay
: a boolean describing if the media is supposed to play. Playback may not start immediately after setting this value for reasons such as buffering. Make sure to update your UI based on the isPlaying
and isBuffering
properties of the AVPlaybackStatus
.rate
: the desired playback rate of the media. This value must be between 0.0
and 32.0
. Only available on Android API version 23 and later and iOS.shouldCorrectPitch
: a boolean describing if we should correct the pitch for a changed rate. If set to true
, the pitch of the audio will be corrected (so a rate different than 1.0
will timestretch the audio).pitchCorrectionQuality
: iOS time pitch algorithm setting. Values: Audio.PitchCorrectionQuality.Low
, Audio.PitchCorrectionQuality.Medium
, or Audio.PitchCorrectionQuality.High
.volume
: the desired volume of the audio for this media. This value must be between 0.0
(silence) and 1.0
(maximum volume).isMuted
: a boolean describing if the audio of this media should be muted.isLooping
: a boolean describing if the media should play once (false
) or loop indefinitely (true
).androidImplementation
: underlying implementation to use (when set to MediaPlayer
it uses Android's MediaPlayer, uses ExoPlayer otherwise). You may need to use this property if you're trying to play an item unsupported by ExoPlayer (formats supported by ExoPlayer, formats supported by Android's MediaPlayer). Note that setting this property takes effect only when the AV object is just being created (toggling its value later will do nothing). [Android only]rate
different than 1.0
is currently only available on Android API version 23 and later and iOS.volume
and isMuted
only affect the audio of this playbackObject
and do NOT affect the system volume.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, }
initialStatus
in loadAsync()
or Audio.Sound.createAsync()
.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)._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? } ... // etc } }; ... // Load the playbackObject and obtain the reference. playbackObject.setOnPlaybackStatusUpdate(this._onPlaybackStatusUpdate); ...
const N = 20; ... _onPlaybackStatusUpdate = (playbackStatus) => { if (playbackStatus.didJustFinish) { if (this.state.numberOfLoops == N - 1) { playbackObject.setIsLooping(false); } this.setState({ numberOfLoops: this.state.numberOfLoops + 1 }); } }; ... this.setState({ numberOfLoops: 0 }); ... // Load the playbackObject and obtain the reference. playbackObject.setOnPlaybackStatusUpdate(this._onPlaybackStatusUpdate); playbackObject.setIsLooping(true); ...