Skip to main content

Basic Video Playback

This guide covers the fundamentals of playing videos in React Native Video, from simple playback to controlling video properties.

Quick Start

The simplest way to play a video is using the useVideoPlayer hook with a video URL:
import { VideoView, useVideoPlayer } from 'react-native-video';
import { StyleSheet, View } from 'react-native';

export function BasicPlayer() {
  const player = useVideoPlayer('https://www.w3schools.com/html/mov_bbb.mp4');

  return (
    <View style={styles.container}>
      <VideoView player={player} style={styles.video} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  video: {
    width: '100%',
    height: 300,
  },
});

Video Sources

Remote Videos

Play videos from a URL:
const player = useVideoPlayer('https://example.com/video.mp4');

Local Videos

Play videos bundled with your app:
const player = useVideoPlayer(require('./assets/video.mp4'));

Advanced Configuration

For more control, pass a configuration object:
const player = useVideoPlayer({
  uri: 'https://example.com/video.mp4',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN',
  },
  metadata: {
    title: 'My Video',
    subtitle: 'Episode 1',
    artist: 'Creator Name',
    imageUri: 'https://example.com/thumbnail.jpg',
  },
});

Controlling Playback

The VideoPlayer instance provides methods and properties to control playback:

Basic Controls

import { VideoView, useVideoPlayer } from 'react-native-video';
import { Button, View } from 'react-native';

export function PlayerWithControls() {
  const player = useVideoPlayer('https://example.com/video.mp4');

  return (
    <View>
      <VideoView player={player} style={{ width: '100%', height: 300 }} />
      
      <View style={{ flexDirection: 'row', gap: 10, padding: 10 }}>
        <Button title="Play" onPress={() => player.play()} />
        <Button title="Pause" onPress={() => player.pause()} />
      </View>
    </View>
  );
}

Seeking

Seek to a specific time or by a relative amount:
// Seek to 30 seconds
player.seekTo(30);

// Skip forward 10 seconds
player.seekBy(10);

// Skip backward 10 seconds
player.seekBy(-10);

Setting Current Time

You can also set the current time directly:
// Jump to the middle of the video
player.currentTime = player.duration / 2;

Player Properties

Volume and Mute

// Set volume (0.0 to 1.0)
player.volume = 0.5;

// Mute/unmute
player.muted = true;
player.muted = false;

Playback Rate

Control playback speed:
// Normal speed
player.rate = 1.0;

// Half speed
player.rate = 0.5;

// Double speed
player.rate = 2.0;

Looping

// Enable looping
player.loop = true;

// Disable looping
player.loop = false;

Reading Properties

Access read-only properties to get video information:
// Get current playback time (seconds)
const currentTime = player.currentTime;

// Get total duration (seconds)
const duration = player.duration;

// Check if playing
const isPlaying = player.isPlaying;

// Get player status
const status = player.status; // 'playing', 'paused', 'buffering', etc.

Displaying Controls

Enable native playback controls:
<VideoView 
  player={player} 
  controls={true}
  style={{ width: '100%', height: 300 }}
/>

Resize Modes

Control how the video fits within the view:
<VideoView
  player={player}
  resizeMode="contain" // Options: 'contain', 'cover', 'stretch', 'none'
  style={{ width: '100%', height: 300 }}
/>
  • contain: Scale uniformly to fit entirely within the view (may show black bars)
  • cover: Scale uniformly to fill the entire view (may crop)
  • stretch: Scale to fill without maintaining aspect ratio
  • none: Do not resize

Complete Example

Here’s a full example with controls and state:
import { VideoView, useVideoPlayer } from 'react-native-video';
import { useState } from 'react';
import { View, Button, Text, StyleSheet } from 'react-native';

export function FullPlayer() {
  const player = useVideoPlayer('https://www.w3schools.com/html/mov_bbb.mp4', (player) => {
    player.loop = true;
    player.volume = 0.8;
  });

  const [isMuted, setIsMuted] = useState(false);

  const toggleMute = () => {
    player.muted = !isMuted;
    setIsMuted(!isMuted);
  };

  const skip10Seconds = () => {
    player.seekBy(10);
  };

  return (
    <View style={styles.container}>
      <VideoView 
        player={player} 
        style={styles.video}
        resizeMode="contain"
      />
      
      <View style={styles.controls}>
        <Button 
          title={player.isPlaying ? 'Pause' : 'Play'} 
          onPress={() => player.isPlaying ? player.pause() : player.play()} 
        />
        <Button title="Skip +10s" onPress={skip10Seconds} />
        <Button title={isMuted ? 'Unmute' : 'Mute'} onPress={toggleMute} />
      </View>
      
      <Text style={styles.info}>
        {Math.floor(player.currentTime)}s / {Math.floor(player.duration)}s
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000',
  },
  video: {
    width: '100%',
    height: 300,
  },
  controls: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    padding: 20,
    backgroundColor: '#fff',
  },
  info: {
    padding: 10,
    color: '#fff',
    textAlign: 'center',
  },
});

Background Playback

Enable playback when the app is in the background:
const player = useVideoPlayer('https://example.com/video.mp4', (player) => {
  player.playInBackground = true;
});
On iOS, you need to configure background modes in your app’s capabilities. On Android, ensure you have the appropriate permissions.

Platform-Specific Behavior

iOS Silent Switch

Control audio behavior when the hardware mute switch is on:
player.ignoreSilentSwitchMode = 'obey'; // or 'ignore'
The ignoreSilentSwitchMode property only works on iOS and has no effect on other platforms.

Audio Mixing

Control how the player’s audio mixes with other audio sources:
player.mixAudioMode = 'mix'; // Play alongside other audio
player.mixAudioMode = 'duck'; // Lower other audio
player.mixAudioMode = 'inherit'; // Use default behavior

Changing Video Source

Replace the current video source without creating a new player:
await player.replaceSourceAsync('https://example.com/new-video.mp4');

// Or with configuration
await player.replaceSourceAsync({
  uri: 'https://example.com/new-video.mp4',
  headers: { 'Authorization': 'Bearer TOKEN' },
});

// Clear the source
await player.replaceSourceAsync(null);

Next Steps

Build docs developers (and LLMs) love