Video

Plays a clip with an optional poster: tap to play inline, or full transport controls (the platform's own on iOS and Android, the kit's bar on the web), with boolean fit, autoplay, loop and muted props.
Give it a source (a { uri }, or a bundled asset from require), an optional poster shown until the clip's first frame is on screen, and the clip's aspectRatio (width over height, 16 / 9 by default): the frame fills its parent's width at that ratio and letterboxes the picture on black. Without controls it is an inline player: the whole picture is one play and pause control, a play emblem sits over the paused picture, and a spinner shows while the clip loads. With controls each platform shows transport its own way: iOS and Android hand the frame to their own player controls, and the web draws the kit's control bar under the picture, with play and pause, the elapsed time, a seek slider, the length, mute, and full screen.
autoplay starts a clip once it is ready unless the system asks to reduce motion; browsers autoplay only muted clips, and this site's own policy blocks autoplay, so the examples here play on tap. Name every clip with accessibilityLabel: its controls are announced as "Play", "Pause", "Seek" and "Mute" followed by that name. Playback runs through the optional expo-video peer; without it the frame keeps its size and poster in a labeled frame.
iOS
Android
Web
tsx
<Video source={{ uri: "/video-sample.mp4" }} poster={{ uri: "/video-sample.jpg" }} accessibilityLabel="Sample clip" />

Props

Prop
Description
source
required
VideoSource
The clip: a remote `{ uri }`, or a bundled asset from `require(...)`.
poster
ImageSourcePropType
A still shown until the clip's first frame is on screen: a remote `{ uri }` or a bundled asset.
contain
boolean
Fit: show the whole picture, letterboxed on black. The default (pick one).
cover
boolean
Fit: fill the frame, cropping the overflow (pick one).
stretch
boolean
Fit: fill the frame by distorting the aspect ratio (pick one).
autoplay
boolean
Start playing as soon as the clip is ready, unless the system asks to reduce motion. Browsers autoplay only muted clips, so pair it with `muted` on the web.
loop
boolean
Play again from the start at the end.
muted
boolean
Play without sound.
controls
boolean
Transport controls: the platform's own player controls on iOS and Android, the kit's control bar on the web.
aspectRatio
number
Width over height of the clip; the frame fills its parent's width at this ratio (default 16 / 9).
radius
VideoRadius
Corner radius from the kit's radius scale (pick one): none, sm, md, lg, xl, 2xl, 3xl, full.
accessibilityLabel
string
The clip's accessible name, used in the names of its controls (default "video").
onPlayingChange
(playing: boolean) => void
Called when playback starts or stops.
onEnd
() => void
Called when the clip plays to its end (each time round, when looping).
testID
string
E2E hook forwarded to the frame.
style
LayoutStyle
Composition within a parent only, never a restyle hook and never a width: the parent layout container provides the bounds.

Do & Don’t

Clips with sound

Don’t
Leave a clip with sound as an inline player; a tap can only play or pause it, so there is no way to seek, see its length, or mute it.
Do
0:00
0:00
Give a clip people watch with sound controls: they can seek, see how long it runs, and mute it.