If you searched for "expo-av" you'll hit a wall: the Audio and Video APIs in expo-av are deprecated and removed in SDK 55. The modern replacements are expo-video and expo-audio — smaller, hook-based, and much easier to use. This guide shows how to play video and audio the right way today.
Install
npx expo install expo-video expo-audio
Play a video
Create a player with useVideoPlayer and render it with VideoView:
import { useVideoPlayer, VideoView } from "expo-video"
import { View } from "react-native"
const source =
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
export default function Player() {
const player = useVideoPlayer(source, (player) => {
player.loop = true
player.play()
})
return (
<View style={{ flex: 1 }}>
<VideoView
style={{ width: "100%", height: 240 }}
player={player}
allowsFullscreen
allowsPictureInPicture
/>
</View>
)
}
The second argument to useVideoPlayer is a setup callback — a great place to set loop, muted, or call play().
Control playback
The player object is imperative — call methods directly:
player.play()
player.pause()
player.replace(newSource) // switch to a different video
player.currentTime = 0 // seek to the start
player.muted = true
React to player state
Use the useEvent hook from expo to re-render when playback status changes:
import { useEvent } from "expo"
const { isPlaying } = useEvent(player, "playingChange", {
isPlaying: player.playing,
})
// <Button title={isPlaying ? "Pause" : "Play"} onPress={() => (isPlaying ? player.pause() : player.play())} />
Play audio
expo-audio mirrors the same pattern with useAudioPlayer:
import { useAudioPlayer } from "expo-audio"
import { Button } from "react-native"
export default function Ping() {
const player = useAudioPlayer(require("./assets/ping.mp3"))
return <Button title="Play sound" onPress={() => player.play()} />
}
You can also stream remote audio by passing a URL string instead of a require.
Record audio
expo-audio also handles recording via useAudioRecorder — request microphone permission, record(), then stop() to get a file URI you can upload or play back.
Gotchas
- Migrating from expo-av? Replace
Video/Audio.SoundwithuseVideoPlayer/useAudioPlayer. There's no<Video>with asourceprop anymore — the player is separate from the view. - Add the
expo-video/expo-audioconfig plugins in app.json for background playback and mic permissions. - Set the audio session mode if you need sound to play in silent mode or continue in the background.
Next steps
Capturing media instead of playing it? See the expo-camera tutorial and expo-image-picker guide. See all ten in the top Expo SDK modules roundup.