A comprehensive React Native video player component with streaming, DRM, and Picture-in-Picture support
npx @tessl/cli install tessl/npm-react-native-video@6.16.0React Native Video is a comprehensive video player component that provides native video playback capabilities across iOS, Android, Windows, and Web platforms. It offers advanced streaming features including HLS, DASH, and SmoothStreaming protocols, integrated DRM support, Picture-in-Picture functionality, and professional-grade video controls with extensive customization options.
npm install react-native-videoimport Video, { VideoRef } from "react-native-video";For specific types:
import type {
ReactVideoProps,
ReactVideoSource,
OnLoadData,
DRMType
} from "react-native-video";CommonJS:
const Video = require("react-native-video").default;import React, { useRef } from "react";
import { View } from "react-native";
import Video, { VideoRef } from "react-native-video";
export default function VideoPlayer() {
const videoRef = useRef<VideoRef>(null);
return (
<View style={{ flex: 1 }}>
<Video
ref={videoRef}
source={{
uri: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
}}
style={{ width: "100%", height: 200 }}
controls={true}
resizeMode="contain"
onLoad={(data) => {
console.log("Video loaded:", data.duration);
}}
onError={(error) => {
console.error("Video error:", error);
}}
/>
</View>
);
}React Native Video is built around several key components:
The main Video component with comprehensive props for all video functionality including playback control, styling, audio configuration, and platform-specific features.
declare const Video: React.ForwardRefExoticComponent<
ReactVideoProps & React.RefAttributes<VideoRef>
>;
interface ReactVideoProps extends ReactVideoEvents, ViewProps {
source?: ReactVideoSource;
style?: StyleProp<ViewStyle>;
paused?: boolean;
rate?: number;
volume?: number;
muted?: boolean;
controls?: boolean;
resizeMode?: "none" | "contain" | "cover" | "stretch";
}Imperative API for programmatic video control including playback, seeking, fullscreen, and Picture-in-Picture functionality.
interface VideoRef {
seek: (time: number, tolerance?: number) => void;
resume: () => void;
pause: () => void;
setVolume: (volume: number) => void;
presentFullscreenPlayer: () => void;
dismissFullscreenPlayer: () => void;
enterPictureInPicture: () => void;
exitPictureInPicture: () => void;
}Comprehensive video source configuration supporting local files, network streams, DRM-protected content, and advanced features like text tracks and metadata.
interface ReactVideoSource {
uri?: string | NodeRequire;
headers?: Record<string, string>;
drm?: Drm;
textTracks?: TextTracks;
startPosition?: number;
metadata?: VideoMetadata;
}
interface Drm {
type?: "widevine" | "playready" | "clearkey" | "fairplay";
licenseServer?: string;
headers?: Record<string, string>;
getLicense?: (spcBase64: string, contentId: string, licenseUrl: string, loadedLicenseUrl: string) => string | Promise<string>;
}Comprehensive event system covering playback events, state changes, track information, buffering, and error handling.
interface ReactVideoEvents {
onLoad?: (e: OnLoadData) => void;
onProgress?: (e: OnProgressData) => void;
onError?: (e: OnVideoErrorData) => void;
onEnd?: () => void;
onBuffer?: (e: OnBufferData) => void;
onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void;
}
interface OnLoadData {
currentTime: number;
duration: number;
naturalSize: { width: number; height: number; orientation: "landscape" | "portrait" };
audioTracks: AudioTrack[];
textTracks: TextTrack[];
videoTracks: VideoTrack[];
}Android decoder utilities and platform-specific functionality including codec support detection and Widevine security level queries.
declare const VideoDecoderProperties: {
getWidevineLevel(): Promise<number>;
isCodecSupported(mimeType: string, width?: number, height?: number): Promise<boolean>;
isHEVCSupported(): Promise<boolean>;
};Expo Config Plugins for configuring native features like Picture-in-Picture, background audio, advertisement integration, and ExoPlayer extensions.
interface ConfigProps {
enableNotificationControls?: boolean;
enableAndroidPictureInPicture?: boolean;
enableBackgroundAudio?: boolean;
enableADSExtension?: boolean;
enableCacheExtension?: boolean;
androidExtensions?: {
useExoplayerRtsp?: boolean;
useExoplayerSmoothStreaming?: boolean;
useExoplayerDash?: boolean;
useExoplayerHls?: boolean;
};
}// Main default export
export default Video;
// Named exports
export { Video, VideoDecoderProperties };
export * from "./types"; // All type definitions
// Core component type
declare const Video: React.ForwardRefExoticComponent<
ReactVideoProps & React.RefAttributes<VideoRef>
>;
// Utility exports (Android only)
declare const VideoDecoderProperties: {
getWidevineLevel(): Promise<number>;
isCodecSupported(mimeType: string, width?: number, height?: number): Promise<'unsupported' | 'hardware' | 'software'>;
isHEVCSupported(): Promise<'unsupported' | 'hardware' | 'software'>;
};
// Main prop interface extending events and view props
interface ReactVideoProps extends ReactVideoEvents, ViewProps {
source?: ReactVideoSource;
style?: StyleProp<ViewStyle>;
// ... see sub-docs for complete prop definitions
}
// Reference interface for imperative control
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
}
// Video source configuration
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;
}
// Key enum exports
declare enum ResizeMode {
NONE = "none",
CONTAIN = "contain",
COVER = "cover",
STRETCH = "stretch"
}
declare enum ViewType {
TEXTURE = 0,
SURFACE = 1,
SURFACE_SECURE = 2
}
declare enum FilterType {
NONE = "",
INVERT = "CIColorInvert",
MONOCHROME = "CIColorMonochrome",
CHROME = "CIPhotoEffectChrome",
SEPIA = "CISepiaTone",
INSTANT = "CIPhotoEffectInstant",
NOIR = "CIPhotoEffectNoir",
PROCESS = "CIPhotoEffectProcess",
TRANSFER = "CIPhotoEffectTransfer",
TONAL = "CIPhotoEffectTonal",
FADE = "CIPhotoEffectFade",
MONO = "CIColorMonochrome",
POSTERIZE = "CIColorPosterize",
FALSE_COLOR = "CIFalseColor",
MAXIMIZE_COMPONENT = "CIMaximumComponent",
MINIMIZE_COMPONENT = "CIMinimumComponent",
CHROME_KEY = "CIChromaKey",
BLOOM = "CIBloom",
GLOOM = "CIGloom"
}
declare enum TextTrackType {
SUBRIP = "application/x-subrip",
TTML = "application/ttml+xml",
VTT = "text/vtt"
}
declare enum Orientation {
PORTRAIT = "portrait",
LANDSCAPE = "landscape"
}
declare enum DRMType {
WIDEVINE = "widevine",
PLAYREADY = "playready",
CLEARKEY = "clearkey",
FAIRPLAY = "fairplay"
}
declare enum CmcdMode {
MODE_REQUEST_HEADER = 0,
MODE_QUERY_PARAMETER = 1
}
declare enum BufferingStrategyType {
DEFAULT = "Default",
DISABLE_BUFFERING = "DisableBuffering",
DEPENDING_ON_MEMORY = "DependingOnMemory"
}
declare enum SelectedTrackType {
SYSTEM = "system",
DISABLED = "disabled",
TITLE = "title",
LANGUAGE = "language",
INDEX = "index"
}
declare enum SelectedVideoTrackType {
AUTO = "auto",
DISABLED = "disabled",
RESOLUTION = "resolution",
INDEX = "index"
}
declare enum FullscreenOrientationType {
ALL = "all",
LANDSCAPE = "landscape",
PORTRAIT = "portrait"
}
declare enum IgnoreSilentSwitchType {
INHERIT = "inherit",
IGNORE = "ignore",
OBEY = "obey"
}
declare enum MixWithOthersType {
INHERIT = "inherit",
MIX = "mix",
DUCK = "duck"
}
declare enum AudioOutput {
SPEAKER = "speaker",
EARPIECE = "earpiece"
}
// Complete AdEvent enum (32 events)
declare enum AdEvent {
AD_BREAK_ENDED = "AD_BREAK_ENDED",
AD_BREAK_READY = "AD_BREAK_READY",
AD_BREAK_STARTED = "AD_BREAK_STARTED",
AD_BUFFERING = "AD_BUFFERING",
AD_CAN_PLAY = "AD_CAN_PLAY",
AD_METADATA = "AD_METADATA",
AD_PERIOD_ENDED = "AD_PERIOD_ENDED",
AD_PERIOD_STARTED = "AD_PERIOD_STARTED",
AD_PROGRESS = "AD_PROGRESS",
ALL_ADS_COMPLETED = "ALL_ADS_COMPLETED",
CLICKED = "CLICKED",
COMPLETED = "COMPLETED",
CONTENT_PAUSE_REQUESTED = "CONTENT_PAUSE_REQUESTED",
CONTENT_RESUME_REQUESTED = "CONTENT_RESUME_REQUESTED",
CUEPOINTS_CHANGED = "CUEPOINTS_CHANGED",
DURATION_CHANGE = "DURATION_CHANGE",
ERROR = "ERROR",
FIRST_QUARTILE = "FIRST_QUARTILE",
IMPRESSION = "IMPRESSION",
INTERACTION = "INTERACTION",
LINEAR_CHANGED = "LINEAR_CHANGED",
LOADED = "LOADED",
LOG = "LOG",
MIDPOINT = "MIDPOINT",
PAUSED = "PAUSED",
RESUMED = "RESUMED",
SKIPPABLE_STATE_CHANGED = "SKIPPABLE_STATE_CHANGED",
SKIPPED = "SKIPPED",
STARTED = "STARTED",
TAPPED = "TAPPED",
THIRD_QUARTILE = "THIRD_QUARTILE",
USER_CLOSE = "USER_CLOSE",
VIDEO_CLICKED = "VIDEO_CLICKED",
VIDEO_ICON_CLICKED = "VIDEO_ICON_CLICKED",
VOLUME_CHANGED = "VOLUME_CHANGED",
VOLUME_MUTED = "VOLUME_MUTED"
}
// Language support
type ISO639_1 = "aa" | "ab" | "ae" | "af" | "ak" | "am" | "an" | "ar" | "as" | "av" | "ay" | "az" | "ba" | "be" | "bg" | "bh" | "bi" | "bm" | "bn" | "bo" | "br" | "bs" | "ca" | "ce" | "ch" | "co" | "cr" | "cs" | "cu" | "cv" | "cy" | "da" | "de" | "dv" | "dz" | "ee" | "el" | "en" | "eo" | "es" | "et" | "eu" | "fa" | "ff" | "fi" | "fj" | "fo" | "fr" | "fy" | "ga" | "gd" | "gl" | "gn" | "gu" | "gv" | "ha" | "he" | "hi" | "ho" | "hr" | "ht" | "hu" | "hy" | "hz" | "ia" | "id" | "ie" | "ig" | "ii" | "ik" | "io" | "is" | "it" | "iu" | "ja" | "jv" | "ka" | "kg" | "ki" | "kj" | "kk" | "kl" | "km" | "kn" | "ko" | "kr" | "ks" | "ku" | "kv" | "kw" | "ky" | "la" | "lb" | "lg" | "li" | "ln" | "lo" | "lt" | "lu" | "lv" | "mg" | "mh" | "mi" | "mk" | "ml" | "mn" | "mr" | "ms" | "mt" | "my" | "na" | "nb" | "nd" | "ne" | "ng" | "nl" | "nn" | "no" | "nr" | "nv" | "ny" | "oc" | "oj" | "om" | "or" | "os" | "pa" | "pi" | "pl" | "ps" | "pt" | "qu" | "rm" | "rn" | "ro" | "ru" | "rw" | "sa" | "sc" | "sd" | "se" | "sg" | "si" | "sk" | "sl" | "sm" | "sn" | "so" | "sq" | "sr" | "ss" | "st" | "su" | "sv" | "sw" | "ta" | "te" | "tg" | "th" | "ti" | "tk" | "tl" | "tn" | "to" | "tr" | "ts" | "tt" | "tw" | "ty" | "ug" | "uk" | "ur" | "uz" | "ve" | "vi" | "vo" | "wa" | "wo" | "xh" | "yi" | "yo" | "za" | "zh" | "zu";
// Utility types
type Headers = Record<string, string>;
type EnumValues<T> = T[keyof T];
interface VideoMetadata {
title?: string;
subtitle?: string;
description?: string;
artist?: string;
imageUri?: string;
}
interface DebugConfig {
enable?: boolean;
thread?: boolean;
}
type TextTracks = {
title: string;
language: ISO639_1;
type: TextTrackType;
uri: string;
}[];
type Chapters = {
title: string;
startTime: number;
endTime: number;
uri?: string;
}[];
interface VideoSaveData {
uri: string;
}