A comprehensive React Native video player component with streaming, DRM, and Picture-in-Picture support
—
The VideoRef interface provides imperative control methods for programmatic video manipulation including playback control, seeking, fullscreen management, and Picture-in-Picture functionality.
Reference interface providing imperative control methods for the Video component.
/**
* Reference interface for imperative video control
* Access through React ref on Video component
*/
interface VideoRef {
seek: (time: number, tolerance?: number) => void;
resume: () => void;
pause: () => void;
setVolume: (volume: number) => void;
presentFullscreenPlayer: () => void;
dismissFullscreenPlayer: () => void;
setFullScreen: (fullScreen: boolean) => void;
enterPictureInPicture: () => void;
exitPictureInPicture: () => void;
save: (options: object) => Promise<VideoSaveData> | void;
getCurrentPosition: () => Promise<number>;
setSource: (source?: ReactVideoSource) => void;
restoreUserInterfaceForPictureInPictureStopCompleted: (restore: boolean) => void;
nativeHtmlVideoRef?: RefObject<HTMLVideoElement | null>; // Web only
}Usage Examples:
import React, { useRef, useEffect } from "react";
import Video, { VideoRef } from "react-native-video";
function VideoPlayer() {
const videoRef = useRef<VideoRef>(null);
useEffect(() => {
// Seek to 30 seconds after component mounts
setTimeout(() => {
videoRef.current?.seek(30);
}, 1000);
}, []);
const handlePlayPause = () => {
// Toggle play/pause state
if (paused) {
videoRef.current?.resume();
} else {
videoRef.current?.pause();
}
};
return (
<Video
ref={videoRef}
source={{ uri: "https://example.com/video.mp4" }}
// ... other props
/>
);
}Core playback control functionality.
/**
* Seek to a specific time position in the video
* @param time - Target time in seconds
* @param tolerance - Seek tolerance in seconds (optional)
*/
seek: (time: number, tolerance?: number) => void;
/**
* Resume video playback
*/
resume: () => void;
/**
* Pause video playback
*/
pause: () => void;
/**
* Set audio volume
* @param volume - Volume level between 0.0 and 1.0
*/
setVolume: (volume: number) => void;Usage Examples:
const videoRef = useRef<VideoRef>(null);
// Seek with precision
videoRef.current?.seek(120.5); // Seek to 2 minutes 30 seconds
videoRef.current?.seek(60, 2); // Seek to 1 minute with 2 second tolerance
// Playback control
videoRef.current?.pause();
videoRef.current?.resume();
// Volume control
videoRef.current?.setVolume(0.5); // 50% volume
videoRef.current?.setVolume(0.0); // Mute
videoRef.current?.setVolume(1.0); // Full volumeMethods for controlling fullscreen presentation.
/**
* Present video in fullscreen mode
*/
presentFullscreenPlayer: () => void;
/**
* Dismiss fullscreen presentation
*/
dismissFullscreenPlayer: () => void;
/**
* Set fullscreen state programmatically
* @param fullScreen - True to enter fullscreen, false to exit
*/
setFullScreen: (fullScreen: boolean) => void;Usage Examples:
const videoRef = useRef<VideoRef>(null);
// Enter fullscreen
videoRef.current?.presentFullscreenPlayer();
// Exit fullscreen
videoRef.current?.dismissFullscreenPlayer();
// Toggle fullscreen
const toggleFullscreen = (isFullscreen: boolean) => {
videoRef.current?.setFullScreen(!isFullscreen);
};Methods for managing Picture-in-Picture mode (iOS and Android).
/**
* Enter Picture-in-Picture mode
* Platform: iOS, Android
*/
enterPictureInPicture: () => void;
/**
* Exit Picture-in-Picture mode
* Platform: iOS, Android
*/
exitPictureInPicture: () => void;
/**
* Complete Picture-in-Picture restoration
* @param restore - Whether restoration was successful
* Platform: iOS
*/
restoreUserInterfaceForPictureInPictureStopCompleted: (restore: boolean) => void;Usage Examples:
const videoRef = useRef<VideoRef>(null);
// Enter PiP mode
const enterPiP = async () => {
try {
videoRef.current?.enterPictureInPicture();
} catch (error) {
console.log("PiP not available");
}
};
// Exit PiP mode
const exitPiP = () => {
videoRef.current?.exitPictureInPicture();
};
// Handle PiP restoration (iOS)
const handlePiPRestore = (restored: boolean) => {
videoRef.current?.restoreUserInterfaceForPictureInPictureStopCompleted(restored);
};Methods for dynamically changing video source.
/**
* Set a new video source
* @param source - New video source configuration or undefined to clear
*/
setSource: (source?: ReactVideoSource) => void;Usage Examples:
const videoRef = useRef<VideoRef>(null);
// Change video source
const changeVideo = () => {
videoRef.current?.setSource({
uri: "https://example.com/new-video.mp4",
headers: { "Authorization": "Bearer new-token" }
});
};
// Clear video source
const clearVideo = () => {
videoRef.current?.setSource(undefined);
};Methods for getting video information and saving content.
/**
* Get current playback position
* @returns Promise resolving to current time in seconds
*/
getCurrentPosition: () => Promise<number>;
/**
* Save video to device (iOS only)
* @param options - Save options
* @returns Promise resolving to save data or void on other platforms
*/
save: (options: object) => Promise<VideoSaveData> | void;Usage Examples:
const videoRef = useRef<VideoRef>(null);
// Get current position
const getCurrentTime = async () => {
try {
const position = await videoRef.current?.getCurrentPosition();
console.log("Current position:", position);
} catch (error) {
console.error("Error getting position:", error);
}
};
// Save video (iOS only)
const saveVideo = async () => {
try {
if (Platform.OS === 'ios') {
const result = await videoRef.current?.save({});
console.log("Video saved:", result?.uri);
}
} catch (error) {
console.error("Error saving video:", error);
}
};Web platform specific reference access.
/**
* Native HTML video element reference (Web only)
* Access to underlying HTMLVideoElement for web-specific functionality
*/
nativeHtmlVideoRef?: RefObject<HTMLVideoElement | null>;Usage Examples:
const videoRef = useRef<VideoRef>(null);
// Access HTML video element on web
const getWebVideoElement = () => {
if (Platform.OS === 'web') {
const htmlVideo = videoRef.current?.nativeHtmlVideoRef?.current;
if (htmlVideo) {
// Direct access to HTML video API
htmlVideo.playbackRate = 1.5;
htmlVideo.addEventListener('timeupdate', handleTimeUpdate);
}
}
};/**
* Video save result data (iOS only)
*/
interface VideoSaveData {
uri: string;
}
/**
* Video source configuration for setSource method
*/
interface ReactVideoSource {
uri?: string | NodeRequire;
headers?: Record<string, string>;
drm?: Drm;
textTracks?: TextTracks;
startPosition?: number;
cropStart?: number;
cropEnd?: number;
contentStartTime?: number;
metadata?: VideoMetadata;
ad?: AdConfig;
cmcd?: boolean | CmcdConfiguration;
bufferConfig?: BufferConfig;
minLoadRetryCount?: number;
textTracksAllowChunklessPreparation?: boolean;
}Install with Tessl CLI
npx tessl i tessl/npm-react-native-video