Setting the file. One moment.
Subchapter 22.2
references/expo-av-to-video.mdMarkdown4 KBView on GitHub
// Before
import { Video, ResizeMode } from 'expo-av';
// After
import { useVideoPlayer, VideoView, VideoSource } from 'expo-video';
import { useEvent, useEventListener } from 'expo';const videoRef = useRef<Video>(null);
const [status, setStatus] = useState({});
<Video
ref={videoRef}
source={{ uri: 'https://example.com/video.mp4' }}
style={{ width: 350, height: 200 }}
resizeMode={ResizeMode.CONTAIN}
isLooping
onPlaybackStatusUpdate={setStatus}
/>
// Control
videoRef.current?.playAsync();
videoRef.current?.pauseAsync();const player = useVideoPlayer('https://example.com/video.mp4', player => {
player.loop = true;
});
const { isPlaying } = useEvent(player, 'playingChange', { isPlaying: player.playing });
<VideoView
player={player}
style={{ width: 350, height: 200 }}
contentFit="contain"
/>
// Control
player.play();
player.pause();<Video
onPlaybackStatusUpdate={status => {
if (status.isLoaded) {
console.log(status.positionMillis, status.durationMillis, status.isPlaying);
if (status.didJustFinish) console.log('finished');
}
}}
/>// Reactive state
const { isPlaying } = useEvent(player, 'playingChange', { isPlaying: player.playing });
// Side effects
useEventListener(player, 'playToEnd', () => console.log('finished'));
// Direct access
console.log(player.currentTime, player.duration, player.playing);<Video source={require('./video.mp4')} />const player = useVideoPlayer({ assetId: require('./video.mp4') });<VideoView
player={player}
allowsFullscreen
allowsPictureInPicture
onFullscreenEnter={() => {}}
onFullscreenExit={() => {}}
/>For PiP and background playback, add to app.json:
{
"expo": {
"plugins": [
["expo-video", { "supportsBackgroundPlayback": true, "supportsPictureInPicture": true }]
]
}
}| expo-av | expo-video |
|---|---|
<Video> | <VideoView> |
ref={videoRef} | player={useVideoPlayer()} |
source={{ uri }} | Pass to useVideoPlayer(uri) |
resizeMode={ResizeMode.CONTAIN} | contentFit="contain" |
isLooping | player.loop = true |
shouldPlay | player.play() in setup |
isMuted | player.muted = true |
useNativeControls | nativeControls={true} |
onPlaybackStatusUpdate | useEvent / useEventListener |
videoRef.current.playAsync() | player.play() |
videoRef.current.pauseAsync() | player.pause() |
videoRef.current.replayAsync() | player.replay() |
videoRef.current.setPositionAsync(ms) | player.currentTime = seconds |
status.positionMillis | player.currentTime (seconds) |
status.durationMillis | player.duration (seconds) |
status.didJustFinish | useEventListener(player, 'playToEnd') |
useEvent/useEventListener from expo instead of callback propsuseCaching: true in VideoSource for persistent offline cachingplayer.currentTime in the useVideoPlayer setup callback may not work on Android—set it after mount insteadplayer.replace(newSource) to change videos without recreating the player