Play a video in React Native
Add adaptive-bitrate playback to a React Native (Expo) app in about five minutes using expo-video and a FastPix playback ID.
FastPix delivers video as HLS, an adaptive-bitrate format that adjusts quality to each device and network. In React Native, expo-video wraps the native players (AVPlayer on iOS, ExoPlayer on Android), both of which play HLS out of the box.
So playback comes down to one thing: pass a FastPix stream URL to expo-video. This guide builds a small, reusable player component that does exactly that.
How it works
- You have a FastPix playback ID from a video uploaded using Upload a video from a device or Upload a video from a URL.
- You build the HLS URL
https://stream.fastpix.com/{PLAYBACK_ID}.m3u8. useVideoPlayerloads that URL, andVideoViewrenders it with native controls.
What you’ll build
A VideoPlayer component that takes a playback ID as a prop and plays it full width with native controls, fullscreen, and Picture-in-Picture. You drop it into any screen with <VideoPlayer playbackId="..." />.
Before you begin
Make sure you have the following:
- A FastPix playback ID. To follow along, use the sample ID
7c8d5087-edf7-462f-a1b3-e2fbd30747fa, then swap in your own. - Node.js and the Expo tooling. You don’t need native build tools to test in Expo Go, but you do need a development build for Picture-in-Picture.
- A device or simulator: the iOS Simulator, an Android emulator, or a physical phone.
Each code block in this guide is a complete file. The bold filename above it tells you where the code goes. Create or replace that file with the code shown, then move on.
Create the app
If you don’t already have an app, create one with Expo:
Install expo-video
Using expo install rather than npm install picks the expo-video version that matches your Expo SDK.
Build the player
Keep the URL format in one place, so components only ever deal with playback IDs. Create a small helper:
src/constants/fastpix.ts
Now create the player. It takes the playback ID as a prop, sets up the player once, and renders it:
src/components/video-player.tsx
NOTE:
The setup callback passed touseVideoPlayerruns once when the player is created. Put initial configuration (loop, autoplay, muting) there rather than in the render body, which can run many times.
Render it from a screen. Keep the playback ID at the screen level so the player component stays reusable:
src/app/index.tsx
Run the app
Press i for the iOS Simulator or a for the Android emulator, or scan the QR code with Expo Go on your phone. The video loads and plays with native controls.
NOTE:
On Android, HTTPS streams like FastPix work with no extra setup. If you point the player at a plainhttp://URL during local testing, Android blocks it by default (cleartext traffic). Stick to thehttps://stream.fastpix.comURLs and you won’t hit this.
Customize playback
VideoView and the player expose the common controls directly, with small edits to the component above:
- Start muted: add
player.muted = true;inside theuseVideoPlayersetup callback, next toplayer.loop = loop;. - Loop by default: pass the prop when you render the component:
<VideoPlayer playbackId={PLAYBACK_ID} loop />. - Portrait (reels) layout: in the
videostyle at the bottom of the file, changeaspectRatio: 16 / 9toaspectRatio: 9 / 16.
Troubleshooting
The player area is black and nothing plays.
Check the playback ID and that the asset is ready. Open https://stream.fastpix.com/{PLAYBACK_ID}.m3u8 in a browser, or https://play.fastpix.com/?playbackId={PLAYBACK_ID}. If that doesn’t play, the ID is wrong or the media is still processing, which is not a React Native issue.
Unable to resolve "expo-video".
The package isn’t installed in this project. Run npx expo install expo-video, then restart the bundler with npx expo start -c to clear the Metro cache.
The video plays but there are no controls.
nativeControls is what draws the play, scrub, and fullscreen UI. Make sure it’s set on VideoView (it is in the component above).
Picture-in-Picture does nothing in Expo Go.
Picture-in-Picture needs the native configuration from a development build. Create one with npx expo run:ios or npx expo run:android (or EAS Build). It doesn’t work in Expo Go.
Frequently asked questions
Can I use expo-video in a bare React Native app, without Expo?
expo-video needs the expo package, so a bare React Native project has to add Expo modules first. See Expo’s install Expo modules guide. Apps created with create-expo-app already have everything.
Does this work in Expo Go, or do I need a development build?
Basic playback works in Expo Go. You only need a development build for advanced features such as Picture-in-Picture and background playback, covered in advanced playback in React Native.
Where do I get a FastPix playback ID?
Upload or import a video, then read the playback ID from the media’s Overview page in the dashboard or from the API response. See upload a video from a device or upload a video from a URL. To just try the guide, use the sample ID above.
What’s next
- React Native Uploads SDK and Node SDK.
- expo-video reference for the full player API.