A comprehensive React Native video player component with streaming, DRM, and Picture-in-Picture support
—
The main Video component provides a comprehensive interface for video playback with extensive configuration options for all supported platforms.
The primary React Native video player component implemented as a forwardRef.
/**
* Main video player component with comprehensive playback capabilities
* @param props - Video component props
* @param ref - Reference for imperative control methods
* @returns React video component
*/
declare const Video: React.ForwardRefExoticComponent<
ReactVideoProps & React.RefAttributes<VideoRef>
>;Usage Examples:
import React, { useRef } from "react";
import Video, { VideoRef } from "react-native-video";
// Basic video playback
<Video
source={{ uri: "https://example.com/video.mp4" }}
style={{ width: 300, height: 200 }}
controls={true}
/>
// With ref for imperative control
const videoRef = useRef<VideoRef>(null);
<Video
ref={videoRef}
source={{ uri: "https://example.com/video.mp4" }}
paused={false}
onLoad={() => videoRef.current?.seek(30)}
/>Complete props interface extending ReactVideoEvents and ViewProps.
/**
* Props interface for the Video component
* Extends ReactVideoEvents for event handling and ViewProps for styling
*/
interface ReactVideoProps extends ReactVideoEvents, ViewProps {
// Media Source
source?: ReactVideoSource;
// Basic Playback Control
paused?: boolean;
rate?: number;
volume?: number;
muted?: boolean;
repeat?: boolean;
// Display & Styling
style?: StyleProp<ViewStyle>;
resizeMode?: "none" | "contain" | "cover" | "stretch";
poster?: string | ReactVideoPoster;
posterResizeMode?: "contain" | "center" | "cover" | "none" | "repeat" | "stretch";
// UI Controls
controls?: boolean;
fullscreen?: boolean;
hideShutterView?: boolean;
shutterColor?: string;
// Audio Configuration
audioOutput?: "speaker" | "earpiece";
mixWithOthers?: "inherit" | "mix" | "duck";
ignoreSilentSwitch?: "inherit" | "ignore" | "obey";
// Advanced Playback
playInBackground?: boolean;
playWhenInactive?: boolean;
automaticallyWaitsToMinimizeStalling?: boolean;
preventsDisplaySleepDuringVideoPlayback?: boolean;
// Track Selection
selectedAudioTrack?: SelectedTrack;
selectedTextTrack?: SelectedTrack;
selectedVideoTrack?: SelectedVideoTrack;
subtitleStyle?: SubtitleStyle;
// Streaming & Buffering
bufferConfig?: BufferConfig;
bufferingStrategy?: "Default" | "DisableBuffering" | "DependingOnMemory";
reportBandwidth?: boolean;
maxBitRate?: number;
minLoadRetryCount?: number;
progressUpdateInterval?: number;
// Platform Features
allowsExternalPlayback?: boolean;
enterPictureInPictureOnLeave?: boolean;
showNotificationControls?: boolean;
disableDisconnectError?: boolean;
// Android Specific
viewType?: 0 | 1 | 2; // TEXTURE | SURFACE | SURFACE_SECURE
useTextureView?: boolean;
useSecureView?: boolean;
focusable?: boolean;
disableFocus?: boolean;
currentPlaybackTime?: number;
controlsStyles?: ControlsStyles;
// iOS Specific
fullscreenAutorotate?: boolean;
fullscreenOrientation?: "all" | "landscape" | "portrait";
chapters?: Chapters[];
filter?: string;
filterEnabled?: boolean;
preferredForwardBufferDuration?: number;
disableAudioSessionManagement?: boolean;
// Web Specific
renderLoader?: ReactNode | ((props: ReactVideoRenderLoaderProps) => ReactNode);
// Debug & Testing
debug?: DebugConfig;
testID?: string;
// Deprecated Props (included for compatibility)
drm?: Drm;
adTagUrl?: string;
adLanguage?: string;
bufferConfig?: BufferConfig;
contentStartTime?: number;
textTracks?: TextTracks;
localSourceEncryptionKeyScheme?: string;
}/**
* Video source configuration supporting various media types and features
*/
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;
}/**
* Poster image configuration
*/
interface ReactVideoPoster {
source?: { uri: string } | number;
style?: StyleProp<ImageStyle>;
resizeMode?: "contain" | "center" | "cover" | "none" | "repeat" | "stretch";
}
/**
* Subtitle styling options (Android)
*/
interface SubtitleStyle {
fontSize?: number;
paddingTop?: number;
paddingBottom?: number;
paddingLeft?: number;
paddingRight?: number;
opacity?: number;
subtitlesFollowVideo?: boolean;
}
/**
* Controls customization (Android)
*/
interface ControlsStyles {
hideSeekBar?: boolean;
hideDuration?: boolean;
hidePosition?: boolean;
hidePlayPause?: boolean;
hideForward?: boolean;
hideRewind?: boolean;
hideNext?: boolean;
hidePrevious?: boolean;
hideFullscreen?: boolean;
hideNavigationBarOnFullScreenMode?: boolean;
hideNotificationBarOnFullScreenMode?: boolean;
hideSettingButton?: boolean;
seekIncrementMS?: number;
liveLabel?: string;
}/**
* Audio and text track selection
*/
interface SelectedTrack {
type: "system" | "disabled" | "title" | "language" | "index";
value?: string | number;
}
/**
* Video quality track selection (Android)
*/
interface SelectedVideoTrack {
type: "auto" | "disabled" | "resolution" | "index";
value?: string | number;
}/**
* Buffering behavior configuration
*/
interface BufferConfig {
minBufferMs?: number;
maxBufferMs?: number;
bufferForPlaybackMs?: number;
bufferForPlaybackAfterRebufferMs?: number;
backBufferDurationMs?: number;
maxHeapAllocationPercent?: number;
minBackBufferMemoryReservePercent?: number;
minBufferMemoryReservePercent?: number;
initialBitrate?: number;
cacheSizeMB?: number;
live?: BufferConfigLive;
}
/**
* Live streaming buffer configuration
*/
interface BufferConfigLive {
maxPlaybackSpeed?: number;
minPlaybackSpeed?: number;
maxOffsetMs?: number;
minOffsetMs?: number;
targetOffsetMs?: number;
}/**
* Chapter information for iOS
*/
interface Chapters {
title: string;
startTime: number;
endTime: number;
uri?: string;
}
/**
* Debug configuration
*/
interface DebugConfig {
enable?: boolean;
thread?: boolean;
}Usage Examples:
// Advanced video configuration
<Video
source={{
uri: "https://example.com/video.m3u8",
headers: { "Authorization": "Bearer token" },
metadata: {
title: "Sample Video",
artist: "Video Creator"
}
}}
style={{ flex: 1 }}
controls={true}
resizeMode="contain"
paused={false}
rate={1.0}
volume={0.8}
muted={false}
repeat={false}
selectedAudioTrack={{ type: "language", value: "en" }}
selectedTextTrack={{ type: "language", value: "en" }}
bufferConfig={{
minBufferMs: 2000,
maxBufferMs: 10000,
bufferForPlaybackMs: 1000
}}
onLoad={(data) => console.log("Duration:", data.duration)}
onProgress={(data) => console.log("Progress:", data.currentTime)}
onError={(error) => console.error("Error:", error)}
/>
// iOS specific features
<Video
source={{ uri: "video.mp4" }}
fullscreenOrientation="landscape"
chapters={[
{ title: "Intro", startTime: 0, endTime: 30 },
{ title: "Main Content", startTime: 30, endTime: 300 }
]}
ignoreSilentSwitch="ignore"
/>
// Android specific features
<Video
source={{ uri: "video.mp4" }}
viewType={1} // SURFACE
useSecureView={true}
controlsStyles={{
hideSeekBar: false,
seekIncrementMS: 15000,
liveLabel: "LIVE"
}}
/>Install with Tessl CLI
npx tessl i tessl/npm-react-native-video