Skip to main content

Basic example

Here’s a complete example to get you started with React Native Video. This example shows a simple video player with native controls:
App.tsx
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { useVideoPlayer, VideoView } from 'react-native-video';

export default function App() {
  const player = useVideoPlayer(
    'https://www.w3schools.com/html/mov_bbb.mp4',
    (player) => {
      player.play();
    }
  );

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  video: {
    width: '100%',
    aspectRatio: 16 / 9,
  },
});
The useVideoPlayer hook creates and manages a video player instance. The second parameter is a setup function that runs when the player is ready.

Understanding the code

Let’s break down the key components:
1

Import the components

Import useVideoPlayer and VideoView from react-native-video:
import { useVideoPlayer, VideoView } from 'react-native-video';
2

Create a player with useVideoPlayer

The useVideoPlayer hook creates a player instance with a video source:
const player = useVideoPlayer(
  'https://www.w3schools.com/html/mov_bbb.mp4',
  (player) => {
    player.play(); // Auto-play when ready
  }
);
  • First parameter: The video source (URL or local file)
  • Second parameter: Setup function called when the player loads
3

Render VideoView

The VideoView component displays the video:
<VideoView
  player={player}
  style={styles.video}
  controls
/>
  • player: The player instance from useVideoPlayer
  • style: Standard React Native style prop
  • controls: Show native playback controls

Playing local videos

You can play videos from your app’s assets using require():
const player = useVideoPlayer(
  require('./assets/video.mp4'),
  (player) => {
    player.play();
  }
);

Controlling playback

The player instance provides methods and properties to control playback:
const player = useVideoPlayer(videoSource);

// Play the video
player.play();

// Pause the video
player.pause();

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

Handling events

Use the useEvent hook to listen to player events:
import { useVideoPlayer, VideoView, useEvent } from 'react-native-video';

export default function App() {
  const player = useVideoPlayer(videoSource);

  useEvent(player, 'onLoad', (data) => {
    console.log('Video loaded:', data);
  });

  useEvent(player, 'onProgress', (data) => {
    console.log('Current time:', data.currentTime);
  });

  useEvent(player, 'onEnd', () => {
    console.log('Video ended');
  });

  useEvent(player, 'onError', (error) => {
    console.error('Video error:', error);
  });

  return <VideoView player={player} style={styles.video} />;
}
The useEvent hook automatically manages event subscriptions and cleans them up when the component unmounts.

Complete example with controls

Here’s a more complete example with custom controls:
import React, { useState } from 'react';
import { StyleSheet, View, Button, Text } from 'react-native';
import { useVideoPlayer, VideoView, useEvent } from 'react-native-video';

export default function App() {
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);

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

  useEvent(player, 'onProgress', (data) => {
    setCurrentTime(data.currentTime);
  });

  useEvent(player, 'onLoad', (data) => {
    setDuration(player.duration);
  });

  const formatTime = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  return (
    <View style={styles.container}>
      <VideoView
        player={player}
        style={styles.video}
        resizeMode="contain"
      />
      
      <View style={styles.controls}>
        <Text style={styles.time}>
          {formatTime(currentTime)} / {formatTime(duration)}
        </Text>
        
        <View style={styles.buttons}>
          <Button
            title="⏮️ -10s"
            onPress={() => player.seekBy(-10)}
          />
          <Button
            title={player.isPlaying ? '⏸️ Pause' : '▶️ Play'}
            onPress={() => player.isPlaying ? player.pause() : player.play()}
          />
          <Button
            title="⏭️ +10s"
            onPress={() => player.seekBy(10)}
          />
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  video: {
    width: '100%',
    aspectRatio: 16 / 9,
  },
  controls: {
    padding: 16,
  },
  time: {
    textAlign: 'center',
    fontSize: 16,
    marginBottom: 16,
  },
  buttons: {
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
});

Video configuration

For more advanced scenarios, pass a configuration object instead of a URL:
import type { VideoConfig } from 'react-native-video';

const videoConfig: VideoConfig = {
  uri: 'https://example.com/video.m3u8',
  headers: {
    'Authorization': 'Bearer token123',
  },
  externalSubtitles: [
    {
      uri: 'https://example.com/subtitles_en.vtt',
      label: 'English',
      language: 'en',
      type: 'vtt',
    },
  ],
};

const player = useVideoPlayer(videoConfig, (player) => {
  player.play();
});
Video configuration supports headers, DRM parameters, buffer config, metadata, and external subtitles. See the VideoConfig API reference for all options.

Common customizations

Resize modes

Control how the video fits within the view:
<VideoView
  player={player}
  style={styles.video}
  resizeMode="contain" // 'contain' | 'cover' | 'stretch' | 'none'
/>
  • contain: Fit video within view, maintaining aspect ratio (may show letterboxing)
  • cover: Fill entire view, maintaining aspect ratio (may crop)
  • stretch: Fill entire view, ignoring aspect ratio
  • none: Use video’s native size

Background playback

Enable playback when the app is in the background:
const player = useVideoPlayer(videoSource, (player) => {
  player.playInBackground = true;
  player.play();
});

Picture in Picture

Enable Picture in Picture mode:
import { useRef } from 'react';
import type { VideoViewRef } from 'react-native-video';

const videoRef = useRef<VideoViewRef>(null);

// Enable PiP button in controls
<VideoView
  ref={videoRef}
  player={player}
  style={styles.video}
  pictureInPicture
  controls
/>

// Or programmatically enter PiP
videoRef.current?.enterPictureInPicture();

Next steps

VideoPlayer API

Learn about all player properties and methods

VideoView API

Explore VideoView props and customization options

Events

Handle player events and track playback state

Streaming

Play HLS and DASH streams