# React Native Video v7 Documentation > Complete documentation for React Native Video v7 This file contains all documentation content in a single document following the llmstxt.org standard. ## Class: VideoPlayer # Class: VideoPlayer Defined in: [VideoPlayer.ts:20](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L20) ## Extends - `VideoPlayerEvents` ## Implements - `VideoPlayerBase` ## Constructors ### Constructor ```ts new VideoPlayer(source): VideoPlayer; ``` Defined in: [VideoPlayer.ts:35](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L35) #### Parameters | Parameter | Type | | ------ | ------ | | `source` | \| [`VideoSource`](../type-aliases/VideoSource.md) \| [`VideoConfig`](../type-aliases/VideoConfig.md) \| `VideoPlayerSource` | #### Returns `VideoPlayer` #### Overrides ```ts VideoPlayerEvents.constructor ``` ## Accessors ### currentTime #### Get Signature ```ts get currentTime(): number; ``` Defined in: [VideoPlayer.ts:149](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L149) The duration of the video in seconds (1.0 = 1 sec). Returns NaN if the duration is not available. ##### Returns `number` #### Set Signature ```ts set currentTime(value): void; ``` Defined in: [VideoPlayer.ts:153](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L153) The duration of the video in seconds (1.0 = 1 sec). Returns NaN if the duration is not available. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `number` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.currentTime ``` *** ### disableAudioSessionManagement #### Get Signature ```ts get disableAudioSessionManagement(): boolean; ``` Defined in: [VideoPlayer.ts:227](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L227) Disables the internal audio session management for this player. When disabled, react-native-video will not configure or activate the AVAudioSession, allowing other libraries (like audio recording libraries) to manage it. ##### Default ```ts false ``` ##### Platform iOS ##### Returns `boolean` #### Set Signature ```ts set disableAudioSessionManagement(value): void; ``` Defined in: [VideoPlayer.ts:231](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L231) Disables the internal audio session management for this player. When disabled, react-native-video will not configure or activate the AVAudioSession, allowing other libraries (like audio recording libraries) to manage it. ##### Default ```ts false ``` ##### Platform iOS ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `boolean` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.disableAudioSessionManagement ``` *** ### duration #### Get Signature ```ts get duration(): number; ``` Defined in: [VideoPlayer.ts:135](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L135) The current time of the video in seconds (1.0 = 1 sec). Returns NaN if the current time is not available. ##### Returns `number` #### Implementation of ```ts VideoPlayerBase.duration ``` *** ### ignoreSilentSwitchMode #### Get Signature ```ts get ignoreSilentSwitchMode(): IgnoreSilentSwitchMode; ``` Defined in: [VideoPlayer.ts:194](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L194) Controls the silent switch mode of the player. ##### Note This is only supported on iOS. - `auto` - uses default behavior for player. - `ignore` - ignore the silent switch. - `obey` - obey the silent switch. ##### Returns [`IgnoreSilentSwitchMode`](../type-aliases/IgnoreSilentSwitchMode.md) #### Set Signature ```ts set ignoreSilentSwitchMode(value): void; ``` Defined in: [VideoPlayer.ts:198](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L198) Controls the silent switch mode of the player. ##### Note This is only supported on iOS. - `auto` - uses default behavior for player. - `ignore` - ignore the silent switch. - `obey` - obey the silent switch. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | [`IgnoreSilentSwitchMode`](../type-aliases/IgnoreSilentSwitchMode.md) | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.ignoreSilentSwitchMode ``` *** ### isPlaying #### Get Signature ```ts get isPlaying(): boolean; ``` Defined in: [VideoPlayer.ts:242](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L242) Whether the player is playing. ##### Note This is a read-only property. ##### Note To pause/resume the player, you need to use [play](../interfaces/WebVideoPlayer.md#play) and [pause](../interfaces/WebVideoPlayer.md#pause) methods. ##### Returns `boolean` #### Implementation of ```ts VideoPlayerBase.isPlaying ``` *** ### loop #### Get Signature ```ts get loop(): boolean; ``` Defined in: [VideoPlayer.ts:167](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L167) Whether the player is looped. ##### Returns `boolean` #### Set Signature ```ts set loop(value): void; ``` Defined in: [VideoPlayer.ts:171](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L171) Whether the player is looped. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `boolean` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.loop ``` *** ### mixAudioMode #### Get Signature ```ts get mixAudioMode(): MixAudioMode; ``` Defined in: [VideoPlayer.ts:185](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L185) Controls the audio mixing mode of the player. - `mixWithOthers` - Mix with other players. - `doNotMix` - Do not mix with other players. - `duckOthers` - Duck other players. - `auto` - uses default behavior for player. default is `auto`. ##### Returns [`MixAudioMode`](../type-aliases/MixAudioMode.md) #### Set Signature ```ts set mixAudioMode(value): void; ``` Defined in: [VideoPlayer.ts:189](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L189) Controls the audio mixing mode of the player. - `mixWithOthers` - Mix with other players. - `doNotMix` - Do not mix with other players. - `duckOthers` - Duck other players. - `auto` - uses default behavior for player. default is `auto`. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | [`MixAudioMode`](../type-aliases/MixAudioMode.md) | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.mixAudioMode ``` *** ### muted #### Get Signature ```ts get muted(): boolean; ``` Defined in: [VideoPlayer.ts:158](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L158) Whether the player is muted. ##### Returns `boolean` #### Set Signature ```ts set muted(value): void; ``` Defined in: [VideoPlayer.ts:162](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L162) Whether the player is muted. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `boolean` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.muted ``` *** ### playInBackground #### Get Signature ```ts get playInBackground(): boolean; ``` Defined in: [VideoPlayer.ts:209](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L209) Whether the player should play in background. - `true` - play in background. - `false` - pause in background (default). ##### Note this can override [playWhenInactive](../interfaces/WebVideoPlayer.md#playwheninactive). ##### Returns `boolean` #### Set Signature ```ts set playInBackground(value): void; ``` Defined in: [VideoPlayer.ts:213](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L213) Whether the player should play in background. - `true` - play in background. - `false` - pause in background (default). ##### Note this can override [playWhenInactive](../interfaces/WebVideoPlayer.md#playwheninactive). ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `boolean` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.playInBackground ``` *** ### playWhenInactive #### Get Signature ```ts get playWhenInactive(): boolean; ``` Defined in: [VideoPlayer.ts:218](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L218) Whether the player should play when the app is inactive (user opened control center). - `true` - play when the app is inactive. - `false` - pause when the app is inactive (default). ##### Note this can be overridden by [playInBackground](../interfaces/WebVideoPlayer.md#playinbackground). ##### Note This is only supported on iOS. ##### Returns `boolean` #### Set Signature ```ts set playWhenInactive(value): void; ``` Defined in: [VideoPlayer.ts:222](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L222) Whether the player should play when the app is inactive (user opened control center). - `true` - play when the app is inactive. - `false` - pause when the app is inactive (default). ##### Note this can be overridden by [playInBackground](../interfaces/WebVideoPlayer.md#playinbackground). ##### Note This is only supported on iOS. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `boolean` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.playWhenInactive ``` *** ### rate #### Get Signature ```ts get rate(): number; ``` Defined in: [VideoPlayer.ts:176](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L176) Controls the speed at which the player should play. ##### Note if rate is = 0, it will pause video. ##### Returns `number` #### Set Signature ```ts set rate(value): void; ``` Defined in: [VideoPlayer.ts:180](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L180) Controls the speed at which the player should play. ##### Note if rate is = 0, it will pause video. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `number` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.rate ``` *** ### selectedTrack #### Get Signature ```ts get selectedTrack(): TextTrack | undefined; ``` Defined in: [VideoPlayer.ts:341](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L341) Get the currently selected text track. ##### Returns [`TextTrack`](../interfaces/TextTrack.md) \| `undefined` The currently selected text track, or undefined if none is selected #### Implementation of ```ts VideoPlayerBase.selectedTrack ``` *** ### showNotificationControls #### Get Signature ```ts get showNotificationControls(): boolean; ``` Defined in: [VideoPlayer.ts:246](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L246) Whether to show notification controls (lock screen / control center). ##### Returns `boolean` #### Set Signature ```ts set showNotificationControls(value): void; ``` Defined in: [VideoPlayer.ts:250](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L250) Whether to show notification controls (lock screen / control center). ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `boolean` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.showNotificationControls ``` *** ### source #### Get Signature ```ts get source(): VideoPlayerSource; ``` Defined in: [VideoPlayer.ts:125](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L125) The source of the video. Source is immutable. To change the source, you need to call [replaceSourceAsync](../interfaces/WebVideoPlayer.md#replacesourceasync) method. see VideoPlayerSourceBase ##### Returns `VideoPlayerSource` #### Implementation of ```ts VideoPlayerBase.source ``` *** ### status #### Get Signature ```ts get status(): VideoPlayerStatus; ``` Defined in: [VideoPlayer.ts:130](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L130) The status of the player. ##### Returns [`VideoPlayerStatus`](../type-aliases/VideoPlayerStatus.md) #### Implementation of ```ts VideoPlayerBase.status ``` *** ### volume #### Get Signature ```ts get volume(): number; ``` Defined in: [VideoPlayer.ts:140](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L140) The volume of the video (0.0 = 0%, 1.0 = 100%). ##### Note If the player is [muted](../interfaces/WebVideoPlayer.md#muted), the volume will be 0.0. ##### Returns `number` #### Set Signature ```ts set volume(value): void; ``` Defined in: [VideoPlayer.ts:144](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L144) The volume of the video (0.0 = 0%, 1.0 = 100%). ##### Note If the player is [muted](../interfaces/WebVideoPlayer.md#muted), the volume will be 0.0. ##### Parameters | Parameter | Type | | ------ | ------ | | `value` | `number` | ##### Returns `void` #### Implementation of ```ts VideoPlayerBase.volume ``` ## Methods ### addEventListener() ```ts addEventListener(event, callback): ListenerSubscription; ``` Defined in: [events/VideoPlayerEvents.native.ts:9](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/events/VideoPlayerEvents.native.ts#L9) #### Type Parameters | Type Parameter | | ------ | | `Event` *extends* keyof VideoPlayerEvents \| `"onError"` | #### Parameters | Parameter | Type | | ------ | ------ | | `event` | `Event` | | `callback` | [`AllPlayerEvents`](../type-aliases/AllPlayerEvents.md)\[`Event`\] | #### Returns `ListenerSubscription` #### Implementation of ```ts VideoPlayerBase.addEventListener ``` #### Inherited from ```ts VideoPlayerEvents.addEventListener ``` *** ### clearAllEvents() ```ts clearAllEvents(): void; ``` Defined in: [events/VideoPlayerEventsBase.ts:42](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/events/VideoPlayerEventsBase.ts#L42) #### Returns `void` #### Inherited from ```ts VideoPlayerEvents.clearAllEvents ``` *** ### getAvailableTextTracks() ```ts getAvailableTextTracks(): TextTrack[]; ``` Defined in: [VideoPlayer.ts:323](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L323) Get all available text tracks for the current source. #### Returns [`TextTrack`](../interfaces/TextTrack.md)[] Array of available text tracks #### Implementation of ```ts VideoPlayerBase.getAvailableTextTracks ``` *** ### initialize() ```ts initialize(): Promise; ``` Defined in: [VideoPlayer.ts:254](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L254) Manually initialize the player. You don't need to call this method manually, unless you set `initializeOnCreation` to false in [VideoConfig](../type-aliases/VideoConfig.md) #### Returns `Promise`\ #### Implementation of ```ts VideoPlayerBase.initialize ``` *** ### pause() ```ts pause(): void; ``` Defined in: [VideoPlayer.ts:284](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L284) Pause playback of player. #### Returns `void` #### Implementation of ```ts VideoPlayerBase.pause ``` *** ### play() ```ts play(): void; ``` Defined in: [VideoPlayer.ts:276](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L276) Start playback of player. #### Returns `void` #### Implementation of ```ts VideoPlayerBase.play ``` *** ### preload() ```ts preload(): Promise; ``` Defined in: [VideoPlayer.ts:260](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L260) Preload the video. This is useful to avoid delay when the user plays the video. Preloading too many videos can lead to memory issues or performance issues. #### Returns `Promise`\ #### Implementation of ```ts VideoPlayerBase.preload ``` *** ### release() ```ts release(): void; ``` Defined in: [VideoPlayer.ts:272](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L272) Releases the player's native resources and releases native state. After calling this method, the player is no longer usable. Accessing any properties or methods of the player after calling this method will throw an error. If you want to clean player resource use `replaceSourceAsync` with `null` instead. #### Returns `void` #### Implementation of ```ts VideoPlayerBase.release ``` *** ### replaceSourceAsync() ```ts replaceSourceAsync(source): Promise; ``` Defined in: [VideoPlayer.ts:308](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L308) Replace the current source of the player. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `source` | \| [`VideoSource`](../type-aliases/VideoSource.md) \| [`VideoConfig`](../type-aliases/VideoConfig.md) \| `null` | The new source of the video. | #### Returns `Promise`\ #### Note If you want to clear the source, you can pass null. see VideoPlayerSourceBase #### Implementation of ```ts VideoPlayerBase.replaceSourceAsync ``` *** ### seekBy() ```ts seekBy(time): void; ``` Defined in: [VideoPlayer.ts:292](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L292) Seek by given time. If the time is negative, it will seek backward. time will be clamped if it is out of range (0 ~ [duration](../interfaces/WebVideoPlayer.md#duration)). #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `time` | `number` | The time to seek from current time in seconds. | #### Returns `void` #### Implementation of ```ts VideoPlayerBase.seekBy ``` *** ### seekTo() ```ts seekTo(time): void; ``` Defined in: [VideoPlayer.ts:300](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L300) Seek to a specific time in the video. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `time` | `number` | The time to seek to in seconds. | #### Returns `void` #### Note This have same effect as [currentTime](../interfaces/WebVideoPlayer.md#currenttime) setter. #### Note time will be clamped if it is out of range (0 ~ [duration](../interfaces/WebVideoPlayer.md#duration)). #### Implementation of ```ts VideoPlayerBase.seekTo ``` *** ### selectTextTrack() ```ts selectTextTrack(textTrack): void; ``` Defined in: [VideoPlayer.ts:332](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/VideoPlayer.ts#L332) Select a text track to display. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `textTrack` | [`TextTrack`](../interfaces/TextTrack.md) \| `null` | Text track to select, or null to unselect current track | #### Returns `void` #### Implementation of ```ts VideoPlayerBase.selectTextTrack ``` --- ## Function: setAudioSessionManagementDisabled() # Function: setAudioSessionManagementDisabled() ```ts function setAudioSessionManagementDisabled(disabled): void; ``` Defined in: [utils/playerFactory.ts:35](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/utils/playerFactory.ts#L35) Disables the internal audio session management on iOS. When disabled, react-native-video will not configure or activate the AVAudioSession, allowing other libraries (like audio recording libraries) to manage it. ## Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `disabled` | `boolean` | If true, audio session management is disabled | ## Returns `void` ## Platform iOS ## Example ```tsx // Disable audio session management before recording setAudioSessionManagementDisabled(true); // Record audio using another library... // Re-enable audio session management after recording setAudioSessionManagementDisabled(false); ``` --- ## Function: useEvent() # Function: useEvent() ```ts function useEvent( player, event, callback): void; ``` Defined in: [hooks/useEvent.ts:12](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/hooks/useEvent.ts#L12) Attaches an event listener to a `VideoPlayer` instance for a specified event. ## Type Parameters | Type Parameter | | ------ | | `T` *extends* keyof VideoPlayerEvents \| `"onError"` | ## Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `player` | `VideoPlayerBase` | The player to attach the event to | | `event` | `T` | The name of the event to attach the callback to | | `callback` | [`AllPlayerEvents`](../type-aliases/AllPlayerEvents.md)\[`T`\] | The callback for the event | ## Returns `void` --- ## Function: useVideoPlayer() # Function: useVideoPlayer() ```ts function useVideoPlayer(source, setup?): VideoPlayer; ``` Defined in: [hooks/useVideoPlayer.ts:30](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/hooks/useVideoPlayer.ts#L30) Creates a `VideoPlayer` instance and manages its lifecycle. if `initializeOnCreation` is true (default), the `setup` function will be called when the player is started loading source. if `initializeOnCreation` is false, the `setup` function will be called when the player is created. changes made to player made before initializing will be overwritten when initializing. ## Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `source` | \| [`VideoSource`](../type-aliases/VideoSource.md) \| [`VideoConfig`](../type-aliases/VideoConfig.md) | The source of the video to play | | `setup?` | (`player`) => `void` | A function to setup the player | ## Returns [`VideoPlayer`](../classes/VideoPlayer.md) The `VideoPlayer` instance --- ## API Reference # API Reference ## Classes - [VideoPlayer](classes/VideoPlayer.md) ## Interfaces - [AudioTrack](interfaces/AudioTrack.md) - [BandwidthData](interfaces/BandwidthData.md) - [JSVideoPlayerEvents](interfaces/JSVideoPlayerEvents.md) - [onLoadData](interfaces/onLoadData.md) - [onLoadStartData](interfaces/onLoadStartData.md) - [onPlaybackStateChangeData](interfaces/onPlaybackStateChangeData.md) - [onProgressData](interfaces/onProgressData.md) - [onVolumeChangeData](interfaces/onVolumeChangeData.md) - [TextTrack](interfaces/TextTrack.md) - [TimedMetadata](interfaces/TimedMetadata.md) - [VideoComponentError](interfaces/VideoComponentError.md) - [VideoError](interfaces/VideoError.md) - [VideoPlayerEvents](interfaces/VideoPlayerEvents.md) - [VideoRuntimeError](interfaces/VideoRuntimeError.md) - [VideoTrack](interfaces/VideoTrack.md) - [VideoViewEvents](interfaces/VideoViewEvents.md) - [VideoViewProps](interfaces/VideoViewProps.md) - [VideoViewRef](interfaces/VideoViewRef.md) - [WebVideoPlayer](interfaces/WebVideoPlayer.md) ## Type Aliases - [AllPlayerEvents](type-aliases/AllPlayerEvents.md) - [IgnoreSilentSwitchMode](type-aliases/IgnoreSilentSwitchMode.md) - [LibraryError](type-aliases/LibraryError.md) - [MixAudioMode](type-aliases/MixAudioMode.md) - [PlayerError](type-aliases/PlayerError.md) - [ResizeMode](type-aliases/ResizeMode.md) - [SourceError](type-aliases/SourceError.md) - [SourceType](type-aliases/SourceType.md) - [TimedMetadataObject](type-aliases/TimedMetadataObject.md) - [UnknownError](type-aliases/UnknownError.md) - [VideoConfig](type-aliases/VideoConfig.md) - [VideoErrorCode](type-aliases/VideoErrorCode.md) - [VideoPlayerStatus](type-aliases/VideoPlayerStatus.md) - [VideoSource](type-aliases/VideoSource.md) - [VideoViewError](type-aliases/VideoViewError.md) - [WebError](type-aliases/WebError.md) ## Variables - [ALL\_PLAYER\_EVENTS](variables/ALL_PLAYER_EVENTS.md) - [ALL\_VIEW\_EVENTS](variables/ALL_VIEW_EVENTS.md) - [VideoView](variables/VideoView.md) ## Functions - [setAudioSessionManagementDisabled](functions/setAudioSessionManagementDisabled.md) - [useEvent](functions/useEvent.md) - [useVideoPlayer](functions/useVideoPlayer.md) --- ## Interface: AudioTrack # Interface: AudioTrack Defined in: [types/AudioTrack.ts:1](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/AudioTrack.ts#L1) ## Properties ### id ```ts id: string; ``` Defined in: [types/AudioTrack.ts:2](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/AudioTrack.ts#L2) *** ### label ```ts label: string; ``` Defined in: [types/AudioTrack.ts:3](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/AudioTrack.ts#L3) *** ### language? ```ts optional language?: string; ``` Defined in: [types/AudioTrack.ts:4](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/AudioTrack.ts#L4) *** ### selected ```ts selected: boolean; ``` Defined in: [types/AudioTrack.ts:5](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/AudioTrack.ts#L5) --- ## Interface: BandwidthData # Interface: BandwidthData Defined in: [types/Events.ts:135](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L135) ## Properties ### bitrate ```ts bitrate: number; ``` Defined in: [types/Events.ts:139](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L139) The bitrate of the video in bits per second. *** ### height? ```ts optional height?: number; ``` Defined in: [types/Events.ts:149](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L149) The height of the video in pixels. #### Platform Android *** ### width? ```ts optional width?: number; ``` Defined in: [types/Events.ts:144](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L144) The width of the video in pixels. #### Platform android --- ## Interface: JSVideoPlayerEvents # Interface: JSVideoPlayerEvents Defined in: [types/Events.ts:100](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L100) ## Properties ### onError ```ts onError: (error) => void; ``` Defined in: [types/Events.ts:101](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L101) #### Parameters | Parameter | Type | | ------ | ------ | | `error` | [`VideoRuntimeError`](VideoRuntimeError.md) | #### Returns `void` --- ## Interface: TextTrack # Interface: TextTrack Defined in: [types/TextTrack.ts:1](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/TextTrack.ts#L1) ## Properties ### id ```ts id: string; ``` Defined in: [types/TextTrack.ts:5](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/TextTrack.ts#L5) Unique identifier for the text track *** ### label ```ts label: string; ``` Defined in: [types/TextTrack.ts:10](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/TextTrack.ts#L10) Display label for the text track *** ### language? ```ts optional language?: string; ``` Defined in: [types/TextTrack.ts:16](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/TextTrack.ts#L16) Language code (ISO 639-1 or ISO 639-2) #### Example ```ts "en", "es", "fr" ``` *** ### selected ```ts selected: boolean; ``` Defined in: [types/TextTrack.ts:21](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/TextTrack.ts#L21) Whether this track is currently selected --- ## Interface: TimedMetadata # Interface: TimedMetadata Defined in: [types/Events.ts:217](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L217) ## Properties ### metadata ```ts metadata: TimedMetadataObject[]; ``` Defined in: [types/Events.ts:221](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L221) The timed metadata of the video. --- ## Interface: VideoComponentError # Interface: VideoComponentError Defined in: [types/VideoError.ts:74](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L74) ## Extends - [`VideoError`](VideoError.md)\ ## Accessors ### code #### Get Signature ```ts get code(): TCode; ``` Defined in: [types/VideoError.ts:44](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L44) ##### Returns `TCode` #### Inherited from [`VideoError`](VideoError.md).[`code`](VideoError.md#code) *** ### message #### Get Signature ```ts get message(): string; ``` Defined in: [types/VideoError.ts:47](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L47) ##### Returns `string` #### Inherited from [`VideoError`](VideoError.md).[`message`](VideoError.md#message) *** ### stack #### Get Signature ```ts get stack(): string | undefined; ``` Defined in: [types/VideoError.ts:51](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L51) ##### Returns `string` \| `undefined` #### Inherited from [`VideoError`](VideoError.md).[`stack`](VideoError.md#stack) ## Methods ### toString() ```ts toString(): string; ``` Defined in: [types/VideoError.ts:68](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L68) Returns a string representation of an object. #### Returns `string` #### Inherited from [`VideoError`](VideoError.md).[`toString`](VideoError.md#tostring) --- ## Interface: VideoError\ # Interface: VideoError\ Defined in: [types/VideoError.ts:39](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L39) ## Extends - `Error` ## Extended by - [`VideoComponentError`](VideoComponentError.md) - [`VideoRuntimeError`](VideoRuntimeError.md) ## Type Parameters | Type Parameter | | ------ | | `TCode` *extends* [`VideoErrorCode`](../type-aliases/VideoErrorCode.md) | ## Accessors ### code #### Get Signature ```ts get code(): TCode; ``` Defined in: [types/VideoError.ts:44](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L44) ##### Returns `TCode` *** ### message #### Get Signature ```ts get message(): string; ``` Defined in: [types/VideoError.ts:47](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L47) ##### Returns `string` #### Overrides ```ts Error.message ``` *** ### stack #### Get Signature ```ts get stack(): string | undefined; ``` Defined in: [types/VideoError.ts:51](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L51) ##### Returns `string` \| `undefined` #### Overrides ```ts Error.stack ``` ## Methods ### toString() ```ts toString(): string; ``` Defined in: [types/VideoError.ts:68](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L68) Returns a string representation of an object. #### Returns `string` --- ## Interface: VideoPlayerEvents # Interface: VideoPlayerEvents Defined in: [types/Events.ts:7](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L7) ## Properties ### onAudioBecomingNoisy ```ts onAudioBecomingNoisy: () => void; ``` Defined in: [types/Events.ts:12](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L12) Called when the audio becomes noisy. #### Returns `void` #### Platform Android *** ### onAudioFocusChange ```ts onAudioFocusChange: (hasAudioFocus) => void; ``` Defined in: [types/Events.ts:18](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L18) Called when the audio focus changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `hasAudioFocus` | `boolean` | Whether the audio has focus. | #### Returns `void` #### Platform Android *** ### onBandwidthUpdate ```ts onBandwidthUpdate: (data) => void; ``` Defined in: [types/Events.ts:22](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L22) Called when the bandwidth of the video changes. #### Parameters | Parameter | Type | | ------ | ------ | | `data` | [`BandwidthData`](BandwidthData.md) | #### Returns `void` *** ### onBuffer ```ts onBuffer: (buffering) => void; ``` Defined in: [types/Events.ts:27](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L27) Called when the video is buffering. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `buffering` | `boolean` | Whether the video is buffering. | #### Returns `void` *** ### onControlsVisibleChange ```ts onControlsVisibleChange: (visible) => void; ``` Defined in: [types/Events.ts:33](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L33) Called when the video view's controls visibility changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `visible` | `boolean` | Whether the video view's controls are visible. | #### Returns `void` #### Platform Android, Ios *** ### onEnd ```ts onEnd: () => void; ``` Defined in: [types/Events.ts:37](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L37) Called when the video ends. #### Returns `void` *** ### onExternalPlaybackChange ```ts onExternalPlaybackChange: (externalPlaybackActive) => void; ``` Defined in: [types/Events.ts:43](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L43) Called when the external playback state changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `externalPlaybackActive` | `boolean` | Whether the external playback is active. | #### Returns `void` #### Platform iOS *** ### onLoad ```ts onLoad: (data) => void; ``` Defined in: [types/Events.ts:48](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L48) Called when the video is loaded. #### Parameters | Parameter | Type | | ------ | ------ | | `data` | [`onLoadData`](onLoadData.md) | #### Returns `void` #### Note onLoadStart -> initialize the player -> onLoad *** ### onLoadStart ```ts onLoadStart: (data) => void; ``` Defined in: [types/Events.ts:53](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L53) Called when the video starts loading. #### Parameters | Parameter | Type | | ------ | ------ | | `data` | [`onLoadStartData`](onLoadStartData.md) | #### Returns `void` #### Note onLoadStart -> initialize the player -> onLoad *** ### onPlaybackRateChange ```ts onPlaybackRateChange: (rate) => void; ``` Defined in: [types/Events.ts:61](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L61) Called when the player playback rate changes. #### Parameters | Parameter | Type | | ------ | ------ | | `rate` | `number` | #### Returns `void` *** ### onPlaybackStateChange ```ts onPlaybackStateChange: (data) => void; ``` Defined in: [types/Events.ts:57](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L57) Called when the player playback state changes. #### Parameters | Parameter | Type | | ------ | ------ | | `data` | [`onPlaybackStateChangeData`](onPlaybackStateChangeData.md) | #### Returns `void` *** ### onProgress ```ts onProgress: (data) => void; ``` Defined in: [types/Events.ts:65](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L65) Called when the player progress changes. #### Parameters | Parameter | Type | | ------ | ------ | | `data` | [`onProgressData`](onProgressData.md) | #### Returns `void` *** ### onReadyToDisplay ```ts onReadyToDisplay: () => void; ``` Defined in: [types/Events.ts:69](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L69) Called when the video is ready to display. #### Returns `void` *** ### onSeek ```ts onSeek: (seekTime) => void; ``` Defined in: [types/Events.ts:73](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L73) Called when the player seeks. #### Parameters | Parameter | Type | | ------ | ------ | | `seekTime` | `number` | #### Returns `void` *** ### onStatusChange ```ts onStatusChange: (status) => void; ``` Defined in: [types/Events.ts:97](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L97) Called when the player status changes. #### Parameters | Parameter | Type | | ------ | ------ | | `status` | [`VideoPlayerStatus`](../type-aliases/VideoPlayerStatus.md) | #### Returns `void` *** ### onTextTrackDataChanged ```ts onTextTrackDataChanged: (texts) => void; ``` Defined in: [types/Events.ts:83](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L83) Called when the text track (currently displayed subtitle) data changes. #### Parameters | Parameter | Type | | ------ | ------ | | `texts` | `string`[] | #### Returns `void` #### Platform Android, Ios *** ### onTimedMetadata ```ts onTimedMetadata: (metadata) => void; ``` Defined in: [types/Events.ts:78](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L78) Called when player receives timed metadata. #### Parameters | Parameter | Type | | ------ | ------ | | `metadata` | [`TimedMetadata`](TimedMetadata.md) | #### Returns `void` #### Platform Android, Ios *** ### onTrackChange ```ts onTrackChange: (track) => void; ``` Defined in: [types/Events.ts:89](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L89) Called when the selected text track changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `track` | [`TextTrack`](TextTrack.md) \| `null` | The newly selected text track, or null if no track is selected | #### Returns `void` #### Platform Android, Ios *** ### onVolumeChange ```ts onVolumeChange: (data) => void; ``` Defined in: [types/Events.ts:93](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L93) Called when the volume of the player changes. #### Parameters | Parameter | Type | | ------ | ------ | | `data` | [`onVolumeChangeData`](onVolumeChangeData.md) | #### Returns `void` --- ## Interface: VideoRuntimeError # Interface: VideoRuntimeError Defined in: [types/VideoError.ts:76](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L76) ## Extends - [`VideoError`](VideoError.md)\ ## Accessors ### code #### Get Signature ```ts get code(): TCode; ``` Defined in: [types/VideoError.ts:44](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L44) ##### Returns `TCode` #### Inherited from [`VideoError`](VideoError.md).[`code`](VideoError.md#code) *** ### message #### Get Signature ```ts get message(): string; ``` Defined in: [types/VideoError.ts:47](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L47) ##### Returns `string` #### Inherited from [`VideoError`](VideoError.md).[`message`](VideoError.md#message) *** ### stack #### Get Signature ```ts get stack(): string | undefined; ``` Defined in: [types/VideoError.ts:51](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L51) ##### Returns `string` \| `undefined` #### Inherited from [`VideoError`](VideoError.md).[`stack`](VideoError.md#stack) ## Methods ### toString() ```ts toString(): string; ``` Defined in: [types/VideoError.ts:68](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L68) Returns a string representation of an object. #### Returns `string` #### Inherited from [`VideoError`](VideoError.md).[`toString`](VideoError.md#tostring) --- ## Interface: VideoTrack # Interface: VideoTrack Defined in: [types/VideoTrack.ts:1](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoTrack.ts#L1) ## Properties ### id ```ts id: string; ``` Defined in: [types/VideoTrack.ts:2](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoTrack.ts#L2) *** ### label ```ts label: string; ``` Defined in: [types/VideoTrack.ts:3](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoTrack.ts#L3) *** ### language? ```ts optional language?: string; ``` Defined in: [types/VideoTrack.ts:4](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoTrack.ts#L4) *** ### selected ```ts selected: boolean; ``` Defined in: [types/VideoTrack.ts:5](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoTrack.ts#L5) --- ## Interface: VideoViewEvents # Interface: VideoViewEvents Defined in: [types/Events.ts:106](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L106) ## Properties ### onFullscreenChange ```ts onFullscreenChange: (fullscreen) => void; ``` Defined in: [types/Events.ts:116](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L116) Called when the video view's fullscreen state changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `fullscreen` | `boolean` | Whether the video view is in fullscreen mode. | #### Returns `void` *** ### onPictureInPictureChange ```ts onPictureInPictureChange: (isInPictureInPicture) => void; ``` Defined in: [types/Events.ts:111](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L111) Called when the video view's picture in picture state changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `isInPictureInPicture` | `boolean` | Whether the video view is in picture in picture mode. | #### Returns `void` *** ### willEnterFullscreen ```ts willEnterFullscreen: () => void; ``` Defined in: [types/Events.ts:120](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L120) Called when the video view will enter fullscreen mode. #### Returns `void` *** ### willEnterPictureInPicture ```ts willEnterPictureInPicture: () => void; ``` Defined in: [types/Events.ts:128](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L128) Called when the video view will enter picture in picture mode. #### Returns `void` *** ### willExitFullscreen ```ts willExitFullscreen: () => void; ``` Defined in: [types/Events.ts:124](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L124) Called when the video view will exit fullscreen mode. #### Returns `void` *** ### willExitPictureInPicture ```ts willExitPictureInPicture: () => void; ``` Defined in: [types/Events.ts:132](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L132) Called when the video view will exit picture in picture mode. #### Returns `void` --- ## Interface: VideoViewProps # Interface: VideoViewProps Defined in: [video-view/VideoViewProps.ts:8](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L8) ## Extends - `Partial`\.`ViewProps` ## Properties ### autoEnterPictureInPicture? ```ts optional autoEnterPictureInPicture?: boolean; ``` Defined in: [video-view/VideoViewProps.ts:28](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L28) Whether to automatically enter picture in picture mode when the video is playing. Defaults to false. *** ### controls? ```ts optional controls?: boolean; ``` Defined in: [video-view/VideoViewProps.ts:20](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L20) Whether to show the controls. Defaults to false. *** ### keepScreenAwake? ```ts optional keepScreenAwake?: boolean; ``` Defined in: [video-view/VideoViewProps.ts:40](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L40) Whether to keep the screen awake while the video view is mounted. Defaults to true. *** ### onFullscreenChange? ```ts optional onFullscreenChange?: (fullscreen) => void; ``` Defined in: [types/Events.ts:116](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L116) Called when the video view's fullscreen state changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `fullscreen` | `boolean` | Whether the video view is in fullscreen mode. | #### Returns `void` #### Inherited from [`VideoViewEvents`](VideoViewEvents.md).[`onFullscreenChange`](VideoViewEvents.md#onfullscreenchange) *** ### onPictureInPictureChange? ```ts optional onPictureInPictureChange?: (isInPictureInPicture) => void; ``` Defined in: [types/Events.ts:111](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L111) Called when the video view's picture in picture state changes. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `isInPictureInPicture` | `boolean` | Whether the video view is in picture in picture mode. | #### Returns `void` #### Inherited from [`VideoViewEvents`](VideoViewEvents.md).[`onPictureInPictureChange`](VideoViewEvents.md#onpictureinpicturechange) *** ### pictureInPicture? ```ts optional pictureInPicture?: boolean; ``` Defined in: [video-view/VideoViewProps.ts:24](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L24) Whether to enable & show the picture in picture button in native controls. Defaults to false. *** ### player ```ts player: VideoPlayerBase; ``` Defined in: [video-view/VideoViewProps.ts:12](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L12) The player to play the video *** ### resizeMode? ```ts optional resizeMode?: ResizeMode; ``` Defined in: [video-view/VideoViewProps.ts:36](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L36) How the video should be resized to fit the view. Defaults to 'none'. - 'contain': Scale the video uniformly (maintain aspect ratio) so that it fits entirely within the view - 'cover': Scale the video uniformly (maintain aspect ratio) so that it fills the entire view (may crop) - 'stretch': Scale the video to fill the entire view without maintaining aspect ratio - 'none': Do not resize the video *** ### style? ```ts optional style?: ViewStyle; ``` Defined in: [video-view/VideoViewProps.ts:16](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L16) The style of the video view - ViewStyle #### Overrides ```ts ViewProps.style ``` *** ### surfaceType? ```ts optional surfaceType?: SurfaceType; ``` Defined in: [video-view/VideoViewProps.ts:52](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L52) The type of underlying native view. Defaults to 'surface'. - 'surface': Uses a SurfaceView on Android. More performant, but cannot be animated or transformed. - 'texture': Uses a TextureView on Android. Less performant, but can be animated and transformed. Only applicable on Android #### Default ```ts 'surface' ``` #### Platform android *** ### willEnterFullscreen? ```ts optional willEnterFullscreen?: () => void; ``` Defined in: [types/Events.ts:120](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L120) Called when the video view will enter fullscreen mode. #### Returns `void` #### Inherited from [`VideoViewEvents`](VideoViewEvents.md).[`willEnterFullscreen`](VideoViewEvents.md#willenterfullscreen) *** ### willEnterPictureInPicture? ```ts optional willEnterPictureInPicture?: () => void; ``` Defined in: [types/Events.ts:128](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L128) Called when the video view will enter picture in picture mode. #### Returns `void` #### Inherited from [`VideoViewEvents`](VideoViewEvents.md).[`willEnterPictureInPicture`](VideoViewEvents.md#willenterpictureinpicture) *** ### willExitFullscreen? ```ts optional willExitFullscreen?: () => void; ``` Defined in: [types/Events.ts:124](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L124) Called when the video view will exit fullscreen mode. #### Returns `void` #### Inherited from [`VideoViewEvents`](VideoViewEvents.md).[`willExitFullscreen`](VideoViewEvents.md#willexitfullscreen) *** ### willExitPictureInPicture? ```ts optional willExitPictureInPicture?: () => void; ``` Defined in: [types/Events.ts:132](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L132) Called when the video view will exit picture in picture mode. #### Returns `void` #### Inherited from [`VideoViewEvents`](VideoViewEvents.md).[`willExitPictureInPicture`](VideoViewEvents.md#willexitpictureinpicture) --- ## Interface: VideoViewRef # Interface: VideoViewRef Defined in: [video-view/VideoViewProps.ts:55](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L55) ## Properties ### addEventListener ```ts addEventListener: (event, callback) => ListenerSubscription; ``` Defined in: [video-view/VideoViewProps.ts:83](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L83) Adds a listener for a view event. #### Type Parameters | Type Parameter | | ------ | | `Event` *extends* keyof [`VideoViewEvents`](VideoViewEvents.md) | #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `event` | `Event` | The event to add a listener for. | | `callback` | [`VideoViewEvents`](VideoViewEvents.md)\[`Event`\] | The callback to call when the event is triggered. | #### Returns `ListenerSubscription` A subscription object that can be used to remove the listener. *** ### canEnterPictureInPicture ```ts canEnterPictureInPicture: () => boolean; ``` Defined in: [video-view/VideoViewProps.ts:76](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L76) Check if picture in picture mode is supported #### Returns `boolean` true if picture in picture mode is supported, false otherwise *** ### enterFullscreen ```ts enterFullscreen: () => void; ``` Defined in: [video-view/VideoViewProps.ts:59](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L59) Enter fullscreen mode #### Returns `void` *** ### enterPictureInPicture ```ts enterPictureInPicture: () => void; ``` Defined in: [video-view/VideoViewProps.ts:67](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L67) Enter picture in picture mode #### Returns `void` *** ### exitFullscreen ```ts exitFullscreen: () => void; ``` Defined in: [video-view/VideoViewProps.ts:63](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L63) Exit fullscreen mode #### Returns `void` *** ### exitPictureInPicture ```ts exitPictureInPicture: () => void; ``` Defined in: [video-view/VideoViewProps.ts:71](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoViewProps.ts#L71) Exit picture in picture mode #### Returns `void` --- ## Interface: WebVideoPlayer # Interface: WebVideoPlayer Defined in: [types/WebVideoPlayer.ts:20](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L20) **`Experimental`** Extended VideoPlayer interface with web-only methods. Use this type when you need access to audio/video track APIs on web. Audio/video tracks have ~16% browser support (Safari only, behind flags in Chrome/Firefox). These methods return empty arrays on unsupported browsers. ## Example ```ts import { useVideoPlayer, type WebVideoPlayer } from 'react-native-video'; const player = useVideoPlayer(source) as WebVideoPlayer; const audioTracks = player.getAvailableAudioTracks(); ``` ## Extends - `VideoPlayerBase` ## Properties ### currentTime ```ts currentTime: number; ``` Defined in: [types/VideoPlayerBase.ts:44](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L44) **`Experimental`** The duration of the video in seconds (1.0 = 1 sec). Returns NaN if the duration is not available. #### Inherited from ```ts VideoPlayerBase.currentTime ``` *** ### disableAudioSessionManagement ```ts disableAudioSessionManagement: boolean; ``` Defined in: [types/VideoPlayerBase.ts:113](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L113) **`Experimental`** Disables the internal audio session management for this player. When disabled, react-native-video will not configure or activate the AVAudioSession, allowing other libraries (like audio recording libraries) to manage it. #### Default ```ts false ``` #### Platform iOS #### Inherited from ```ts VideoPlayerBase.disableAudioSessionManagement ``` *** ### duration ```ts readonly duration: number; ``` Defined in: [types/VideoPlayerBase.ts:32](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L32) **`Experimental`** The current time of the video in seconds (1.0 = 1 sec). Returns NaN if the current time is not available. #### Inherited from ```ts VideoPlayerBase.duration ``` *** ### ignoreSilentSwitchMode ```ts ignoreSilentSwitchMode: IgnoreSilentSwitchMode; ``` Defined in: [types/VideoPlayerBase.ts:82](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L82) **`Experimental`** Controls the silent switch mode of the player. #### Note This is only supported on iOS. - `auto` - uses default behavior for player. - `ignore` - ignore the silent switch. - `obey` - obey the silent switch. #### Inherited from ```ts VideoPlayerBase.ignoreSilentSwitchMode ``` *** ### isPlaying ```ts readonly isPlaying: boolean; ``` Defined in: [types/VideoPlayerBase.ts:120](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L120) **`Experimental`** Whether the player is playing. #### Note This is a read-only property. #### Note To pause/resume the player, you need to use [play](#play) and [pause](#pause) methods. #### Inherited from ```ts VideoPlayerBase.isPlaying ``` *** ### loop ```ts loop: boolean; ``` Defined in: [types/VideoPlayerBase.ts:54](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L54) **`Experimental`** Whether the player is looped. #### Inherited from ```ts VideoPlayerBase.loop ``` *** ### mixAudioMode ```ts mixAudioMode: MixAudioMode; ``` Defined in: [types/VideoPlayerBase.ts:72](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L72) **`Experimental`** Controls the audio mixing mode of the player. - `mixWithOthers` - Mix with other players. - `doNotMix` - Do not mix with other players. - `duckOthers` - Duck other players. - `auto` - uses default behavior for player. default is `auto`. #### Inherited from ```ts VideoPlayerBase.mixAudioMode ``` *** ### muted ```ts muted: boolean; ``` Defined in: [types/VideoPlayerBase.ts:49](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L49) **`Experimental`** Whether the player is muted. #### Inherited from ```ts VideoPlayerBase.muted ``` *** ### playInBackground ```ts playInBackground: boolean; ``` Defined in: [types/VideoPlayerBase.ts:92](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L92) **`Experimental`** Whether the player should play in background. - `true` - play in background. - `false` - pause in background (default). #### Note this can override [playWhenInactive](#playwheninactive). #### Inherited from ```ts VideoPlayerBase.playInBackground ``` *** ### playWhenInactive ```ts playWhenInactive: boolean; ``` Defined in: [types/VideoPlayerBase.ts:103](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L103) **`Experimental`** Whether the player should play when the app is inactive (user opened control center). - `true` - play when the app is inactive. - `false` - pause when the app is inactive (default). #### Note this can be overridden by [playInBackground](#playinbackground). #### Note This is only supported on iOS. #### Inherited from ```ts VideoPlayerBase.playWhenInactive ``` *** ### rate ```ts rate: number; ``` Defined in: [types/VideoPlayerBase.ts:60](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L60) **`Experimental`** Controls the speed at which the player should play. #### Note if rate is = 0, it will pause video. #### Inherited from ```ts VideoPlayerBase.rate ``` *** ### selectedAudioTrack? ```ts readonly optional selectedAudioTrack?: AudioTrack; ``` Defined in: [types/WebVideoPlayer.ts:23](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L23) **`Experimental`** *** ### selectedTrack? ```ts readonly optional selectedTrack?: TextTrack; ``` Defined in: [types/VideoPlayerBase.ts:186](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L186) **`Experimental`** Get the currently selected text track. #### Returns The currently selected text track, or undefined if none is selected #### Inherited from ```ts VideoPlayerBase.selectedTrack ``` *** ### selectedVideoTrack? ```ts readonly optional selectedVideoTrack?: VideoTrack; ``` Defined in: [types/WebVideoPlayer.ts:27](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L27) **`Experimental`** *** ### showNotificationControls ```ts showNotificationControls: boolean; ``` Defined in: [types/VideoPlayerBase.ts:191](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L191) **`Experimental`** Whether to show notification controls (lock screen / control center). #### Inherited from ```ts VideoPlayerBase.showNotificationControls ``` *** ### source ```ts readonly source: VideoPlayerSourceBase; ``` Defined in: [types/VideoPlayerBase.ts:17](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L17) **`Experimental`** The source of the video. Source is immutable. To change the source, you need to call [replaceSourceAsync](#replacesourceasync) method. see VideoPlayerSourceBase #### Inherited from ```ts VideoPlayerBase.source ``` *** ### status ```ts readonly status: VideoPlayerStatus; ``` Defined in: [types/VideoPlayerBase.ts:26](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L26) **`Experimental`** The status of the player. #### Param The player is idle (source is not loaded) #### Param The player is loading. #### Param The player is ready to play (source is loaded). #### Param The player has an error. #### Inherited from ```ts VideoPlayerBase.status ``` *** ### volume ```ts volume: number; ``` Defined in: [types/VideoPlayerBase.ts:38](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L38) **`Experimental`** The volume of the video (0.0 = 0%, 1.0 = 100%). #### Note If the player is [muted](#muted), the volume will be 0.0. #### Inherited from ```ts VideoPlayerBase.volume ``` ## Methods ### addEventListener() ```ts addEventListener(event, callback): ListenerSubscription; ``` Defined in: [types/VideoPlayerBase.ts:198](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L198) **`Experimental`** #### Type Parameters | Type Parameter | | ------ | | `Event` *extends* keyof VideoPlayerEvents \| `"onError"` | #### Parameters | Parameter | Type | | ------ | ------ | | `event` | `Event` | | `callback` | [`AllPlayerEvents`](../type-aliases/AllPlayerEvents.md)\[`Event`\] | #### Returns `ListenerSubscription` #### Inherited from ```ts VideoPlayerBase.addEventListener ``` *** ### getAvailableAudioTracks() ```ts getAvailableAudioTracks(): AudioTrack[]; ``` Defined in: [types/WebVideoPlayer.ts:21](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L21) **`Experimental`** #### Returns [`AudioTrack`](AudioTrack.md)[] *** ### getAvailableTextTracks() ```ts getAvailableTextTracks(): TextTrack[]; ``` Defined in: [types/VideoPlayerBase.ts:174](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L174) **`Experimental`** Get all available text tracks for the current source. #### Returns [`TextTrack`](TextTrack.md)[] Array of available text tracks #### Inherited from ```ts VideoPlayerBase.getAvailableTextTracks ``` *** ### getAvailableVideoTracks() ```ts getAvailableVideoTracks(): VideoTrack[]; ``` Defined in: [types/WebVideoPlayer.ts:25](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L25) **`Experimental`** #### Returns [`VideoTrack`](VideoTrack.md)[] *** ### initialize() ```ts initialize(): Promise; ``` Defined in: [types/VideoPlayerBase.ts:125](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L125) **`Experimental`** Manually initialize the player. You don't need to call this method manually, unless you set `initializeOnCreation` to false in [VideoConfig](../type-aliases/VideoConfig.md) #### Returns `Promise`\ #### Inherited from ```ts VideoPlayerBase.initialize ``` *** ### pause() ```ts pause(): void; ``` Defined in: [types/VideoPlayerBase.ts:142](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L142) **`Experimental`** Pause playback of player. #### Returns `void` #### Inherited from ```ts VideoPlayerBase.pause ``` *** ### play() ```ts play(): void; ``` Defined in: [types/VideoPlayerBase.ts:137](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L137) **`Experimental`** Start playback of player. #### Returns `void` #### Inherited from ```ts VideoPlayerBase.play ``` *** ### preload() ```ts preload(): Promise; ``` Defined in: [types/VideoPlayerBase.ts:132](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L132) **`Experimental`** Preload the video. This is useful to avoid delay when the user plays the video. Preloading too many videos can lead to memory issues or performance issues. #### Returns `Promise`\ #### Inherited from ```ts VideoPlayerBase.preload ``` *** ### release() ```ts release(): void; ``` Defined in: [types/VideoPlayerBase.ts:196](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L196) **`Experimental`** Releases the player's resources. After calling this, the player is no longer usable. #### Returns `void` #### Inherited from ```ts VideoPlayerBase.release ``` *** ### replaceSourceAsync() ```ts replaceSourceAsync(source): Promise; ``` Defined in: [types/VideoPlayerBase.ts:166](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L166) **`Experimental`** Replace the current source of the player. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `source` | \| [`VideoSource`](../type-aliases/VideoSource.md) \| [`VideoConfig`](../type-aliases/VideoConfig.md) \| `VideoPlayerSourceBase` \| `null` | The new source of the video. | #### Returns `Promise`\ #### Note If you want to clear the source, you can pass null. see VideoPlayerSourceBase #### Inherited from ```ts VideoPlayerBase.replaceSourceAsync ``` *** ### seekBy() ```ts seekBy(time): void; ``` Defined in: [types/VideoPlayerBase.ts:150](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L150) **`Experimental`** Seek by given time. If the time is negative, it will seek backward. time will be clamped if it is out of range (0 ~ [duration](#duration)). #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `time` | `number` | The time to seek from current time in seconds. | #### Returns `void` #### Inherited from ```ts VideoPlayerBase.seekBy ``` *** ### seekTo() ```ts seekTo(time): void; ``` Defined in: [types/VideoPlayerBase.ts:158](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L158) **`Experimental`** Seek to a specific time in the video. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `time` | `number` | The time to seek to in seconds. | #### Returns `void` #### Note This have same effect as [currentTime](#currenttime) setter. #### Note time will be clamped if it is out of range (0 ~ [duration](#duration)). #### Inherited from ```ts VideoPlayerBase.seekTo ``` *** ### selectAudioTrack() ```ts selectAudioTrack(track): void; ``` Defined in: [types/WebVideoPlayer.ts:22](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L22) **`Experimental`** #### Parameters | Parameter | Type | | ------ | ------ | | `track` | [`AudioTrack`](AudioTrack.md) \| `null` | #### Returns `void` *** ### selectTextTrack() ```ts selectTextTrack(textTrack): void; ``` Defined in: [types/VideoPlayerBase.ts:180](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerBase.ts#L180) **`Experimental`** Select a text track to display. #### Parameters | Parameter | Type | Description | | ------ | ------ | ------ | | `textTrack` | [`TextTrack`](TextTrack.md) \| `null` | Text track to select, or null to unselect current track | #### Returns `void` #### Inherited from ```ts VideoPlayerBase.selectTextTrack ``` *** ### selectVideoTrack() ```ts selectVideoTrack(track): void; ``` Defined in: [types/WebVideoPlayer.ts:26](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/WebVideoPlayer.ts#L26) **`Experimental`** #### Parameters | Parameter | Type | | ------ | ------ | | `track` | [`VideoTrack`](VideoTrack.md) \| `null` | #### Returns `void` --- ## Interface: onLoadData # Interface: onLoadData Defined in: [types/Events.ts:152](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L152) ## Properties ### currentTime ```ts currentTime: number; ``` Defined in: [types/Events.ts:156](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L156) The current time of the video in seconds. *** ### duration ```ts duration: number; ``` Defined in: [types/Events.ts:161](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L161) The duration of the video in seconds. #### Note NaN if the duration is unknown. *** ### height ```ts height: number; ``` Defined in: [types/Events.ts:165](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L165) The height of the video in pixels. *** ### orientation ```ts orientation: VideoOrientation; ``` Defined in: [types/Events.ts:173](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L173) The orientation of the video. *** ### width ```ts width: number; ``` Defined in: [types/Events.ts:169](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L169) The width of the video in pixels. --- ## Interface: onLoadStartData # Interface: onLoadStartData Defined in: [types/Events.ts:178](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L178) ## Properties ### source ```ts source: VideoPlayerSourceBase; ``` Defined in: [types/Events.ts:187](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L187) The source of the video. *** ### sourceType ```ts sourceType: SourceType; ``` Defined in: [types/Events.ts:183](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L183) The type of the source. #### Note `local` for local files, `network` for network sources. --- ## Interface: onPlaybackStateChangeData # Interface: onPlaybackStateChangeData Defined in: [types/Events.ts:190](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L190) ## Properties ### isBuffering ```ts isBuffering: boolean; ``` Defined in: [types/Events.ts:198](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L198) Whether the video is buffering. *** ### isPlaying ```ts isPlaying: boolean; ``` Defined in: [types/Events.ts:194](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L194) Whether the video is playing. --- ## Interface: onProgressData # Interface: onProgressData Defined in: [types/Events.ts:201](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L201) ## Properties ### bufferDuration ```ts bufferDuration: number; ``` Defined in: [types/Events.ts:209](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L209) The time that player is able to play with only buffer. *** ### currentTime ```ts currentTime: number; ``` Defined in: [types/Events.ts:205](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L205) The current time of the video in seconds. --- ## Interface: onVolumeChangeData # Interface: onVolumeChangeData Defined in: [types/Events.ts:224](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L224) ## Properties ### muted ```ts muted: boolean; ``` Defined in: [types/Events.ts:232](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L232) Whether the player is muted. *** ### volume ```ts volume: number; ``` Defined in: [types/Events.ts:228](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L228) The volume of the player (0.0 = 0%, 1.0 = 100%). --- ## Type Alias: AllPlayerEvents # Type Alias: AllPlayerEvents ```ts type AllPlayerEvents = VideoPlayerEvents & JSVideoPlayerEvents; ``` Defined in: [types/Events.ts:104](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L104) --- ## Type Alias: IgnoreSilentSwitchMode # Type Alias: IgnoreSilentSwitchMode ```ts type IgnoreSilentSwitchMode = "auto" | "ignore" | "obey"; ``` Defined in: [types/IgnoreSilentSwitchMode.ts:1](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/IgnoreSilentSwitchMode.ts#L1) --- ## Type Alias: LibraryError # Type Alias: LibraryError ```ts type LibraryError = "library/deallocated" | "library/application-context-not-found"; ``` Defined in: [types/VideoError.ts:1](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L1) --- ## Type Alias: MixAudioMode # Type Alias: MixAudioMode ```ts type MixAudioMode = "mixWithOthers" | "doNotMix" | "duckOthers" | "auto"; ``` Defined in: [types/MixAudioMode.ts:1](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/MixAudioMode.ts#L1) --- ## Type Alias: PlayerError # Type Alias: PlayerError ```ts type PlayerError = | "player/released" | "player/not-initialized" | "player/asset-not-initialized" | "player/invalid-source"; ``` Defined in: [types/VideoError.ts:5](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L5) --- ## Type Alias: ResizeMode # Type Alias: ResizeMode ```ts type ResizeMode = "contain" | "cover" | "stretch" | "none"; ``` Defined in: [types/ResizeMode.ts:9](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/ResizeMode.ts#L9) Video resize modes that determine how video content is resized to fit the view - 'contain': Scale the video uniformly (maintain aspect ratio) so that it fits entirely within the view - 'cover': Scale the video uniformly (maintain aspect ratio) so that it fills the entire view (may crop) - 'stretch': Scale the video to fill the entire view without maintaining aspect ratio - 'none': Do not resize the video - it will fallback to default behavior (contain) --- ## Type Alias: SourceError # Type Alias: SourceError ```ts type SourceError = | "source/invalid-uri" | "source/missing-read-file-permission" | "source/file-does-not-exist" | "source/failed-to-initialize-asset" | "source/unsupported-content-type"; ``` Defined in: [types/VideoError.ts:11](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L11) --- ## Type Alias: SourceType # Type Alias: SourceType ```ts type SourceType = "local" | "network"; ``` Defined in: [types/Events.ts:176](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L176) --- ## Type Alias: TimedMetadataObject # Type Alias: TimedMetadataObject ```ts type TimedMetadataObject = object; ``` Defined in: [types/Events.ts:212](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L212) ## Properties ### identifier ```ts identifier: string; ``` Defined in: [types/Events.ts:214](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L214) *** ### value ```ts value: string; ``` Defined in: [types/Events.ts:213](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L213) --- ## Type Alias: UnknownError # Type Alias: UnknownError ```ts type UnknownError = "unknown/unknown"; ``` Defined in: [types/VideoError.ts:29](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L29) --- ## Type Alias: VideoConfig # Type Alias: VideoConfig ```ts type VideoConfig = object; ``` Defined in: [types/VideoConfig.ts:6](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L6) ## Properties ### bufferConfig? ```ts optional bufferConfig?: BufferConfig; ``` Defined in: [types/VideoConfig.ts:28](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L28) The player buffer configuration. *** ### drm? ```ts optional drm?: DrmParams; ``` Defined in: [types/VideoConfig.ts:24](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L24) The DRM parameters to be used. *** ### externalSubtitles? ```ts optional externalSubtitles?: ExternalSubtitle[]; ``` Defined in: [types/VideoConfig.ts:56](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L56) The external subtitles to be used. #### Note on iOS, only WebVTT (.vtt) subtitles are supported (for HLS streams and MP4 files). #### Note on iOS, `label` can be overridden by player and there is no way to get around it. #### Example ```ts externalSubtitles: [ { uri: 'https://example.com/subtitles_en.vtt', label: 'English', type: 'vtt', language: 'en' }, { uri: 'https://example.com/subtitles_es.vtt', label: 'Español', type: 'vtt', language: 'es' } ] ``` *** ### headers? ```ts optional headers?: Record; ``` Defined in: [types/VideoConfig.ts:20](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L20) The headers to be sent with the request. *** ### initializeOnCreation? ```ts optional initializeOnCreation?: boolean; ``` Defined in: [types/VideoConfig.ts:63](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L63) when the player is created, this flag will determine if native player should be initialized immediately. If set to true, the player will be initialized as soon as player is created If set to false, the player will need be initialized manually later #### Default ```ts true ``` *** ### metadata? ```ts optional metadata?: CustomVideoMetadata; ``` Defined in: [types/VideoConfig.ts:33](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L33) The custom metadata to be associated with the video. This metadata can be used by the native player to show information about the video. *** ### uri ```ts uri: VideoSource; ``` Defined in: [types/VideoConfig.ts:16](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L16) The uri of the video. #### Example ```ts uri: 'https://example.com/video.mp4' // or uri: require('./assets/video.mp4') ``` --- ## Type Alias: VideoErrorCode # Type Alias: VideoErrorCode ```ts type VideoErrorCode = | LibraryError | PlayerError | SourceError | VideoViewError | WebError | UnknownError; ``` Defined in: [types/VideoError.ts:31](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L31) --- ## Type Alias: VideoPlayerStatus # Type Alias: VideoPlayerStatus ```ts type VideoPlayerStatus = "idle" | "loading" | "readyToPlay" | "error"; ``` Defined in: [types/VideoPlayerStatus.ts:8](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoPlayerStatus.ts#L8) The status of the player. ## Param The player is idle (source is not loaded) ## Param The player is loading (source is loading). ## Param The player is ready to play (source is loaded). ## Param The player has an error (source is not loaded). --- ## Type Alias: VideoSource # Type Alias: VideoSource ```ts type VideoSource = number | string; ``` Defined in: [types/VideoConfig.ts:4](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoConfig.ts#L4) --- ## Type Alias: VideoViewError # Type Alias: VideoViewError ```ts type VideoViewError = | "view/not-found" | "view/deallocated" | "view/picture-in-picture-not-supported"; ``` Defined in: [types/VideoError.ts:18](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L18) --- ## Type Alias: WebError # Type Alias: WebError ```ts type WebError = "web/aborted" | "web/network" | "web/decode" | "web/unsupported-source"; ``` Defined in: [types/VideoError.ts:23](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/VideoError.ts#L23) --- ## Variable: ALL\_PLAYER\_EVENTS # Variable: ALL\_PLAYER\_EVENTS ```ts const ALL_PLAYER_EVENTS: keyof AllPlayerEvents[]; ``` Defined in: [types/Events.ts:250](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L250) --- ## Variable: ALL\_VIEW\_EVENTS # Variable: ALL\_VIEW\_EVENTS ```ts const ALL_VIEW_EVENTS: keyof VideoViewEvents[]; ``` Defined in: [types/Events.ts:274](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/types/Events.ts#L274) --- ## Variable: VideoView # Variable: VideoView ```ts VideoView: MemoExoticComponent>>; ``` Defined in: [video-view/VideoView.tsx:323](https://github.com/TheWidlarzGroup/react-native-video/blob/3faf42c2a695990d24c8c89de79d7949bea4436d/packages/react-native-video/src/core/video-view/VideoView.tsx#L323) --- ## llms.txt # llms.txt [`llms.txt`](https://llmstxt.org) is a standard for exposing documentation to AI in a clean, plain-text form: a curated index of the docs (titles, links, descriptions) plus a full-text bundle. Think `robots.txt`, but for LLMs. We generate these on **every build**, so they always match the current docs. The main file (current v7 docs): ``` https://docs.thewidlarzgroup.com/react-native-video/llms.txt ``` Full-text and version-specific variants are in [Files we publish](#files-we-publish) below. ## How it's actually used Not by pasting it into a chat. In practice llms.txt is a **Business-to-Agent** format, and the real consumers are **coding agents**: - **Your coding agent fetches it on demand.** Point Cursor, Claude Code, GitHub Copilot, Windsurf, Cline, or Aider at the URL (via Cursor's **@Docs**, or by listing it in a rules file like `.cursor/rules/…`, `CLAUDE.md`, or `AGENTS.md`), and the agent pulls `llms.txt` when it's relevant and follows the links it needs. It's URL-based: no copy-paste, no token bloat. - **Context7 (MCP) already has our docs.** react-native-video is indexed on [Context7](https://context7.com), including the v7 documentation. With the Context7 MCP configured, just add **`use context7`** to your prompt and your assistant gets up-to-date, version-specific react-native-video docs injected automatically, so you never touch a `.txt` file. - **The skill is the turnkey version.** [Install the skill](./skills.mdx) and you get all of the above wrapped with automatic version detection. Nothing to wire up. - **Plain chat? Paste as a fallback.** In a chat that can't fetch URLs (a basic ChatGPT/Claude window), paste `llms-full.txt`. Note: general web-crawling models don't reliably auto-load llms.txt, so treat this as a fallback, not the main path. :::note Honest take IDE and coding agents use llms.txt today; the big web-search LLMs mostly don't yet, and it isn't an SEO trick. We publish it for the coding-agent workflow above. ::: ## Files we publish Served from the docs root. **Point your agent at `llms.txt`**; the rest are variants for specific needs. | File | What it is | |------|-----------| | [`llms.txt`](https://docs.thewidlarzgroup.com/react-native-video/llms.txt) | **The one to link.** Curated index of the current (v7) docs (titles, descriptions, links); the generated API reference is left out for signal. | | [`llms-full.txt`](https://docs.thewidlarzgroup.com/react-native-video/llms-full.txt) | The same curated docs as **one full-text file** for a single paste into a large-context chat. | | [`llms-v7.txt`](https://docs.thewidlarzgroup.com/react-native-video/llms-v7.txt) / [`llms-v7-full.txt`](https://docs.thewidlarzgroup.com/react-native-video/llms-v7-full.txt) | v7 **including the full API reference** (bigger and noisier; use when you need exact TypeScript signatures). | | [`llms-v6.txt`](https://docs.thewidlarzgroup.com/react-native-video/llms-v6.txt) / [`llms-v6-full.txt`](https://docs.thewidlarzgroup.com/react-native-video/llms-v6-full.txt) | Legacy v6 index / full text. | ## Set it up - **Cursor** - add the URL to Cursor's indexed docs (**Settings → Indexing & Docs**, or `@Docs → Add new doc` in the chat; see [Cursor's docs](https://cursor.com/docs/context/@-symbols/@-docs)), or list it in a `.cursor/rules/*.md` file. - **Claude Code / Codex** - add the URL to `CLAUDE.md` / `AGENTS.md`, or just [install the skill](./skills.mdx). - **Copilot / Windsurf / Cline / Aider** - reference the URL in the tool's rules or context file. - **Context7** - with the MCP set up, add `use context7` to your prompt; it resolves react-native-video automatically. - **Plain chat (fallback)** - paste `llms-full.txt`. ## Which file? - **Link one URL:** `llms.txt` (current v7, curated). - **Need exact API signatures:** `llms-v7.txt` / `llms-v7-full.txt`. - **App is on v6:** `llms-v6.txt` / `llms-v6-full.txt`. (Check `package.json` → `react-native-video`: `7.x` incl. `7.0.0-beta.x` is v7; `6.x` is v6.) - **Want zero setup:** [install the skill](./skills.mdx), with version detection and routing built in. --- ## Build with AI # Build with AI AI assistants are great at React Native, right up until they guess at react-native-video. The library has **two very different APIs** (v6's `` component and v7's `useVideoPlayer` + `VideoView` player model), and an assistant with no context will happily mix them, invent props, or reach for a `drm` prop that only exists in one of them. The fix is simple: **give your assistant the right context.** This page shows the three ways to do that, from "drop-in for agents" to "paste into a chat," and points you to the deep-dive pages. ## Give your AI context Pick the option that matches your tool. You can combine them. ### 1. Install the skill (best for coding agents) Our agent skill teaches the assistant to detect your installed version first, then use the matching API, plus DRM, offline, PiP, background audio, native setup, and v6→v7 migration. **One command installs it for every agent you use** (Claude Code, Cursor, Codex, Copilot, Windsurf, Gemini, VS Code, and dozens more): ```sh npx skills add TheWidlarzGroup/react-native-video ``` No per-tool config. The [skills.sh](https://skills.sh) CLI writes the skill into each agent's directory for you. → Full details on the **[Skills](./skills.mdx)** page. ### 2. Point your coding agent at `llms.txt` (or Context7) This is how llms.txt is actually used: give the URL to your agent and it fetches on demand. Add it to Cursor's **@Docs**, or list it in a rules file (`.cursor/rules/…`, `CLAUDE.md`) for Claude Code, Copilot, Windsurf, Cline, or Aider. It's all URL-based, so no copy-paste and no token bloat. ``` https://docs.thewidlarzgroup.com/react-native-video/llms.txt ``` Already using **[Context7](https://context7.com)**? react-native-video is indexed there, so just add `use context7` to your prompt and up-to-date docs are injected automatically. → Every file and how to wire it up on the **[llms.txt](./llms-txt.mdx)** page. ### 3. Paste the docs (quick fallback for plain chat) No integration? In a plain ChatGPT, Claude, or Gemini window, paste a `llms.txt` file before you ask your question. Fastest way to unblock a one-off. ## Set up your tool **Claude Code** - Install the skill (option 1); it activates automatically when your prompt mentions react-native-video, `useVideoPlayer`, `VideoView`, and friends. To pin context for a whole project, add the `llms.txt` URL to your `CLAUDE.md`. **Cursor** - Install the skill (option 1), or add the `llms.txt` URL to Cursor's indexed docs (**Settings → Indexing & Docs**, or `@Docs → Add new doc` in the chat; the exact spot moves between versions, so see [Cursor's docs](https://cursor.com/docs/context/@-symbols/@-docs)). Version-proof alternative: list the URL in a `.cursor/rules/*.md` file. **Context7 (MCP)** - Add `use context7` to your prompt. react-native-video is already indexed, so current, version-specific docs are injected automatically. **ChatGPT / Claude.ai / Gemini** - The fallback for plain chat: paste a `llms.txt` file (option 3). For a persistent setup, add the `llms.txt` URL to a Project's custom instructions or knowledge. **Codex, Copilot, Windsurf, Gemini, VS Code, and more** - Install the skill (option 1). The same `npx skills add` command sets it up for each. One command covers dozens of agents. **Anything else** - Reference the `llms.txt` URL in whatever context or rules file your tool supports. ## Why version context matters react-native-video v6 and v7 are **not** the same API: - **v6**: one imperative component (``), controlled through props and a `ref`. - **v7**: a player object (`const player = useVideoPlayer(source)`) rendered with ``, controlled through the player instance. An assistant that doesn't know which one you're on will produce code that simply doesn't exist in your version. The skill solves this by detecting your version first; the `llms.txt` files are version-labelled so you can point the assistant at exactly v6 or v7. When in doubt, tell your assistant which major version you use. ## Example prompts With the skill installed (or `llms.txt` loaded), paste any of these to get going: ```text Build a video player screen with react-native-video v7 (useVideoPlayer + VideoView) that plays an HLS stream, shows native controls, and pauses when the screen loses focus. ``` ```text Migrate this v6 component to the v7 useVideoPlayer + VideoView API. ``` ```text Add Picture-in-Picture and fullscreen support to my VideoView in react-native-video v7. ``` ```text Set up Widevine (Android) and FairPlay (iOS) DRM playback with react-native-video v7. ``` ## What's next We're exploring more ways to make react-native-video first-class for AI workflows, starting with an **MCP server**. Have a request, or a setup that works well for you? Tell us in **[GitHub Discussions](https://github.com/TheWidlarzGroup/react-native-video/discussions)**. --- ## Skills # Skills An **agent skill** is a reusable instruction set: a `SKILL.md` file your AI assistant loads automatically when it's relevant. Ours teaches your assistant to use react-native-video *correctly*, across **both v6 and v7**. `SKILL.md` is an open standard supported natively by Claude Code, Codex, Cursor, GitHub Copilot, and VS Code, among others. Ours is distributed through [skills.sh](https://skills.sh), Vercel Labs' open skills registry, so **one command installs it into every agent you have**, no per-tool setup. ## Install ```sh npx skills add TheWidlarzGroup/react-native-video ``` That's the whole setup. The `npx skills` CLI **auto-detects the coding agents on your machine** and writes the skill into each one's skills directory (`.claude/skills/`, `.cursor/`, and so on). If it can't detect any, it asks which to install to. No config, no API keys, no pasting into rules files. ## What it does ### Detects your version first The most common AI mistake with this library is mixing v6 and v7. The skill checks your installed version **before** giving any API advice, then uses the matching model, never handing a v7 user a `` example or telling a v6 user to call `useVideoPlayer`. ### Activates on Playing or controlling video/audio, the v6 `Video` component or the v7 `useVideoPlayer` / `VideoView` API, source / props / events (`onLoad`, `onProgress`, `onEnd`, `paused`, `resizeMode`, `drm`), HLS/DASH, DRM (Widevine / FairPlay, `@react-native-video/drm`), captions & tracks, Picture-in-Picture, background / lockscreen audio, fullscreen, buffering, offline / downloading, native iOS/Android setup, and deciding between v6 and v7 or migrating between them. Trigger words include `react-native-video`, `RNV`, `Video`, `useVideoPlayer`, `VideoView`. ### Covers - **Version choice & migration** - an honest v6-vs-v7 decision guide and a v6→v7 migration path. - **Correct API per version** - component model (v6) vs player model (v7): setup, playback control, events. - **Hard topics** - DRM, tracks/subtitles, PiP, fullscreen, background audio, offline, video feeds. - **Native setup & troubleshooting** - install, streaming, background modes, and a troubleshooting reference. ### Output you can trust API claims are **verified against the library source and docs**, not guessed. The skill presents v7's beta status honestly (it's beta, but ships in production apps with 1M+ users) and points to TheWidlarzGroup add-ons only when the open-source core genuinely can't do the job, helpfully and never salesy. ## Compatibility The same `npx skills add` command works across the open skills ecosystem, covering **dozens of agents**, including: Claude Code · Cursor · Codex · GitHub Copilot · Windsurf · Gemini CLI · Amp · Antigravity · Goose · Kilo · Kiro CLI · OpenCode · Roo · Trae · Droid · VS Code, and many more. If your agent supports the `SKILL.md` standard, this skill works in it. ## Learn more - Skill source & `SKILL.md`: [`skills/react-native-video`](https://github.com/TheWidlarzGroup/react-native-video/tree/master/skills/react-native-video) - Prefer plain context instead of a skill? See **[llms.txt](./llms-txt.mdx)**. --- ## Configuration with Expo # Expo Plugin The `react-native-video` library provides an Expo plugin to simplify the integration and configuration of specific features into your Expo project. ## Installation To use the Expo plugin, you need to add it to your app's configuration file (`app.json` or `app.config.js`). ```json title="app.json" { "expo": { "plugins": [ [ "react-native-video", { "enableAndroidPictureInPicture": true, "enableBackgroundAudio": true, "androidExtensions": { "useExoplayerDash": true, "useExoplayerHls": true } } ] ] } } ``` ```javascript title="app.config.js" export default { plugins: [ [ 'react-native-video', { enableAndroidPictureInPicture: true, enableBackgroundAudio: true, androidExtensions: { useExoplayerDash: true, useExoplayerHls: true, }, }, ], ], }; ``` ## Configuration Options The plugin accepts an optional configuration object with the following properties: ### `enableAndroidPictureInPicture` (optional) - **Type:** `boolean` - **Default:** `false` - **Description:** Enables Picture-in-Picture (PiP) mode on Android. This will apply the necessary configurations to your Android project. ### `enableBackgroundAudio` (optional) - **Type:** `boolean` - **Default:** `false` - **Description:** Enables audio playback to continue when the app is in the background on Android. Ensure you have also configured the necessary background modes capabilities in your app if required by the operating system. ### `androidExtensions` (optional) - **Type:** `object` - **Default:** `{ useExoplayerDash: true, useExoplayerHls: true }` - **Description:** Allows you to specify which Android ExoPlayer extensions to include. This can help reduce the size of your app by only including the extensions you need. - `useExoplayerDash` (boolean, default: `true`): Whether to include ExoPlayer's Dash extension. - `useExoplayerHls` (boolean, default: `true`): Whether to include ExoPlayer's HLS extension. ### `reactNativeTestApp` (optional) - **Type:** `boolean` - **Default:** `false` - **Description:** Whether to use `react-native-test-app` compatible mode. ## Usage Once configured in your `app.json` or `app.config.js`, the plugin will automatically apply the necessary native project changes during the prebuild process (e.g., when running `npx expo prebuild`). No further manual setup is typically required for these features. --- ## Manual Configuration without Expo # Manual Configuration If you prefer not to use the Expo plugin you can configure **react-native-video** manually by editing the native project files directly. The steps below show the exact changes performed by the plugin so you can reproduce them in a plain React Native or bare Expo project. --- ## iOS ### Enable Background Audio To allow video sound to continue when the app goes to the background add the `audio` mode to `Info.plist`: ```xml title="ios/YourApp/Info.plist" UIBackgroundModes audio ``` ## Android ### Configure ExoPlayer extensions By default the library enables DASH & HLS extensions. You can fine-tune this by adding properties to **gradle.properties**: ```properties title="android/gradle.properties" # Enable / disable ExoPlayer extensions used by react-native-video RNVideo_useExoplayerDash=true # DASH playback support RNVideo_useExoplayerHls=true # HLS playback support ``` Set a value to `false` to exclude the corresponding extension and reduce APK size. ### Enable Picture-in-Picture (PiP) Add the `android:supportsPictureInPicture` flag to your *main* activity in **AndroidManifest.xml**: ```xml title="android/app/src/main/AndroidManifest.xml" ``` PiP requires **API 26+** (Android 8.0). Make sure `minSdkVersion` is at least `26` when enabling this feature. ## Verification After the modifications: 1. **iOS** – run `cd ios && pod install` then build the app from Xcode or via `npx react-native run-ios` / `npx expo run:ios`. 2. **Android** – clean & rebuild the project: `./gradlew clean && ./gradlew :app:assembleDebug` or simply run `npx react-native run-android` / `npx expo run:android`. If the build succeeds your manual configuration is complete. --- ### Need an easier way? Use the [Expo plugin](./with-expo.md) to apply exactly the same changes automatically during `expo prebuild`. --- ## Installation — iOS, Android, tvOS # Installation React Native Video is a library that allows you to play various kinds of video in a React Native application. It is built on top of the [`react-native-nitro-modules`](https://nitro.margelo.com/docs/what-is-nitro) framework, giving it type-safety and blazing fast communication across Native and JavaScript threads. React Native Video supports both the New Architecture and the Old Architecture. ## Requirements ### System Requirements - iOS `15.0` or higher - Android `6.0` or higher ### Minimal Package Requirements - `react-native` `0.75.0` or higher - `react-native-nitro-modules` `0.35.0` or higher ## Installation 1. Install dependencies: ```bash npm install react-native-video@next react-native-nitro-modules ``` 2. Configure Library: You can configure the library in two ways: - [With Expo](./configuration/with-expo.md) - [Without Expo](./configuration/without-expo.md) 3. Run the project: If you are using Expo, you will need to generate native files: ```bash npx expo prebuild ``` And then run the project: ```bash npx expo run:ios # run on iOS npx expo run:android # run on Android ``` If you are using React Native CLI, you will need to install Pods for iOS: ```bash cd ios && pod install && cd .. ``` And then run the project: ```bash npx react-native run-ios # run on iOS npx react-native run-android # run on Android ``` ## Patch for react-native Patch for `react-native-nitro-modules` ```diff diff --git a/node_modules/react-native-nitro-modules/cpp/core/HybridFunction.hpp b/node_modules/react-native-nitro-modules/cpp/core/HybridFunction.hpp index efcea05..ffad3f2 100644 --- a/node_modules/react-native-nitro-modules/cpp/core/HybridFunction.hpp +++ b/node_modules/react-native-nitro-modules/cpp/core/HybridFunction.hpp @@ -23,6 +23,10 @@ struct JSIConverter; #include #include +#ifdef ANDROID +#include +#endif + namespace margelo::nitro { using namespace facebook; @@ -109,6 +113,15 @@ public: std::string funcName = getHybridFuncFullName(kind, name, hybridInstance.get()); std::string message = exception.what(); throw jsi::JSError(runtime, funcName + ": " + message); +#ifdef ANDROID +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexceptions" + } catch (const jni::JniException& exception) { + std::string funcName = getHybridFuncFullName(kind, name, hybridInstance.get()); + std::string message = exception.what(); + throw jsi::JSError(runtime, funcName + ": " + message); +#pragma clang diagnostic pop +#endif } catch (...) { // Some unknown exception was thrown - add method name information and re-throw as `JSError`. std::string funcName = getHybridFuncFullName(kind, name, hybridInstance.get()); ``` see [raw](https://github.com/TheWidlarzGroup/react-native-video/blob/v7/example/patches/react-native-nitro-modules%2B0.27.2.patch) ## Usage ```tsx title="App.tsx" import { VideoView, useVideoPlayer } from 'react-native-video'; export default function App() { const player = useVideoPlayer({ source: { uri: 'https://www.w3schools.com/html/mov_bbb.mp4', }, }); return ; } ``` --- ## Introduction to React Native Video import { V7Lead, V7FeatureCards, V7ApiModel, V7NitroSection, V7StatusTimeline, V7OpenSource, V7ProPlugins, } from '@site/src/components/Intro'; # Intro React Native Video is a powerful, cross-platform video player library for React Native. Version 7 introduces a new Player API built on Nitro Modules for type-safe, high-performance native communication. It supports DRM protection (Widevine and FairPlay), a modular plugin architecture, offline video playback, and works on iOS, Android, tvOS, and visionOS with both New and Old Architecture. :::tip Building with an AI assistant? Install the **[react-native-video skill](../build-with-ai/skills.mdx)**: one command (`npx skills add TheWidlarzGroup/react-native-video`) sets up Claude Code, Cursor, Codex and more to write correct, version-aware code. See **[Build with AI](../build-with-ai/overview.mdx)** for other options. ::: ## What changed in v7 vs v6 ## New API model in practice ### New model: you control the player, the view is optional ## Why Nitro Modules? ### Nitro Modules as the foundation of v7 ## Status v7 ## Open-source + optional Pro features and services ## Pro plugins --- ## Web Support — Play Video in Browser with React Native import PlatformsList from '@site/src/components/PlatformsList/PlatformsList'; # Web Support React Native Video supports the web platform through [video.js](https://videojs.org/) (v10), providing the same `VideoPlayer` and `VideoView` API you use on iOS and Android. ## Setup Configure your project for web support: - [With Expo](https://docs.expo.dev/workflow/web/) - [Without Expo (bare React Native)](https://necolas.github.io/react-native-web/docs/multi-platform/) React Native Video handles video.js internally - no additional CSS imports or configuration needed beyond standard React Native Web setup. ## Usage The API is identical to native: ```tsx import { useVideoPlayer, VideoView } from 'react-native-video'; function Player() { const player = useVideoPlayer({ uri: 'https://example.com/video.mp4', }); return ( ); } ``` ### Web-enhanced player The web platform may offer additional features not available on native. To access them, cast the player to [`WebVideoPlayer`](../api-reference/interfaces/WebVideoPlayer): ```tsx import { useVideoPlayer, type WebVideoPlayer } from 'react-native-video'; const player = useVideoPlayer(source) as WebVideoPlayer; ``` This is optional - the standard `useVideoPlayer` works perfectly on web. The cast simply gives you typed access to extra capabilities when building web-specific features. ## How it works Web support uses the same API as native - `useVideoPlayer` for creating a player and `VideoView` for displaying video. You can use the player with or without a view: - **With `VideoView`** - displays video with optional built-in controls (powered by [video.js](https://videojs.org/)) - **Without `VideoView`** - audio-only playback ## Supported features | Feature | Status | Notes | |---------|--------|-------| | Play / Pause / Seek | ✅ | Full support | | Volume / Mute | ✅ | Full support | | Loop | ✅ | Full support | | Playback rate | ✅ | Full support | | Text tracks (subtitles) | ✅ | Including external subtitles | | Resize mode | ✅ | contain, cover, stretch, none | | Fullscreen | ✅ | Full support | | Picture-in-Picture | ✅ | Depends on browser | | Media Session | ✅ | Lock screen controls | | Preload | ✅ | Full support | | Events | ✅ | Core playback events (play/pause, buffering, errors). Some native-only events are not available on web. | | HLS streaming | ✅ | Via video.js engine | | Audio tracks | ⚠️ | Safari only (experimental in other browsers) | | Video tracks | ⚠️ | Safari only (experimental in other browsers) | | DRM | ❌ | Not yet available | | Ads | ❌ | ## Web-only features See the [WebVideoPlayer](../api-reference/interfaces/WebVideoPlayer) API reference for web-specific methods. ## Known limitations - `mixAudioMode`, `ignoreSilentSwitchMode`, `playInBackground`, `playWhenInactive` are no-ops on web - Video sources must be URLs (strings) - `require('./video.mp4')` is not supported on web - DRM and Ads are not yet supported --- ## Professional Support & Pro Plugins import { IntroHero, OfferCards, HowItWorks, Services, Extensions, DecisionTable, Contact, } from "@site/src/components/Offer"; # Offer ## What you can use Three ways to work with react-native-video, depending on your needs and timeline: ## How it works ## Services When you need guaranteed response times and direct maintainer involvement: ## Extensions Ready-to-use modules and templates for advanced use cases: ## Which option should I choose? Quick reference guide based on your situation: ## Contact Ready to discuss your project? Here's what to include: --- ## Manual Analytics with Native Plugins # Manual Analytics Integrate your own analytics system using native plugins. ## Overview Most analytics systems that track player data (e.g., bitrate, errors) can be integrated directly with ExoPlayer or AVPlayer. The [plugin system](../../plugins/plugins.mdx) allows for non-intrusive analytics integration with react-native-video. It should be implemented in native languages (Kotlin/Swift) to ensure efficiency. ## Architecture ``` ┌─────────────────────────────────────┐ │ React Native App │ │ ┌───────────────────────────────┐ │ │ │ react-native-video │ │ │ │ ┌─────────────────────────┐ │ │ │ │ │ Plugin System │ │ │ │ │ └─────────────────────────┘ │ │ │ └───────────────────────────────┘ │ └─────────────────────────────────────┘ │ │ │ onPlayerCreated │ onPlayerCreated ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Android Plugin │ │ iOS Plugin │ │ (Kotlin) │ │ (Swift) │ │ │ │ │ │ ExoPlayer │ │ AVPlayer │ │ Analytics │ │ KVO Observers │ │ Listener │ │ │ └─────────────────┘ └─────────────────┘ ``` ## Implementation ### Android (Kotlin) ```kotlin import androidx.annotation.OptIn import androidx.media3.common.Format import androidx.media3.common.PlaybackException import androidx.media3.common.Player import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.analytics.AnalyticsListener import com.twg.video.core.plugins.NativeVideoPlayer import com.twg.video.core.plugins.ReactNativeVideoPlugin import java.lang.ref.WeakReference @OptIn(UnstableApi::class) class AnalyticsPlugin : ReactNativeVideoPlugin("MyAnalytics") { override fun onPlayerCreated(player: WeakReference) { val nativePlayer = player.get() ?: return val exoPlayer = nativePlayer.player exoPlayer.addAnalyticsListener(object : AnalyticsListener { override fun onBandwidthEstimate( eventTime: AnalyticsListener.EventTime, totalLoadTimeMs: Int, totalBytesLoaded: Long, bitrateEstimate: Long ) { trackMetric("bitrate", bitrateEstimate) } override fun onDroppedVideoFrames( eventTime: AnalyticsListener.EventTime, droppedFrames: Int, elapsedMs: Long ) { trackMetric("dropped_frames", droppedFrames) } override fun onVideoInputFormatChanged( eventTime: AnalyticsListener.EventTime, format: Format, decoderReuseDecision: Int? ) { trackEvent("quality_change", mapOf( "width" to format.width, "height" to format.height, "bitrate" to format.bitrate )) } override fun onPlaybackStateChanged( eventTime: AnalyticsListener.EventTime, state: Int ) { when (state) { Player.STATE_BUFFERING -> trackEvent("buffering_start") Player.STATE_READY -> trackEvent("buffering_end") Player.STATE_ENDED -> trackEvent("playback_complete") } } override fun onPlayerError( eventTime: AnalyticsListener.EventTime, error: PlaybackException ) { trackEvent("error", mapOf( "code" to error.errorCode, "message" to error.message )) } }) } override fun onPlayerDestroyed(player: WeakReference) { flushAnalytics() } private fun trackEvent(name: String, params: Map = emptyMap()) { // Send to your analytics backend } private fun trackMetric(name: String, value: Number) { // Send to your analytics backend } private fun flushAnalytics() { // Flush pending analytics } } ``` ### iOS (Swift) ```swift import AVFoundation class AnalyticsPlugin: ReactNativeVideoPlugin { // MARK: - Properties private weak var currentPlayer: AVPlayer? private var rateObserver: NSKeyValueObservation? private var statusObserver: NSKeyValueObservation? private var timeObserver: Any? // MARK: - Init init() { super.init(name: "MyAnalytics") } // MARK: - Plugin Lifecycle override func onPlayerCreated(player: Weak) { guard let nativePlayer = player.value else { return } currentPlayer = nativePlayer.player setupPlaybackObservers(for: nativePlayer.player) setupQualityTracking(for: nativePlayer.playerItem) } override func onPlayerDestroyed(player: Weak) { removeAllObservers() flushAnalytics() } // MARK: - Setup private func setupPlaybackObservers(for player: AVPlayer) { rateObserver = player.observe(\.rate) { [weak self] p, _ in self?.trackEvent(p.rate > 0 ? "play" : "pause") } statusObserver = player.observe(\.status) { [weak self] p, _ in if p.status == .readyToPlay { self?.trackEvent("ready") } else if p.status == .failed { self?.trackEvent("error", params: ["message": p.error?.localizedDescription ?? ""]) } } timeObserver = player.addPeriodicTimeObserver( forInterval: CMTime(seconds: 10, preferredTimescale: 1), queue: .main ) { [weak self] time in self?.trackMetric("position", value: time.seconds) } } private func setupQualityTracking(for playerItem: AVPlayerItem?) { NotificationCenter.default.addObserver( self, selector: #selector(handleAccessLog), name: .AVPlayerItemNewAccessLogEntry, object: playerItem ) } @objc private func handleAccessLog(_ notification: Notification) { guard let item = notification.object as? AVPlayerItem, let event = item.accessLog()?.events.last else { return } trackMetric("bitrate", value: event.indicatedBitrate) trackMetric("stalls", value: Double(event.numberOfStalls)) trackMetric("dropped_frames", value: Double(event.numberOfDroppedVideoFrames)) } private func removeAllObservers() { if let observer = timeObserver { currentPlayer?.removeTimeObserver(observer) } rateObserver?.invalidate() statusObserver?.invalidate() NotificationCenter.default.removeObserver(self) currentPlayer = nil timeObserver = nil } // MARK: - Analytics private func trackEvent(_ name: String, params: [String: Any] = [:]) { // Send to your analytics backend } private func trackMetric(_ name: String, value: Double) { // Send to your analytics backend } private func flushAnalytics() { // Flush pending analytics } } ``` ## Available Metrics ### Android (ExoPlayer AnalyticsListener) | Event | Method | Data | |-------|--------|------| | Bitrate | `onBandwidthEstimate` | `bitrateEstimate` | | Dropped frames | `onDroppedVideoFrames` | `droppedFrames`, `elapsedMs` | | Quality change | `onVideoInputFormatChanged` | `format.width`, `format.height` | | Buffering | `onPlaybackStateChanged` | `Player.STATE_BUFFERING` | | Stall | `onStallStart` / `onStallEnd` | duration | | Seek | `onSeekStarted` / `onSeekProcessed` | position | | Error | `onPlayerError` | `errorCode`, `message` | ### iOS (AVPlayer) | Metric | Source | Property | |--------|--------|----------| | Bitrate | `accessLog` | `indicatedBitrate` | | Stalls | `accessLog` | `numberOfStalls` | | Dropped frames | `accessLog` | `numberOfDroppedVideoFrames` | | Bytes | `accessLog` | `numberOfBytesTransferred` | | Playback status | KVO | `player.status` | | Play/Pause | KVO | `player.rate` | | Buffer | `playerItem` | `isPlaybackLikelyToKeepUp` | ## Registration Plugins auto-register when instantiated. Create your plugin early in app lifecycle: **Android** - `MainApplication.kt`: ```kotlin class MainApplication : Application() { override fun onCreate() { super.onCreate() AnalyticsPlugin() // Auto-registers via init block } } ``` **iOS** - `AppDelegate.swift`: ```swift @main class AppDelegate: UIResponder, UIApplicationDelegate { private var analyticsPlugin: AnalyticsPlugin? func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { analyticsPlugin = AnalyticsPlugin() // Auto-registers via init return true } } ``` ## See Also - [Plugins](../../plugins/plugins.mdx) - Full plugin system documentation - [Plugin Interface](../../plugins/interface.md) - Complete API reference --- ## Simple Analytics with JavaScript Events # Simple Analytics The easiest way to track video analytics is by using the JavaScript events provided by `react-native-video`. This approach requires no native code and works across all platforms. ## Overview Use the `useEvent` hook to subscribe to player events. For a complete list of available events and their data, see the [Events documentation](../events.md). ## Example ```tsx import { useVideoPlayer, useEvent, VideoView } from 'react-native-video'; function VideoPlayer() { const player = useVideoPlayer('https://example.com/video.mp4'); useEvent(player, 'onLoad', (data) => { analytics.track('video_loaded', { duration: data.duration }); }); useEvent(player, 'onProgress', (data) => { analytics.track('video_progress', { currentTime: data.currentTime }); }); useEvent(player, 'onError', (error) => { analytics.track('video_error', { error: error.error }); }); useEvent(player, 'onEnd', () => { analytics.track('video_completed'); }); return ; } ``` ## When to Use **Use JS Events when:** - You need basic playback tracking (play, pause, progress, errors) - You want a quick integration without native code - Your analytics needs are straightforward **Consider [Manual Analytics](./manual.md) when:** - You need low-level metrics (bitrate, dropped frames, buffer health) - You want to integrate with native analytics SDKs - You need the most accurate and detailed data ## Tips 1. **Throttle progress events** - `onProgress` fires frequently. Consider throttling before sending to your analytics backend. 2. **Track session data** - Store a session ID to group events from the same viewing session. 3. **Include video metadata** - Add video ID, title, or other metadata to your events for better reporting. ```tsx const sessionId = useRef(uuid()).current; const handleProgress = (data) => { // Throttle to every 10 seconds if (Math.floor(data.currentTime) % 10 === 0) { analytics.track('video_progress', { sessionId, videoId: 'video-123', currentTime: data.currentTime, }); } }; ``` --- ## Download API Reference # Downloading ## Authorization ### `registerPlugin(apiKey: string): Promise` Registers and authorizes the plugin with the provided API key. Must be called before using any other functions. **Parameters:** - `apiKey`: Your API key obtained from [sdk.thewidlarzgroup.com](https://sdk.thewidlarzgroup.com?utm_source=rnv&utm_medium=docs&utm_campaign=downloading&utm_id=downloading_api-key-param) **Returns:** `Promise` - `true` if registration was successful, `false` otherwise ```tsx import { registerPlugin } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const success = await registerPlugin("YOUR_API_KEY"); ``` ### `disablePlugin(): void` Disables the plugin. After calling this, you'll need to call `registerPlugin` again to use the SDK. ```tsx import { disablePlugin } from "@TheWidlarzGroup/react-native-video-stream-downloader"; disablePlugin(); ``` ### `isRegistered(): boolean` Checks if the plugin is currently registered and authorized. **Returns:** `boolean` - `true` if registered, `false` otherwise ```tsx import { isRegistered } from "@TheWidlarzGroup/react-native-video-stream-downloader"; if (isRegistered()) { // Plugin is ready to use } ``` ## Configuration ### `setConfig(config: DownloadConfig): void` Sets global configuration for downloads. **Parameters:** - `config`: Configuration with the following properties: - `updateFrequencyMS?: number` - How often to update download progress (in milliseconds) - `maxParallelDownloads?: number` - Maximum number of simultaneous downloads ```tsx import { setConfig } from "@TheWidlarzGroup/react-native-video-stream-downloader"; setConfig({ updateFrequencyMS: 1000, maxParallelDownloads: 3, }); ``` ### `getConfig(): DownloadConfig` Gets the current global configuration. **Returns:** `DownloadConfig` with properties: - `updateFrequencyMS?: number` - `maxParallelDownloads?: number` ```tsx import { getConfig } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const config = getConfig(); ``` ## Download Management ### `downloadStream(url: string, options?: DownloadOptions): Promise` {#downloadstream} Downloads a video stream for offline playback. **Parameters:** - `url`: The URL of the video stream to download - `options`: Optional download configuration with the following properties: - `includeAllTracks?: boolean` - Whether to download all available tracks (default: `false`) - `tracks?: Track[]` - Array of specific tracks to download. Each track has: - `id: string` - Track identifier - `type: 'video' | 'audio' | 'text'` - Track type - `language?: string` - Language code (for audio/text tracks) - `expiresAt?: number` - Unix timestamp when the download should expire - `drm?: DRMConfig` - DRM configuration (see [DRM Downloading](./drm-downloading.md) for details) - `metadata?: Record` - Custom metadata to store with the download **Returns:** `Promise` - Status immediately after adding to queue (not after completion) **DownloadStatus properties:** - `id: string` - Unique download identifier - `url: string` - Source URL - `status: 'queued' | 'downloading' | 'paused' | 'completed' | 'failed' | 'cancelled'` - Current status - `progress: number` - Download progress (0-1) - `bytesDownloaded: number` - Number of bytes downloaded - `totalBytes: number` - Total bytes to download (may be `undefined` until known) ```tsx import { downloadStream } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const status = await downloadStream("https://example.com/video.m3u8", { tracks: [ { id: "video-1", type: "video" }, { id: "audio-en", type: "audio", language: "en" }, ], }); ``` ### `pauseDownload(id: string): Promise` Pauses an active download. **Parameters:** - `id`: The download identifier returned from `downloadStream` ```tsx import { pauseDownload } from "@TheWidlarzGroup/react-native-video-stream-downloader"; await pauseDownload(downloadId); ``` ### `resumeDownload(id: string): Promise` Resumes a paused download. **Parameters:** - `id`: The download identifier returned from `downloadStream` ```tsx import { resumeDownload } from "@TheWidlarzGroup/react-native-video-stream-downloader"; await resumeDownload(downloadId); ``` ### `cancelDownload(id: string): Promise` Cancels a download and removes it from the queue. Also deletes any partially downloaded files. **Parameters:** - `id`: The download identifier returned from `downloadStream` ```tsx import { cancelDownload } from "@TheWidlarzGroup/react-native-video-stream-downloader"; await cancelDownload(downloadId); ``` ### `cancelAllDownloads(): Promise` Cancels all active and queued downloads. ```tsx import { cancelAllDownloads } from "@TheWidlarzGroup/react-native-video-stream-downloader"; await cancelAllDownloads(); ``` ### `getDownloadStatus(id: string): Promise` Gets the current status of a specific download. **Parameters:** - `id`: The download identifier **Returns:** `Promise` - Current download status or `null` if not found ```tsx import { getDownloadStatus } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const status = await getDownloadStatus(downloadId); ``` ### `getDownloadsStatus(): Promise` Gets the status of all downloads (active, queued, completed, etc.). **Returns:** `Promise` - Array of all download statuses ```tsx import { getDownloadsStatus } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const allStatuses = await getDownloadsStatus(); ``` ## Track Inspection ### `getAvailableTracks(url: string): Promise` {#getavailabletracks} Retrieves information about available audio, video, and subtitle tracks in a stream. **Parameters:** - `url`: The URL of the video stream to inspect **Returns:** `Promise` with the following structure: - `video: VideoTrack[]` - Available video tracks, each with: - `id: string` - Track identifier - `width: number` - Video width in pixels - `height: number` - Video height in pixels - `bitrate: number` - Bitrate in bits per second - `audio: AudioTrack[]` - Available audio tracks, each with: - `id: string` - Track identifier - `language: string` - Language code (e.g., "en", "es") - `bitrate: number` - Bitrate in bits per second - `text: TextTrack[]` - Available subtitle tracks, each with: - `id: string` - Track identifier - `language: string` - Language code - `type: string` - Subtitle format (e.g., "text/vtt") ```tsx import { getAvailableTracks } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const tracks = await getAvailableTracks("https://example.com/video.m3u8"); // Use tracks.video, tracks.audio, tracks.text to let user select // Then pass selected tracks to downloadStream ``` For more details on track selection, see [Track Selection](./track-selection.md). ## Types ### `DownloadStatus` {#downloadstatus} Status information for a download. **Properties:** - `id: string` - Unique download identifier - `url: string` - Source URL - `status: 'queued' | 'downloading' | 'paused' | 'completed' | 'failed' | 'cancelled'` - Current status - `progress: number` - Download progress (0-1) - `bytesDownloaded: number` - Number of bytes downloaded - `totalBytes: number | undefined` - Total bytes to download (may be `undefined` until known) ### `DownloadOptions` Configuration options for `downloadStream`. **Properties:** - `includeAllTracks?: boolean` - Whether to download all available tracks (default: `false`) - `tracks?: Track[]` - Array of specific tracks to download - `expiresAt?: number` - Unix timestamp when the download should expire - `drm?: DRMConfig` - DRM configuration (see [DRM Downloading](./drm-downloading.md)) - `metadata?: Record` - Custom metadata to store with the download ### `Track` A track selection for download. **Properties:** - `id: string` - Track identifier - `type: 'video' | 'audio' | 'text'` - Track type - `language?: string` - Language code (for audio/text tracks) ### `AvailableTracks` Result from `getAvailableTracks` containing available tracks. **Properties:** - `video: VideoTrack[]` - Available video tracks - `audio: AudioTrack[]` - Available audio tracks - `text: TextTrack[]` - Available subtitle tracks ### `VideoTrack` Information about a video track. **Properties:** - `id: string` - Track identifier - `width: number` - Video width in pixels - `height: number` - Video height in pixels - `bitrate: number` - Bitrate in bits per second ### `AudioTrack` Information about an audio track. **Properties:** - `id: string` - Track identifier - `language: string` - Language code (e.g., "en", "es") - `bitrate: number` - Bitrate in bits per second ### `TextTrack` Information about a subtitle track. **Properties:** - `id: string` - Track identifier - `language: string` - Language code - `type: string` - Subtitle format (e.g., "text/vtt") ### `DownloadConfig` Global configuration for downloads. **Properties:** - `updateFrequencyMS?: number` - How often to update download progress (in milliseconds) - `maxParallelDownloads?: number` - Maximum number of simultaneous downloads ### `DRMConfig` DRM configuration for downloading protected content. **Properties:** - `licenseServer: string` - URL of the license server - `certificateUrl?: string` - Certificate URL (required for FairPlay on iOS) - `headers?: Record` - HTTP headers for license requests - `getLicense?: (spcData: ArrayBuffer) => Promise` - Custom license acquisition function (iOS only, FairPlay) --- ## DRM Offline — Widevine & FairPlay Downloads # DRM Downloading The Offline Video SDK supports downloading and playing DRM-protected content offline, including support for persistent licenses. ## Prerequisites :::warning Critical Requirement Your DRM provider **must support persistent/offline licenses**. Not all DRM providers support this feature. Contact your DRM provider to confirm offline license support before implementing. ::: To download DRM-protected content, you need: - **Encrypted media**: Video content encrypted with DRM (Widevine, FairPlay, PlayReady) - **License server**: A license server that supports **persistent/offline licenses** - **Short-lived token**: Authentication token for license acquisition (if required) ## High-level Flow 1. **Content Preparation**: Media is encrypted and packaged with DRM 2. **License Server Configuration**: License server is configured to issue persistent licenses 3. **Download with DRM Config**: Call `downloadStream` with DRM configuration 4. **License Acquisition**: SDK automatically acquires and stores persistent license 5. **Offline Playback**: Downloaded content can be played offline using the stored license ## Configuration The `drm` property in `downloadStream` accepts a `DRMConfig` with the following properties: - `licenseServer: string` - URL of the license server - `certificateUrl?: string` - Certificate URL (required for FairPlay on iOS) - `headers?: Record` - HTTP headers for license requests - `getLicense?: (spcData: ArrayBuffer) => Promise` - Custom license acquisition function (iOS only, FairPlay) See [DRMConfig](./downloading.md#drmconfig) in API Reference for complete type definition. ### Basic DRM Configuration ```tsx import { downloadStream } from "@TheWidlarzGroup/react-native-video-stream-downloader"; await downloadStream(videoUrl, { drm: { licenseServer: "https://license.example.com/acquire", headers: { "Authorization": "Bearer YOUR_TOKEN", }, }, }); ``` ### FairPlay (iOS) For FairPlay on iOS, you also need to provide the certificate URL: ```tsx await downloadStream(videoUrl, { drm: { licenseServer: "https://license.example.com/acquire", certificateUrl: "https://license.example.com/certificate.cer", headers: { "Authorization": "Bearer YOUR_TOKEN", }, }, }); ``` ### Custom License Acquisition (iOS only) On iOS, you can provide a custom license acquisition function: ```tsx await downloadStream(videoUrl, { drm: { licenseServer: "https://license.example.com/acquire", certificateUrl: "https://license.example.com/certificate.cer", getLicense: async (spcData: ArrayBuffer) => { // Custom license acquisition logic const response = await fetch("https://license.example.com/acquire", { method: "POST", headers: { "Content-Type": "application/octet-stream", "Authorization": "Bearer YOUR_TOKEN", }, body: spcData, }); return await response.arrayBuffer(); }, }, }); ``` ## Platform-Specific Notes ### Android - Supports Widevine and PlayReady - License acquisition is handled automatically by the SDK - Ensure your license server supports persistent licenses ### iOS - Supports FairPlay - Requires `certificateUrl` for FairPlay - Custom license acquisition via `getLicense` is optional but available - FairPlay configuration should match your `react-native-video` DRM setup ## Testing :::tip Always test DRM downloading on a **real device**. Simulators/emulators may not properly handle DRM operations. ::: When testing: 1. Ensure your test content is properly encrypted 2. Verify your license server supports persistent licenses 3. Test on both iOS and Android devices 4. Verify offline playback works after download completes 5. Test license expiration scenarios ## FairPlay Notes The FairPlay configuration for offline downloading should match your `react-native-video` DRM configuration exactly. Use the same: - `licenseServer` URL - `certificateUrl` - `headers` (if applicable) - `getLicense` function (if using custom acquisition) This ensures consistency between online and offline playback. --- ## Download Events — Progress & Status Tracking # Downloading Events The Offline Video SDK emits events that allow you to monitor and react to changes in download status and progress. You can subscribe to these events using the `useEvent` hook. ## Available Events ### `onError` Fired when an error occurs during download. **Callback signature:** ```tsx (error: string) => void ``` **Parameters:** - `error`: Error message describing what went wrong ```tsx import { useEvent } from "@TheWidlarzGroup/react-native-video-stream-downloader"; useEvent("onError", (error: string) => { console.error("Download error:", error); }); ``` ### `onDownloadProgress` Fired periodically during downloads with current progress information. **Callback signature:** ```tsx (downloads: DownloadStatus[]) => void ``` **Parameters:** - `downloads`: Array of `DownloadStatus` - See [DownloadStatus structure](./downloading.md#downloadstatus) in API Reference for complete properties ```tsx import { useEvent } from "@TheWidlarzGroup/react-native-video-stream-downloader"; useEvent("onDownloadProgress", (downloads: DownloadStatus[]) => { downloads.forEach((download) => { console.log(`Download ${download.id}: ${(download.progress * 100).toFixed(1)}%`); }); }); ``` ### `onDownloadEnd` Fired when a download completes (successfully or with failure). **Callback signature:** ```tsx (download: DownloadStatus) => void ``` **Parameters:** - `download`: Final `DownloadStatus` - See [DownloadStatus structure](./downloading.md#downloadstatus) in API Reference for complete properties. When this event fires, `status` will be either `'completed'` or `'failed'`. ```tsx import { useEvent } from "@TheWidlarzGroup/react-native-video-stream-downloader"; useEvent("onDownloadEnd", (download: DownloadStatus) => { if (download.status === "completed") { console.log(`Download ${download.id} completed successfully`); } else { console.log(`Download ${download.id} failed`); } }); ``` ## Using Events Events are automatically typed and can be used with the `useEvent` hook: ```tsx import { useEvent } from "@TheWidlarzGroup/react-native-video-stream-downloader"; function DownloadManager() { useEvent("onDownloadProgress", (downloads) => { // Update UI with progress }); useEvent("onDownloadEnd", (download) => { // Handle completion }); useEvent("onError", (error) => { // Handle errors }); // ... rest of component } ``` The `useEvent` hook automatically manages cleanup when the component unmounts, preventing memory leaks. --- ## Getting Started with Offline Video # Getting Started This section covers the **Offline Video SDK** - a commercial extension for `react-native-video` that enables downloading and offline playback. The Offline Video SDK is a commercial add-on for `react-native-video` (versions 6 and 7) that enables secure offline playback of HLS/DASH streams or static videos like MP4, including support for DRM, multiple audio tracks, and subtitles. ## Requirements - **React Native Video**: version 6.15.0 or higher (versions 6 and 7 are supported) - **iOS**: 15.0 or higher - **Android**: 6.0 or higher - **Api key**: A valid api key for the Offline Video SDK is required. You can obtain this through the [SDK platform](https://sdk.thewidlarzgroup.com?utm_source=rnv&utm_medium=docs&utm_campaign=downloading&utm_id=getting-started_api-key-requirement). ## Features - **HLS/DASH/MP4 Downloading**: Download and store video streams for offline playback - **Asset Management**: Full control over downloaded assets - **Offline DRM**: Supports offline playback of DRM-protected content with proper rights enforcement and license handling - **Offline Playback**: Play downloaded content without internet connection - **Cross-platform**: Works on both iOS and Android ## Installation ### 1. Configure npm for Private Package Since this is a private package, configure npm to access GitHub Packages by adding the following to your `~/.npmrc` file: ``` @TheWidlarzGroup:registry=https://npm.pkg.github.com //npm.pkg.github.com/:_authToken= ``` Replace `` with your GitHub token. To obtain this token, please [contact us](https://sdk.thewidlarzgroup.com/?utm_source=rnv&utm_medium=docs&utm_campaign=downloading&utm_id=getting-started_github-token&contact=true). :::note This token is different from the API key used for plugin authorization. ::: ### 2. Install the Package Install the package using npm: ```bash npm install @TheWidlarzGroup/react-native-video-stream-downloader ``` ### 3. Android Configuration Add the following line to your `./android/app/build.gradle` file in the `dependencies` block: ```groovy implementation fileTree(dir: "../../node_modules/@TheWidlarzGroup/react-native-video-stream-downloader/native-libs", include: ["*.aar"]) ``` Ensure the path matches your project's `node_modules` location. ### 4. iOS Configuration No additional configuration is required for iOS; the plugin will be automatically linked. ### 5. Plugin Authorization After installation, authorize the plugin with an API key: ```tsx import { registerPlugin } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const success = await registerPlugin("YOUR_API_KEY"); ``` Replace `"YOUR_API_KEY"` with your actual API key obtained from [sdk.thewidlarzgroup.com](https://sdk.thewidlarzgroup.com?utm_source=rnv&utm_medium=docs&utm_campaign=downloading&utm_id=getting-started_api-key-link). ## Supported Formats | Format | iOS | Android | |--------|-----|---------| | HLS | ✅ | ✅ | | MP4 | ✅ | ✅ | | MPEG-DASH | ❌ | ✅ | ## Licensing & Pricing The Offline Video SDK is distributed under a commercial license. You can evaluate it for free for 14 days without a credit card. For questions or assistance, contact [hi@thewidlarzgroup.com](mailto:hi@thewidlarzgroup.com). --- ## Track Selection for Offline Downloads # Track Selection Track selection allows you to download only the specific audio, video, and subtitle tracks you need, optimizing storage usage and download time. ## Why Select Tracks? - **Storage Optimization**: Download only the tracks you need (e.g., specific language, resolution) - **Language Support**: Choose audio tracks in different languages - **Subtitle Selection**: Download only the subtitle languages your users need - **Bitrate Control**: Select video tracks with appropriate bitrates for your use case ## How It Works The track selection process follows a 2-step flow: 1. **Inspect Available Tracks**: Use `getAvailableTracks(url)` to retrieve all available tracks 2. **Select Tracks for Download**: Pass the selected track IDs to `downloadStream` in the `tracks` property ### Step 1: Get Available Tracks Use `getAvailableTracks` to retrieve all available tracks. See [getAvailableTracks](./downloading.md#getavailabletracks) in API Reference for complete details. ```tsx import { getAvailableTracks } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const tracks = await getAvailableTracks("https://example.com/video.m3u8"); // tracks.video, tracks.audio, tracks.text contain available tracks ``` ### Step 2: Download Selected Tracks ```tsx import { downloadStream } from "@TheWidlarzGroup/react-native-video-stream-downloader"; // Select specific tracks const selectedTracks = [ tracks.video[0].id, // First video track (usually highest quality) tracks.audio.find(t => t.language === "en")?.id, // English audio tracks.text.find(t => t.language === "en")?.id, // English subtitles ].filter(Boolean); // Remove undefined values await downloadStream("https://example.com/video.m3u8", { tracks: selectedTracks.map(id => ({ id, type: "video" })), // You need to specify type }); ``` ## Example: Multi-Language Selection ```tsx import { getAvailableTracks, downloadStream } from "@TheWidlarzGroup/react-native-video-stream-downloader"; const tracks = await getAvailableTracks(videoUrl); // Select video track (highest quality) const videoTrack = tracks.video[0]; // Select multiple audio tracks (English and Spanish) const audioTracks = tracks.audio.filter(t => t.language === "en" || t.language === "es" ); // Select subtitles for both languages const subtitleTracks = tracks.text.filter(t => t.language === "en" || t.language === "es" ); // Build track selection array const selectedTracks = [ { id: videoTrack.id, type: "video" as const }, ...audioTracks.map(t => ({ id: t.id, type: "audio" as const })), ...subtitleTracks.map(t => ({ id: t.id, type: "text" as const })), ]; await downloadStream(videoUrl, { tracks: selectedTracks, }); ``` ## Default Behavior If you don't specify `tracks` in `downloadStream`, or if `includeAllTracks` is `false`, only the default tracks are downloaded (typically the first video track and the first audio track). To download all available tracks, set `includeAllTracks: true`: ```tsx await downloadStream(videoUrl, { includeAllTracks: true, }); ``` --- ## DRM — Widevine & FairPlay Content Protection # DRM ## What is DRM (Digital Rights Management)? DRM is a set of access control technologies that are used to protect copyrighted content from unauthorized use and distribution. It allows content owners to control how their digital media is used and distributed. ### When do you need it? If you are working with copyrighted content and want to prevent unauthorized access or distribution, you will need DRM. It is especially important for streaming services, e-learning platforms, and any application that delivers premium content that you want to protect from piracy. ### What next? This page explains how to play DRM‑protected content with React Native Video using the official DRM plugin. It covers installing and enabling the plugin, configuring sources with DRM, and platform‑specific notes for Android (Widevine) and iOS/visionOS (FairPlay). ## Install and enable the DRM plugin :::tip Pluginable Architecture React Native Video uses a plugin architecture. DRM support is provided by the `@react-native-video/drm` plugin and is not built into the core package. ::: 1) Install dependencies in your app: ```sh npm install @react-native-video/drm ``` 2) Enable the plugin at app startup (before creating any players): ```ts // App.tsx (or any place you want to initialize the plugin) import { enable } from '@react-native-video/drm'; enable(); ``` The plugin autolinks on both Android and iOS. Nitro Modules are required because the plugin uses Nitro under the hood. ## Quick start You pass DRM configuration via `VideoConfig.drm` when creating a player or using the `useVideoPlayer` hook. If `drm.type` is omitted, the default is inferred per platform (`widevine` on Android, `fairplay` on iOS/visionOS). ```tsx import { VideoView, useVideoPlayer } from 'react-native-video'; export function Player() { const player = useVideoPlayer({ source: { uri: 'https://example.com/manifest.mpd', // or HLS .m3u8 for FairPlay // On iOS these headers are also used for the default license request headers: { Authorization: 'Bearer ' }, drm: { // type: 'widevine' | 'fairplay' // optional; inferred by platform licenseUrl: 'https://license.example.com/widevine', }, }, }); return ; } ``` :::warning You shouldn't include your authorization token directly in the code. Instead, use a backend method to retrieve it at runtime. ::: ## DRM config reference All properties are optional unless marked otherwise for a platform. The table below describes each property, the expected type, platforms where it applies, whether it's required, and important notes. | Property | Type | Platform | Required | Notes | |---|---:|---|:---:|---| | `type` | `'widevine' \| 'fairplay'` | Android, iOS, visionOS | No (defaulted) | Default inferred per platform when `drm` is present and `type` omitted (Android → `widevine`, iOS/visionOS → `fairplay`). | | `licenseUrl` | `string` | Android, iOS, visionOS | Android: Yes; iOS/visionOS: Yes for default/custom flows | URL of the license (CKC) service. Required for license acquisition. | | `licenseHeaders` | ``Record`` | Android | No | Extra headers sent with the Widevine license request. (On iOS, use `source.headers` for license requests.) | | `multiSession` | `boolean` | Android | No | Whether to allow multiple Widevine sessions. | | `certificateUrl` | `string` | iOS, visionOS | Yes (for FairPlay) | URL to fetch the FairPlay application certificate (used to create the SPC). | | `contentId` | `string` | iOS, visionOS | No | If omitted, derived from the `skd://` key URL. Used when creating the SPC. | | `getLicense` | ``(payload) => Promise`` | iOS, visionOS | No | Optional hook for custom FairPlay license logic; must resolve to a base64‑encoded CKC string. | Payload shape passed to `getLicense` (iOS/visionOS): | Field | Type | Description | |---|---:|---| | `contentId` | `string` | Content identifier for the asset. If not provided the player will try to derive it from the `skd://` key URL. | | `licenseUrl` | `string` | The license server URL that should be used for license acquisition. | | `keyUrl` | `string` | The key URL/identifier received from the stream (typically an `skd://` URL). | | `spc` | `string` | The SPC (secure playback context) as a base64‑encoded string. Send raw SPC bytes to your license server (server side may expect raw bytes rather than base64). | ## Android: Widevine - Set `drm.type` to `'widevine'` or omit it (the library will default to Widevine on Android if `drm` is present). - `licenseUrl` is required; `licenseHeaders` and `multiSession` are optional. - Implementation details: - The plugin uses ExoPlayer’s `DefaultDrmSessionManager` and `HttpMediaDrmCallback` with your `licenseUrl` and `licenseHeaders`. - If a first attempt fails due to device security level issues, the plugin retries with `L3` security level. Example: ```tsx useVideoPlayer({ source: { uri: 'https://example.com/manifest.mpd', drm: { // type: 'widevine', // optional licenseUrl: 'https://license.example.com/widevine', licenseHeaders: { 'X-Custom-Header': 'value' }, multiSession: false, }, }, }); ``` ## iOS and visionOS: FairPlay Two ways to get the CKC (license): 1) Default flow (no `getLicense`): - Required: `certificateUrl`, `licenseUrl`. - The plugin requests the application certificate, generates the SPC, then POSTs the SPC to `licenseUrl`. - It uses `source.headers` (not `drm.licenseHeaders`) for the license request. 2) Custom flow (provide `getLicense`): - Required: `certificateUrl`, `licenseUrl`, and a `getLicense` implementation. - You receive `{ contentId, licenseUrl, keyUrl, spc }` and must return a base64‑encoded CKC string. Notes: - DRM isn’t supported in the iOS Simulator; the plugin returns `null` for DRM in Simulator builds. - If `contentId` isn’t provided, it is derived from the `skd://` key URL. Default flow example: ```tsx useVideoPlayer({ source: { uri: 'https://example.com/fairplay.m3u8', headers: { Authorization: 'Bearer ' }, // used for the license request drm: { // type: 'fairplay', // optional certificateUrl: 'https://license.example.com/fps-cert', licenseUrl: 'https://license.example.com/fps', // contentId: 'my-content-id', // optional }, }, }); ``` Custom `getLicense` example: :::tip This is example code for a custom `getLicense` implementation. it may differ from your actual implementation provided by your DRM provider ::: ```tsx useVideoPlayer({ source: { uri: 'https://example.com/fairplay.m3u8', drm: { certificateUrl: 'https://license.example.com/fps-cert', licenseUrl: 'https://license.example.com/fps', getLicense: async ({ contentId, licenseUrl, keyUrl, spc }) => { // Example: POST SPC to your license server and return base64 CKC const res = await fetch(licenseUrl, { method: 'POST', body: Buffer.from(spc, 'base64'), // server expects raw SPC bytes headers: { 'Content-Type': 'application/octet-stream', 'X-Content-ID': contentId, 'X-Asset-Id': keyUrl, }, }); if (!res.ok) throw new Error(`License request failed: ${res.status}`); const ckc = await res.arrayBuffer(); // return base64 CKC string return Buffer.from(ckc).toString('base64'); }, }, }, }); ``` ## Offline If you are looking for implementing offline playback with DRM, make sure to checkout our [Offline Video SDK](https://sdk.thewidlarzgroup.com/offline-video?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=offline-sdk-link). It provides a comprehensive solution for downloading and playing Streams and DRM-protected content. ## Troubleshooting - DRMPluginNotFound: Ensure you installed `@react-native-video/drm`, imported it, and called `enable()` before creating any players. - iOS headers: The default FairPlay flow uses `source.headers` for license requests; `drm.licenseHeaders` are not used on iOS. - Invalid CKC: `getLicense` must return a base64 string. Returning raw bytes or JSON will fail. - 403/415 from license server: Verify required auth headers, content type, and whether the server expects raw SPC bytes vs base64. - Android security level issues: The plugin retries with Widevine L3 if the first attempt fails. - iOS Simulator: DRM isn’t supported in Simulator. Test on a real device. ## Notes and defaults - If `drm` is provided without `type`, the library sets a platform default: Android → Widevine, iOS/visionOS → FairPlay. - For custom DRM systems or advanced pipelines, you can implement your own plugin. See the Plugin Interface docs. --- ## Player Events — onLoad, onProgress, onError # Handling Player Events The `VideoPlayer` emits a variety of events that allow you to monitor and react to changes in its state and playback. ## Using the `useEvent` Hook For React functional components, the `useEvent` hook provides a convenient way to subscribe to player events and automatically manage cleanup. ```typescript import { useVideoPlayer, useEvent } from 'react-native-video'; import { useEffect } from 'react'; const MyVideoComponent = () => { const player = useVideoPlayer('https://example.com/video.mp4', (_player) => { _player.play(); }); useEvent(player, 'onLoad', (data) => { console.log('Video loaded via useEvent! Duration:', data.duration); }); useEvent(player, 'onProgress', (data) => { console.log('Progress via useEvent:', data.currentTime); }); // For onError, which is a direct property on VideoPlayer, not from VideoPlayerEvents useEvent(player, 'onError', (error) => { console.error('Player Error via useEvent:', error.code, error.message); }); return ; }; ``` ## Available Events The `VideoPlayer` class, through `VideoPlayerEvents`, supports the following events. You can subscribe to these by assigning a callback function to the corresponding property on the `VideoPlayer` instance. | Event | Callback Signature | Description | |----------------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------| | `onAudioBecomingNoisy` | () => void | Fired when audio is about to become noisy (e.g., headphones unplugged). | | `onAudioFocusChange` | (hasAudioFocus: boolean) => void | Fired when the audio focus changes (e.g., another app starts playing audio). | | `onBandwidthUpdate` | (data: [BandwidthData](../api-reference/interfaces/BandwidthData.md)) => void | Fired with an estimate of the available bandwidth. | | `onBuffer` | (buffering: boolean) => void | Fired when the player starts or stops buffering data. | | `onControlsVisibleChange` | (visible: boolean) => void | Fired when the visibility of native controls changes. | | `onEnd` | () => void | Fired when the video playback reaches the end. | | `onExternalPlaybackChange` | (externalPlaybackActive: boolean) => void | Fired when the external playback status changes (e.g., AirPlay). | | `onLoad` | (data: [onLoadData](../api-reference/interfaces/onLoadData.md)) => void | Fired when the video has loaded and is ready to play. | | `onLoadStart` | (data: [onLoadStartData](../api-reference/interfaces/onLoadStartData.md)) => void | Fired when the video starts loading. | | `onPlaybackRateChange` | (rate: number) => void | Fired when the playback rate changes. | | `onPlaybackStateChange` | (data: [onPlaybackStateChangeData](../api-reference/interfaces/onPlaybackStateChangeData.md)) => void | Fired when the playback state changes (e.g., playing, paused, stopped). | | `onProgress` | (data: [onProgressData](../api-reference/interfaces/onProgressData.md)) => void | Fired periodically during playback with the current time. | | `onReadyToDisplay` | () => void | Fired when the player is ready to display the first frame of the video. | | `onSeek` | (seekTime: number) => void | Fired when a seek operation has completed. | | `onStatusChange` | (status: [VideoPlayerStatus](../api-reference/type-aliases/VideoPlayerStatus.md)) => void | Fired when the player status changes (detailed status updates). | | `onTextTrackDataChanged` | (texts: string[]) => void | Fired when text track data (e.g., subtitles) changes. | | `onTimedMetadata` | (metadata: [TimedMetadata](../api-reference/interfaces/TimedMetadata.md)) => void | Fired when timed metadata is encountered in the video stream. | | `onTrackChange` | (track: [TextTrack](../api-reference/interfaces/TextTrack.md) \| null) => void | Fired when the selected text track changes. | | `onVolumeChange` | (data: [onVolumeChangeData](../api-reference/interfaces/onVolumeChangeData.md)) => void | Fired when the volume changes. | Additionally, the `VideoPlayer` instance itself has an `onError` property: - `onError: (error: ` [VideoRuntimeError](../api-reference/interfaces/VideoRuntimeError.md) `) => void` - Fired when an error occurs. The callback receives the `VideoRuntimeError` object. **Benefits of `useEvent`**: - **Automatic Cleanup**: The event listener is automatically removed when the component unmounts or when the `player`, `event`, or `callback` dependencies change, preventing memory leaks. - **Type Safety**: Provides better type inference for event callback parameters. This hook is recommended for managing event subscriptions in a declarative React style. ### Initialization Timing and Events `onLoadStart` / `onLoad` will fire automatically after construction when `initializeOnCreation` (default `true`) is enabled. If you set `initializeOnCreation: false`, these events will not fire until you call `initialize()` or `preload()`. Attach your event handlers before invoking those methods to avoid missing early events. ## Subscribing to Events You can subscribe to an event by assigning a function to the player instance's corresponding property: ```typescript import { VideoPlayer } from 'react-native-video'; const player = new VideoPlayer('https://example.com/video.mp4'); player.addEventListener('onLoad', (data) => { console.log('Video loaded! Duration:', data.duration); }); player.addEventListener('onProgress', (data) => { console.log('Current time:', data.currentTime); }); player.addEventListener('onError', (error) => { console.error('Player Error:', error.code, error.message); }); player.play(); ``` ## Clearing Events - The `player.clearEvent(eventName)` method can be used to clear a specific native event handler. - When a player instance is no longer needed and `player.release()` is called, all event listeners are automatically cleared --- ## Player — Playback Control & Lifecycle # Player The `VideoPlayer` class is the primary way to control video playback. It provides methods and properties to manage the video source, playback state, volume, and other aspects of the video. ## Initialization To use the `VideoPlayer`, you first need to create an instance of it with a video source. There are two ways to do this. By default the native media item is initialized asynchronously right after creation (unless you opt out with `initializeOnCreation: false`). ### Using `useVideoPlayer` hook ```tsx import { useVideoPlayer } from 'react-native-video'; const player = useVideoPlayer({ source: { uri: 'https://www.w3schools.com/html/mov_bbb.mp4', }, }); ``` :::info `useVideoPlayer` hook is recommended for most use cases. It automatically manages the player lifecycle between the component mount and unmount. ::: For detailed information about using the hook, see [useVideoPlayer](./use-video-player.md). ### Using `VideoPlayer` class constructor directly ```typescript import { VideoPlayer } from 'react-native-video'; // Using a URL string const player = new VideoPlayer('https://example.com/video.mp4'); // Using a VideoSource object const playerWithSource = new VideoPlayer({ uri: 'https://example.com/video.mp4' }); // Using a VideoConfig object const playerWithConfig = new VideoPlayer({ source: { uri: 'https://example.com/video.mp4' }, // other configurations }); ``` :::warning When using `VideoPlayer` class directly, you need to manually manage the player lifecycle. Once you no longer need the player, you need to call `release()` method to release the player's native resources. See [Player Lifecycle](./video-player.md#player-lifecycle) for more details. ::: For detailed information about using the class, see [VideoPlayer](./video-player.md). --- ## useVideoPlayer — React Hook for Video Playback # useVideoPlayer The `useVideoPlayer` hook is the recommended way to create and manage a `VideoPlayer` instance in React components. It automatically handles the player lifecycle, ensuring resources are properly released when the component unmounts. ## Quick Start The simplest way to use the hook is to pass a video source: ```tsx import { useVideoPlayer } from 'react-native-video'; const player = useVideoPlayer('https://www.w3schools.com/html/mov_bbb.mp4'); ``` You can also pass a configuration object for more control: ```tsx const player = useVideoPlayer({ source: { uri: 'https://www.w3schools.com/html/mov_bbb.mp4', }, }); ``` ## Why useVideoPlayer? The `useVideoPlayer` hook provides several advantages over creating a `VideoPlayer` instance directly: - **Automatic lifecycle management**: The player is automatically released when the component unmounts - **React-friendly**: Works seamlessly with React's component lifecycle :::info For most React components, `useVideoPlayer` is the recommended approach. If you need more control over the player lifecycle, see [VideoPlayer class](./video-player.md) for direct instantiation. ::: ## Using the Player Instance The `useVideoPlayer` hook returns a `VideoPlayer` instance that you can use to control playback: ```tsx import { useVideoPlayer } from 'react-native-video'; const player = useVideoPlayer('https://example.com/video.mp4'); // Control playback player.play(); player.pause(); player.muted = true; ``` ### Playback Control | Method | Description | |--------|-------------| | `play()` | Starts or resumes video playback. | | `pause()` | Pauses video playback. | | `seekBy(time: number)` | Seeks the video forward or backward by the specified number of seconds. | | `seekTo(time: number)` | Seeks the video to a specific time in seconds. | | `replaceSourceAsync(source: VideoSource \| VideoConfig \| null)` | Replaces the current video source with a new one. Pass `null` to release the current source without replacing it. | | `initialize()` | Manually initialize the underlying native player item when `initializeOnCreation` was set to `false`. No-op if already initialized. | | `preload()` | Ensures the media source is set and prepared (buffering started) without starting playback. If not yet initialized it will initialize first. | | `release()` | Releases the player's native resources. The player is no longer usable after calling this method. **Note:** If you intend to reuse the player instance with a different source, use `replaceSourceAsync(null)` to clear resources instead of `release()`. | ### Properties | Property | Access | Type | Description | |----------|--------|------|-------------| | `source` | Read-only | `VideoPlayerSource` | Gets the current `VideoPlayerSource` object. | | `status` | Read-only | `VideoPlayerStatus` | Gets the current status (e.g., `playing`, `paused`, `buffering`). | | `duration` | Read-only | `number` | Gets the total duration of the video in seconds. Returns `NaN` until metadata is loaded. | | `volume` | Read/Write | `number` | Gets or sets the player volume (0.0 to 1.0). | | `currentTime` | Read/Write | `number` | Gets or sets the current playback time in seconds. | | `muted` | Read/Write | `boolean` | Gets or sets whether the video is muted. | | `loop` | Read/Write | `boolean` | Gets or sets whether the video should loop. | | `rate` | Read/Write | `number` | Gets or sets the playback rate (e.g., 1.0 for normal speed, 0.5 for half speed, 2.0 for double speed). | | `mixAudioMode` | Read/Write | `MixAudioMode` | Controls how this player's audio mixes with other audio sources (see [MixAudioMode](../api-reference/type-aliases/MixAudioMode.md)). | | `ignoreSilentSwitchMode` | Read/Write | `IgnoreSilentSwitchMode` | iOS-only. Determines how audio should behave when the hardware mute (silent) switch is on. | | `playInBackground` | Read/Write | `boolean` | Whether playback should continue when the app goes to the background. | | `playWhenInactive` | Read/Write | `boolean` | Whether playback should continue when the app is inactive (e.g., during a phone call). | | `isPlaying` | Read-only | `boolean` | Returns `true` if the video is currently playing. | | `selectedTrack` | Read-only | `TextTrack \| undefined` | Currently selected text track, or `undefined` when no track is selected. | ### Error Handling | Property | Type | Description | |----------|------|-------------| | `onError?` | `(error: VideoRuntimeError) => void` | A callback function that is invoked when a runtime error occurs in the player. You can use this to catch and handle errors gracefully. | ### Buffer Config You can fine‑tune buffering via `bufferConfig` on the `VideoConfig` you pass to `useVideoPlayer`/`VideoPlayer`. This controls how much data is buffered, live latency targets, and iOS network constraints. Example ```ts const player = useVideoPlayer({ source: { uri: 'https://example.com/stream.m3u8', bufferConfig: { // Android minBufferMs: 5000, maxBufferMs: 10000, // iOS preferredForwardBufferDurationMs: 3000, // Live (cross‑platform target) livePlayback: { targetOffsetMs: 500 }, }, }, }); ``` #### Android Properties below are Android‑only | Property | Type | Description | |----------|------|-------------| | `minBufferMs` | `number` | Minimum media duration the player attempts to keep buffered (ms). Default: 5000. | | `maxBufferMs` | `number` | Maximum media duration the player attempts to buffer (ms). Default: 10000. | | `bufferForPlaybackMs` | `number` | Media that must be buffered before playback can start or resume after user action (ms). Default: 1000. | | `bufferForPlaybackAfterRebufferMs` | `number` | Media that must be buffered to resume after a rebuffer (ms). Default: 2000. | | `backBufferDurationMs` | `number` | Duration kept behind the current position to allow instant rewind without rebuffer (ms). | | `livePlayback.minPlaybackSpeed` | `number` | Minimum playback speed used to maintain target live offset. | | `livePlayback.maxPlaybackSpeed` | `number` | Maximum playback speed used to catch up to target live offset. | | `livePlayback.minOffsetMs` | `number` | Minimum allowed live offset (ms). | | `livePlayback.maxOffsetMs` | `number` | Maximum allowed live offset (ms). | | `livePlayback.targetOffsetMs` | `number` | Target live offset the player tries to maintain (ms). | #### iOS, visionOS, tvOS Properties below are Apple platforms‑only | Property | Type | Description | |----------|------|-------------| | `preferredForwardBufferDurationMs` | `number` | Preferred duration the player attempts to retain ahead of the playhead (ms). | | `preferredPeakBitRate` | `number` | Desired limit of network bandwidth for loading the current item (bits per second). | | `preferredMaximumResolution` | `{ width: number; height: number }` | Preferred maximum video resolution. | | `preferredPeakBitRateForExpensiveNetworks` | `number` | Bandwidth limit for expensive networks (e.g., cellular), in bits per second. | | `preferredMaximumResolutionForExpensiveNetworks` | `{ width: number; height: number }` | Preferred maximum resolution on expensive networks. | | `livePlayback.targetOffsetMs` | `number` | Target live offset (ms) the player will try to maintain. | ## DRM Protected content is supported via a plugin. See the full DRM guide: [DRM](./drm.md). Quick notes: - Install and enable the official plugin `@react-native-video/drm` and call `enable()` at app startup before creating players. - Pass DRM configuration on the source using the `drm` property of `VideoConfig` (see the DRM guide for platform specifics and `getLicense` examples). - If you defer initialization (`initializeOnCreation: false`), be sure to call `await player.initialize()` (or `preload()`) before expecting DRM license acquisition events. --- ## VideoPlayer Class — Full API Reference # VideoPlayer :::tip When to Use What - **[`useVideoPlayer`](./use-video-player.md) hook** - Recommended for most cases. Automatically manages player lifecycle (creation, cleanup on unmount, source changes). - **`VideoPlayer` class** - Use when you need manual lifecycle control, e.g., preloading videos before displaying them, managing multiple players with custom logic, or deferred initialization scenarios. ::: The `VideoPlayer` class is the primary way to control video playback. It provides methods and properties to manage the video source, playback state, volume, and other aspects of the video. ## Initialization To use the `VideoPlayer`, you first need to create an instance of it with a video source. By default the native media item is initialized asynchronously right after creation (unless you opt out with `initializeOnCreation: false`). ```typescript import { VideoPlayer } from 'react-native-video'; // Using a URL string const player = new VideoPlayer('https://example.com/video.mp4'); // Using a VideoSource object const playerWithSource = new VideoPlayer({ uri: 'https://example.com/video.mp4' }); // Using a VideoConfig object const playerWithConfig = new VideoPlayer({ source: { uri: 'https://example.com/video.mp4' }, // other configurations }); ``` :::warning When using `VideoPlayer` class directly, you need to manually manage the player lifecycle. Once you no longer need the player, you need to call `release()` method to release the player's native resources. See the [Player Lifecycle](#player-lifecycle) section below for more details. ::: ## Core Functionality The `VideoPlayer` class offers a comprehensive set of methods and properties to control video playback: ### Playback Control | Method | Description | |--------|-------------| | `play()` | Starts or resumes video playback. | | `pause()` | Pauses video playback. | | `seekBy(time: number)` | Seeks the video forward or backward by the specified number of seconds. | | `seekTo(time: number)` | Seeks the video to a specific time in seconds. | | `replaceSourceAsync(source: VideoSource \| VideoConfig \| null)` | Replaces the current video source with a new one. Pass `null` to release the current source without replacing it. | | `initialize()` | Manually initialize the underlying native player item when `initializeOnCreation` was set to `false`. No-op if already initialized. | | `preload()` | Ensures the media source is set and prepared (buffering started) without starting playback. If not yet initialized it will initialize first. | | `release()` | Releases the player's native resources. The player is no longer usable after calling this method. **Note:** If you intend to reuse the player instance with a different source, use `replaceSourceAsync(null)` to clear resources instead of `release()`. | ### Properties | Property | Access | Type | Description | |----------|--------|------|-------------| | `source` | Read-only | `VideoPlayerSource` | Gets the current `VideoPlayerSource` object. | | `status` | Read-only | `VideoPlayerStatus` | Gets the current status (e.g., `playing`, `paused`, `buffering`). | | `duration` | Read-only | `number` | Gets the total duration of the video in seconds. Returns `NaN` until metadata is loaded. | | `volume` | Read/Write | `number` | Gets or sets the player volume (0.0 to 1.0). | | `currentTime` | Read/Write | `number` | Gets or sets the current playback time in seconds. | | `muted` | Read/Write | `boolean` | Gets or sets whether the video is muted. | | `loop` | Read/Write | `boolean` | Gets or sets whether the video should loop. | | `rate` | Read/Write | `number` | Gets or sets the playback rate (e.g., 1.0 for normal speed, 0.5 for half speed, 2.0 for double speed). | | `mixAudioMode` | Read/Write | `MixAudioMode` | Controls how this player's audio mixes with other audio sources (see [MixAudioMode](../api-reference/type-aliases/MixAudioMode.md)). | | `ignoreSilentSwitchMode` | Read/Write | `IgnoreSilentSwitchMode` | iOS-only. Determines how audio should behave when the hardware mute (silent) switch is on. | | `playInBackground` | Read/Write | `boolean` | Whether playback should continue when the app goes to the background. | | `playWhenInactive` | Read/Write | `boolean` | Whether playback should continue when the app is inactive (e.g., during a phone call). | | `isPlaying` | Read-only | `boolean` | Returns `true` if the video is currently playing. | | `selectedTrack` | Read-only | `TextTrack \| undefined` | Currently selected text track, or `undefined` when no track is selected. | ### Error Handling | Property | Type | Description | |----------|------|-------------| | `onError?` | `(error: VideoRuntimeError) => void` | A callback function that is invoked when a runtime error occurs in the player. You can use this to catch and handle errors gracefully. | ### Buffer Config You can fine‑tune buffering via `bufferConfig` on the `VideoConfig` you pass to `useVideoPlayer`/`VideoPlayer`. This controls how much data is buffered, live latency targets, and iOS network constraints. Example ```ts const player = new VideoPlayer({ source: { uri: 'https://example.com/stream.m3u8', bufferConfig: { // Android minBufferMs: 5000, maxBufferMs: 10000, // iOS preferredForwardBufferDurationMs: 3000, // Live (cross‑platform target) livePlayback: { targetOffsetMs: 500 }, }, }, }); ``` #### Android Properties below are Android‑only | Property | Type | Description | |----------|------|-------------| | `minBufferMs` | `number` | Minimum media duration the player attempts to keep buffered (ms). Default: 5000. | | `maxBufferMs` | `number` | Maximum media duration the player attempts to buffer (ms). Default: 10000. | | `bufferForPlaybackMs` | `number` | Media that must be buffered before playback can start or resume after user action (ms). Default: 1000. | | `bufferForPlaybackAfterRebufferMs` | `number` | Media that must be buffered to resume after a rebuffer (ms). Default: 2000. | | `backBufferDurationMs` | `number` | Duration kept behind the current position to allow instant rewind without rebuffer (ms). | | `livePlayback.minPlaybackSpeed` | `number` | Minimum playback speed used to maintain target live offset. | | `livePlayback.maxPlaybackSpeed` | `number` | Maximum playback speed used to catch up to target live offset. | | `livePlayback.minOffsetMs` | `number` | Minimum allowed live offset (ms). | | `livePlayback.maxOffsetMs` | `number` | Maximum allowed live offset (ms). | | `livePlayback.targetOffsetMs` | `number` | Target live offset the player tries to maintain (ms). | #### iOS, visionOS, tvOS Properties below are Apple platforms‑only | Property | Type | Description | |----------|------|-------------| | `preferredForwardBufferDurationMs` | `number` | Preferred duration the player attempts to retain ahead of the playhead (ms). | | `preferredPeakBitRate` | `number` | Desired limit of network bandwidth for loading the current item (bits per second). | | `preferredMaximumResolution` | `{ width: number; height: number }` | Preferred maximum video resolution. | | `preferredPeakBitRateForExpensiveNetworks` | `number` | Bandwidth limit for expensive networks (e.g., cellular), in bits per second. | | `preferredMaximumResolutionForExpensiveNetworks` | `{ width: number; height: number }` | Preferred maximum resolution on expensive networks. | | `livePlayback.targetOffsetMs` | `number` | Target live offset (ms) the player will try to maintain. | ## DRM Protected content is supported via a plugin. See the full DRM guide: [DRM](./drm.md). Quick notes: - Install and enable the official plugin `@react-native-video/drm` and call `enable()` at app startup before creating players. - Pass DRM configuration on the source using the `drm` property of `VideoConfig` (see the DRM guide for platform specifics and `getLicense` examples). - If you defer initialization (`initializeOnCreation: false`), be sure to call `await player.initialize()` (or `preload()`) before expecting DRM license acquisition events. ## Player Lifecycle Understanding the lifecycle of the `VideoPlayer` is crucial for managing resources effectively and ensuring a smooth user experience. ### Creation and Initialization 1. **Instantiation**: A `VideoPlayer` instance is created by calling its constructor with a video source (URL, `VideoSource`, or `VideoConfig`). ```typescript const player = new VideoPlayer('https://example.com/video.mp4'); ``` 2. **Native Player Allocation**: A lightweight native player object is allocated immediately. 3. **Asset Initialization**: By default (unless you opt out) the underlying media item is prepared **asynchronously right after creation**. You can control this with `initializeOnCreation` inside `VideoConfig`. #### Deferred Initialization (Advanced) If you pass a `VideoConfig` with `{ initializeOnCreation: false }`, the player will skip preparing the media item automatically. This is useful when: - You need to batch‑create many players without incurring immediate decoding / network cost - You want to attach event handlers before any network requests happen - You want explicit control over when buffering begins (e.g. on user interaction) To initialize later, call: ```ts await player.initialize(); // or preload if you also want it prepared & ready await player.preload(); ``` #### Initialization Methods Comparison | Method | When to use | What it does | |--------|-------------|--------------| | `initialize()` | You deferred initialization and now want to create the native player item / media source | Creates & attaches the underlying player item / media source without starting playback | | `preload()` | You want the player item prepared (buffering kicked off) ahead of an upcoming `play()` call | Ensures the media source is set and prepared; resolves once preparation started (may already be initialized) | | Implicit (default) | `initializeOnCreation` not set or `true` | Automatically schedules initialization after JS construction | :::info By default, the player initializes automatically after construction. If you need to defer initialization, set `initializeOnCreation: false` in the config. You can then call `player.initialize()` or `player.preload()` later to start the player. ::: ### Playing a Video 1. **Loading**: When the player (auto) initializes, `preload()` is called, or after `replaceSourceAsync()`, the player starts loading the video metadata and buffering content. - `onLoadStart`: Fired when the video starts loading. - `onLoad`: Fired when the video metadata is loaded and the player is ready to play (duration, dimensions, etc., are available). - `onBuffer`: Fired when buffering starts or ends. 2. **Playback**: Once enough data is buffered, playback begins. - `onPlaybackStateChange`: Fired when the playback state changes (e.g., from `buffering` to `playing`). - `onProgress`: Fired periodically with the current playback time. - `onReadyToDisplay`: Fired when the first frame is ready to be displayed. ### Controlling Playback - `pause()`: Pauses playback. `status` changes to `paused`. - `seekTo(time)`, `seekBy(time)`: Changes the current playback position. `onSeek` is fired when the seek operation completes. - `set volume(value)`, `set muted(value)`, `set loop(value)`, `set rate(value)`: Modify player properties. Corresponding events like `onVolumeChange` or `onPlaybackRateChange` might be fired. ### Changing Source - `replaceSourceAsync(newSource)`: This method allows you to change the video source dynamically. 1. The current native player resources associated with the old source are released (similar to `release()` but specifically for the source). 2. A new native player instance (or reconfigured existing one) is prepared for the `newSource`. 3. The loading lifecycle events (`onLoadStart`, `onLoad`, etc.) will fire for the new source. - `replaceSourceAsync(null)`: This effectively unloads the current video and releases its associated resources without loading a new one. This is useful for freeing up memory if the player is temporarily not needed but might be used again later. ### Releasing Resources There are two main ways to release resources: 1. **`replaceSourceAsync(null)`**: This is a less destructive way to free resources related *only* to the current video source. - The `VideoPlayer` instance itself remains usable. - You can later call `replaceSourceAsync(newSource)` to load and play a new video. 2. **`release()`**: This is a destructive operation. :::danger After calling `release()`, the player instance becomes unusable. Any subsequent calls to its methods or property access will result in errors. ::: :::tip It is recommended to use `replaceSourceAsync(null)` when you want to free resources related to the current video source. You should call `release()` only when you are 100% sure that you don't need the player instance anymore. Anyway garbage collector will release the player instance when it is no longer needed. ::: ### Error Handling - The `onError` callback, if provided, will be called when a `VideoRuntimeError` occurs. This allows you to handle issues like network errors, invalid source, or platform-specific playback problems. - If `onError` is not provided, errors might be thrown as exceptions. ### Using with Hooks (`useVideoPlayer`) The `useVideoPlayer` hook simplifies managing the `VideoPlayer` lifecycle within React components. ```typescript import { useVideoPlayer } from 'react-native-video'; const MyComponent = () => { const player = useVideoPlayer('https://example.com/video.mp4', (playerInstance) => { // Optional setup function: configure the player instance after creation playerInstance.loop = true; }); // ... use player ... return ; }; ``` - **Automatic Creation**: `useVideoPlayer` creates a `VideoPlayer` instance when the component mounts or when the source dependency changes. - **Automatic Cleanup**: It automatically cleanup resources when the component unmounts or before recreating the player due to a source change. This prevents resource leaks. - **Dependency Management**: If the `source` prop passed to `useVideoPlayer` changes, the hook will clean up the old player instance and create a new one with the new source. :::tip Using `useVideoPlayer` is the recommended way to manage `VideoPlayer` instances in functional components to ensure proper lifecycle management and resource cleanup. It will also respect `initializeOnCreation` (defaults to `true`). If you need deferred initialization with the hook: ```tsx const player = useVideoPlayer({ source: { uri: 'https://example.com/video.mp4' }, initializeOnCreation: false, }, (instance) => { // Attach listeners first instance.onLoad = () => console.log('Loaded'); }); // Later (e.g. on user tap) await player.initialize(); // or player.preload() player.play(); ``` ::: --- ## Request a Custom Plugin # Ask for Plugin Need a custom plugin for your React Native Video application? We can build it for you. ## What We Build Our team specializes in creating production-ready plugins for `react-native-video`. Whatever video functionality you need - we can build it. **Examples of plugins we can build:** - **Analytics integrations** - Connect with any analytics provider (Mux, Conviva, custom solutions) - **Live streaming features** - Real-time chat overlays, live reactions, viewer counts - **Interactive video** - Clickable hotspots, branching narratives, shoppable videos - **Accessibility enhancements** - Audio descriptions, sign language overlays, custom captions styling - **AI-powered features** - Auto-generated thumbnails, content moderation, speech-to-text - **Social features** - Watch parties, synchronized playback, clip sharing - **Custom UI components** - Branded controls, gesture handlers, thumbnail previews on seek ## Why Choose Us? - **Deep expertise** - We maintain `react-native-video` and know the codebase inside out - **Production-ready** - Battle-tested code with proper error handling and edge cases covered - **Native performance** - Plugins implemented in Kotlin/Swift for optimal performance - **Ongoing support** - We maintain and update plugins as the library evolves ## Our Existing Plugins We've already built several production-ready plugins: | Plugin | Description | |--------|-------------| | [Offline Video SDK](https://sdk.thewidlarzgroup.com/offline-video?utm_source=rnv&utm_medium=docs&utm_campaign=ask-for-plugin&utm_id=offline-video-sdk) | Download and play HLS, MPEG-DASH, MP4 streams offline with DRM support | | [Background Uploader](https://sdk.thewidlarzgroup.com/background-uploader?utm_source=rnv&utm_medium=docs&utm_campaign=ask-for-plugin&utm_id=background-uploader) | Upload files in the background with retry support and progress tracking | | [Chapters Plugin](https://sdk.thewidlarzgroup.com/chapters?utm_source=rnv&utm_medium=docs&utm_campaign=ask-for-plugin&utm_id=chapters-plugin) | Chapter markers and navigation on the seekbar | ## Get Started Ready to discuss your plugin needs? ➡️ [**Request a Plugin**](https://sdk.thewidlarzgroup.com/ask-for-plugin?utm_source=rnv&utm_medium=docs&utm_campaign=ask-for-plugin&utm_id=request-plugin-button) We'll review your requirements and get back to you with a proposal. --- ## Plugin Usage Examples # Plugin Usage Examples This document provides practical examples of implementing common plugin scenarios for React Native Video. ## Basic Plugin Template ```kotlin title="Android" class MyPlugin : ReactNativeVideoPlugin("MyPlugin") { override fun onPlayerCreated(player: WeakReference) { Log.d("MyPlugin", "Player created with uri ${player.get()?.source.uri}") } override fun onPlayerDestroyed(player: WeakReference) { Log.d("MyPlugin", "Player destroyed") } override fun overrideSource(source: NativeVideoPlayerSource): NativeVideoPlayerSource { Log.d("MyPlugin", "Overriding source with uri ${source.uri}") return source } } // Usage val plugin = MyPlugin() // Automatically registered ``` ```swift title="iOS" class MyPlugin: ReactNativeVideoPlugin { init() { super.init(name: "MyPlugin") } override func onPlayerCreated(player: Weak) { // Custom logic when player is created } override func onPlayerDestroyed(player: Weak) { // Custom cleanup when player is destroyed } override func overrideSource(source: NativeVideoPlayerSource) async -> NativeVideoPlayerSource { // Modify source if needed return source } } // Usage let plugin = MyPlugin() // Automatically registered ``` ## DRM Plugin Implement custom DRM handling for protected content. :::warning DRM plugins are not supported yet in React Native Video. `getDRMManager` is not implemented yet and will have no effect. ::: ```kotlin title="Android" class CustomDRMPlugin : ReactNativeVideoPlugin("CustomDRM") { override fun getDRMManager(source: NativeVideoPlayerSource): Any? { if (source.isDRMProtected() && source.drmType == "custom") { return CustomDRMManager( licenseUrl = source.drmLicenseUrl, certificateUrl = source.drmCertificateUrl, keyId = source.drmKeyId ) } return null } } ``` ```swift title="iOS" class CustomDRMPlugin: ReactNativeVideoPlugin { init() { super.init(name: "CustomDRM") } override func getDRMManager(source: NativeVideoPlayerSource) async -> Any? { guard source.isDRMProtected() && source.drmType == "custom" else { return nil } return CustomDRMManager( licenseUrl: source.drmLicenseUrl, certificateUrl: source.drmCertificateUrl, keyId: source.drmKeyId ) } } ``` --- ## Plugin Interface Reference # Plugin Interface Reference This document provides a complete reference for the `ReactNativeVideoPluginSpec` interface and the base `ReactNativeVideoPlugin` implementation. ## ReactNativeVideoPluginSpec Interface ### Required Properties #### id: String Unique identifier for the plugin. Must be unique across all registered plugins. ```kotlin // Android override val id: String = "my_unique_plugin_id" ``` ```swift // iOS var id: String { "my_unique_plugin_id" } ``` #### name: String Human-readable name for the plugin, used in debug logging. ```kotlin // Android override val name: String = "My Custom Plugin" ``` ```swift // iOS var name: String { "My Custom Plugin" } ``` ## Lifecycle Methods ### Player Lifecycle #### onPlayerCreated Called when a new player instance is created. ```kotlin // Android @UnstableApi fun onPlayerCreated(player: WeakReference) ``` ```swift // iOS func onPlayerCreated(player: Weak) ``` **Parameters:** - `player`: Weak reference to the newly created player instance **Use Cases:** - Initialize player-specific resources - Set up player event listeners - Configure player settings #### onPlayerDestroyed Called when a player instance is being destroyed. ```kotlin // Android @UnstableApi fun onPlayerDestroyed(player: WeakReference) ``` ```swift // iOS func onPlayerDestroyed(player: Weak) ``` **Parameters:** - `player`: Weak reference to the player instance being destroyed **Use Cases:** - Clean up player-specific resources - Remove event listeners - Save state or analytics data ### Video View Lifecycle #### onVideoViewCreated Called when a new video view is created. ```kotlin // Android @UnstableApi fun onVideoViewCreated(view: WeakReference) ``` ```swift // iOS func onVideoViewCreated(view: Weak) ``` **Parameters:** - `view`: Weak reference to the newly created video view **Use Cases:** - Configure view-specific settings - Set up UI event handlers - Initialize view overlays #### onVideoViewDestroyed Called when a video view is being destroyed. ```kotlin // Android @UnstableApi fun onVideoViewDestroyed(view: WeakReference) ``` ```swift // iOS func onVideoViewDestroyed(view: Weak) ``` **Parameters:** - `view`: Weak reference to the video view being destroyed **Use Cases:** - Clean up view-specific resources - Remove UI event handlers - Save view state ## Content Modification Methods ### overrideSource Modify the video source before it's processed by the player. ```kotlin // Android fun overrideSource(source: NativeVideoPlayerSource): NativeVideoPlayerSource ``` ```swift // iOS func overrideSource(source: NativeVideoPlayerSource) async -> NativeVideoPlayerSource ``` **Parameters:** - `source`: The original video source **Returns:** - Modified video source (can be the same instance if no changes needed) **Use Cases:** - Add authentication headers - Modify URLs (e.g., CDN switching) - Add tracking parameters - Transform source format ### getDRMManager Provide a custom DRM manager for protected content. ```kotlin // Android fun getDRMManager(source: NativeVideoPlayerSource): Any? ``` ```swift // iOS func getDRMManager(source: NativeVideoPlayerSource) async -> Any? ``` **Parameters:** - `source`: The video source that may require DRM **Returns:** - DRM manager instance, or `null` if this plugin doesn't handle DRM for this source **Use Cases:** - Widevine DRM implementation - FairPlay DRM implementation - Custom DRM solutions - License acquisition logic ## Android-Specific Methods ### getMediaDataSourceFactory Override the data source factory used by ExoPlayer. ```kotlin fun getMediaDataSourceFactory( source: NativeVideoPlayerSource, mediaDataSourceFactory: DataSource.Factory ): DataSource.Factory? ``` **Parameters:** - `source`: The video source - `mediaDataSourceFactory`: The default data source factory **Returns:** - Custom data source factory, or `null` to use the default **Use Cases:** - Custom caching strategies - Network optimization - Custom authentication - Analytics data collection ### getMediaSourceFactory Override the media source factory used by ExoPlayer. ```kotlin fun getMediaSourceFactory( source: NativeVideoPlayerSource, mediaSourceFactory: MediaSource.Factory, mediaDataSourceFactory: DataSource.Factory ): MediaSource.Factory? ``` **Parameters:** - `source`: The video source - `mediaSourceFactory`: The default media source factory - `mediaDataSourceFactory`: The data source factory **Returns:** - Custom media source factory, or `null` to use the default **Use Cases:** - Custom media format support - Advanced ExoPlayer configuration - Source-specific optimizations ### getMediaItemBuilder Override the media item builder used by ExoPlayer. ```kotlin fun getMediaItemBuilder( source: NativeVideoPlayerSource, mediaItemBuilder: MediaItem.Builder ): MediaItem.Builder? ``` **Parameters:** - `source`: The video source - `mediaItemBuilder`: The default media item builder **Returns:** - Modified media item builder, or `null` to use the default **Use Cases:** - Add custom metadata - Configure subtitles - Set playback preferences - Configure DRM settings ### shouldDisableCache Control whether caching should be disabled for a source. ```kotlin fun shouldDisableCache(source: NativeVideoPlayerSource): Boolean ``` **Parameters:** - `source`: The video source **Returns:** - `true` to disable caching, `false` to allow caching **Use Cases:** - Disable caching for live streams - Disable caching for DRM content - Custom caching policies ## Base Implementation: ReactNativeVideoPlugin The base class provides default implementations for all methods: ### Automatic Registration ```kotlin // Android init { PluginsRegistry.shared.register(this) } ``` ```swift // iOS public init(name: String) { self.name = name self.id = "RNV_Plugin_\(name)" PluginsRegistry.shared.register(plugin: self) } ``` ### Automatic Cleanup (iOS only) ```swift deinit { PluginsRegistry.shared.unregister(plugin: self) } ``` ### Default Implementations All methods have sensible defaults: - Lifecycle methods: No-op implementations - `overrideSource`: Returns the original source unchanged - `getDRMManager`: Returns `null` - Factory methods (Android): Return `null` (use defaults) - `shouldDisableCache`: Returns `false` ## Method Calling Order ### Source Processing Flow 1. `overrideSource` - Called for each registered plugin in order 2. `getDRMManager` - Called for each plugin until one returns non-null 3. Factory methods (Android) - Called for each plugin until one returns non-null ### Lifecycle Flow 1. View/Player creation methods called for all plugins 2. Source processing happens during playback 3. View/Player destruction methods called for all plugins ## Error Handling ### DRM Plugin Not Found If no plugin provides a DRM manager when required: ```kotlin // Android throw LibraryError.DRMPluginNotFound ``` ```swift // iOS throw LibraryError.DRMPluginNotFound.error() ``` ### Best Practices - Return `null` from optional methods when not providing custom behavior - Handle weak reference nullability properly - Use appropriate error handling in async methods (iOS) - Log meaningful debug information ## Platform Differences Summary | Feature | Android | iOS | |---------|---------|-----| | Async Support | No | Yes (async/await) | | Media Factories | Full ExoPlayer support | Limited AVFoundation | | Cache Control | Yes | No | | Auto Cleanup | Manual | Automatic (deinit) | | Weak References | `WeakReference` | `Weak` | --- ## Plugin System Overview # Plugins Overview The **React Native Video** library offers a robust plugin system to extend and customize video functionality on Android and iOS. With plugins, you can override source handling, implement custom DRM, modify media factories, and respond to player lifecycle events. :::tip Use in Third Party Library Guide If you are looking how to import React Native Video in your native code to use plugins, you can checkout [Use in Third Party Library](./use-in-third-party-library) page. ::: ## What Are Plugins? Plugins are modular extensions that hook into the video player's lifecycle and processing pipeline. They allow you to: - **Customize video sources** before playback - **Implement custom DRM** for protected content - **Override media factories** (Android only) - **React to player lifecycle events** for analytics, logging, or cleanup - **Control caching behavior** for performance ## Architecture The plugin system consists of three main components: | Component | Description | |:-----------------------------|:-------------------------------------------------------------------------------------------| | `PluginsRegistry` | Singleton that manages plugin registration and coordinates plugin interactions | | `ReactNativeVideoPluginSpec` | Interface/protocol defining the contract all plugins must implement | | `ReactNativeVideoPlugin` | Base implementation with convenient defaults; override only the methods you care about | :::tip Plugins are automatically registered when you instantiate a class that extends `ReactNativeVideoPlugin`. ::: ## Core Concepts ### Plugin Lifecycle Plugins receive notifications for key events: - **Player creation/destruction** - react to player instance lifecycle - **Video view creation/destruction** - handle UI component lifecycle - **Source processing** - modify video sources before playback - **DRM requests** - provide custom DRM handling - **Media factory overrides** - customize ExoPlayer components (Android) :::caution All player and view references passed to plugins are **weak references** to prevent memory leaks. ::: ## Platform Differences | Feature | Android (Kotlin / ExoPlayer) | iOS (Swift / AVFoundation) | |:-------------------------------|:-----------------------------------------------|:-----------------------------------| | Underlying player | ExoPlayer | AVFoundation | | Media factory customization | Extensive | Limited | | Cache control | Supported | Limited | | Plugin method style | Synchronous | Async/await | | Memory management | Manual cleanup | Manual cleanup | ## Getting Started ### Example: Android Plugin ```kotlin // Android class MyPlugin : ReactNativeVideoPlugin("MyPluginName") { override fun onPlayerCreated(player: WeakReference) { // Custom logic here } } ``` ### Example: iOS Plugin ```swift // iOS class MyPlugin: ReactNativeVideoPlugin { init() { super.init(name: "MyPluginName") } override func onPlayerCreated(player: Weak) { // Custom logic here } } ``` ## Next Steps - [**Plugin Registry**](./registry) - Learn about plugin management and registration - [**Plugin Interface**](./interface) - Complete API reference for plugin methods - [**Usage Examples**](./examples) - Practical implementations and common patterns - [**Ask for Plugin**](./ask-for-plugin) - Request a custom plugin built by our team --- ## Plugin Registry # Plugin Registry The `PluginsRegistry` is a singleton that manages all plugin instances and coordinates their interactions with the video player system. It handles registration, unregistration, and notification distribution to all active plugins. ## Singleton Pattern Both Android and iOS use a shared singleton: ```kotlin title="Android" // Register PluginsRegistry.shared.register(plugin) // Unregister PluginsRegistry.shared.unregister(plugin) ``` ```swift title="iOS" // Register PluginsRegistry.shared.register(plugin: plugin) // Unregister PluginsRegistry.shared.unregister(plugin: plugin) ``` :::tip Plugin Ordering Plugins are processed in registration order. Later plugins can override earlier ones. ::: ## Registration Methods ### Automatic Registration You can use the base class `ReactNativeVideoPlugin` to automatically register your plugin. This will also mock all the methods that are not implemented in your plugin. :::danger You still need to unregister your plugin manually when you are done with it. Otherwise, you will have a memory leak. ::: ```kotlin title="Android" class MyPlugin : ReactNativeVideoPlugin("MyPlugin") { // ... } val plugin = MyPlugin() // Auto-registered ``` ```swift title="iOS" class MyPlugin: ReactNativeVideoPlugin { init() { super.init(name: "MyPlugin") } // Auto-unregistered in deinit } let plugin = MyPlugin() // Auto-registered ``` ### Manual Registration You can also manually register your plugin. This is useful if you want to implement a plugin that is not a subclass of `ReactNativeVideoPlugin`. You will need to implement the `ReactNativeVideoPluginSpec` interface. This is a protocol that defines the methods and properties that a plugin must implement. ```kotlin title="Android" class MyCustomPlugin : ReactNativeVideoPluginSpec { override val id = "my_custom_id" override val name = "MyCustomPlugin" // ... } val plugin = MyCustomPlugin() PluginsRegistry.shared.register(plugin) ``` ```swift title="iOS" class MyCustomPlugin: ReactNativeVideoPluginSpec { let id = "my_custom_id" let name = "MyCustomPlugin" // ... } let plugin = MyCustomPlugin() PluginsRegistry.shared.register(plugin: plugin) ``` ## Plugin ID Generation When using the base class, IDs are auto-generated: ```kotlin title="Android" ID Format: "RNV_Plugin_{name}" Example: "RNV_Plugin_MyCustomDRM" ``` ```swift title="iOS" ID Format: "RNV_Plugin_{name}" Example: "RNV_Plugin_MyCustomDRM" ``` ## Plugin Internals Bellow are the internals of the plugin registry, that shows logic for certain methods. ### Source Processing The registry coordinates source modifications: ```kotlin title="Android" internal fun overrideSource(source: NativeVideoPlayerSource): NativeVideoPlayerSource { var overriddenSource = source for (plugin in plugins.values) { overriddenSource = plugin.overrideSource(overriddenSource) } return overriddenSource } ``` ```swift title="iOS" internal func overrideSource(source: NativeVideoPlayerSource) async -> NativeVideoPlayerSource { var overriddenSource = source for plugin in plugins.values { overriddenSource = await plugin.overrideSource(source: source) } return overriddenSource } ``` ### DRM Manager Resolution Finds the first plugin that can provide a DRM manager: ```kotlin title="Android" internal fun getDRMManager(source: NativeVideoPlayerSource): Any { for (plugin in plugins.values) { val manager = plugin.getDRMManager(source) if (manager != null) return manager } throw LibraryError.DRMPluginNotFound } ``` ```swift title="iOS" internal func getDrmManager(source: NativeVideoPlayerSource) async throws -> Any? { for plugin in plugins.values { if let drmManager = await plugin.getDRMManager(source: source) { return drmManager } } throw LibraryError.DRMPluginNotFound.error() } ``` ## Android-Specific Registry Methods | Method Name | Purpose | |:----------------------------------|:----------------------------------------------------------| | `overrideMediaDataSourceFactory` | Override data source factory for custom ExoPlayer sources | | `overrideMediaSourceFactory` | Override media source factory | | `overrideMediaItemBuilder` | Customize the media item builder | | `shouldDisableCache` | Control caching behavior | Example signatures: ```kotlin internal fun overrideMediaDataSourceFactory( source: NativeVideoPlayerSource, mediaDataSourceFactory: DataSource.Factory ): DataSource.Factory internal fun overrideMediaSourceFactory( source: NativeVideoPlayerSource, mediaSourceFactory: MediaSource.Factory, mediaDataSourceFactory: DataSource.Factory ): MediaSource.Factory internal fun overrideMediaItemBuilder( source: NativeVideoPlayerSource, mediaItemBuilder: MediaItem.Builder ): MediaItem.Builder internal fun shouldDisableCache(source: NativeVideoPlayerSource): Boolean ``` ## Best Practices - **Memory management**: Registry holds strong references to plugins; plugins get weak references to players/views. - **Unregister plugins**: Use unregistration to prevent memory leaks. - **Performance**: Minimize work in notification handlers. Cache expensive operations. Be mindful of plugin order. :::tip Need a Custom Plugin? If you need functionality that the library doesn't currently offer, we can build it for you. Check out [Ask for Plugin](./ask-for-plugin.md) to request a custom plugin built by our team. ::: --- ## Using Plugins in Third-Party Libraries # Use in Third Party Library You can use React Native Video in your third party library either as a dependency if you want to have specific version of the library or as a peer dependency if you want to version selection to be handled by the consumer of the library. ## In JS Add `react-native-video` as a dependency or peer dependency. ```json title="package.json" { "dependencies": { "react-native-video": "latest" } // OR "peerDependencies": { "react-native-video": "*" } } ``` And then you can import it in your code. ```ts import { VideoPlayer } from 'react-native-video'; const player = new VideoPlayer({ uri: 'https://www.example.com/video.mp4' }); player.play(); ``` ## In Native ### iOS Add `ReactNativeVideo` as a dependency in your `*.podspec` file. ```ruby title="*.podspec" Pod::Spec.new do |s| // ... s.dependency 'ReactNativeVideo' end ``` ### Android Add `:react-native-video` and `:react-native-nitro-modules` as a dependency in your `build.gradle` file. Also you will need to add `androidx.media3` dependencies. to use player and source in your library. ```groovy title="build.gradle" // ... dependencies { // ... implementation project(':react-native-video') implementation project(':react-native-nitro-modules') implementation "androidx.media3:media3-common:1.4.1" implementation "androidx.media3:media3-exoplayer:1.4.1" } ``` --- ## Useful Projects & Community Resources # Useful Projects This page lists open-source projects that can be helpful for your player implementation. If you have a project that could benefit other users, feel free to open a PR to add it here. ## Our (TheWidlarzGroup) Libraries - [react-native-video-player](https://github.com/TheWidlarzGroup/react-native-video-player): Our video player UI library. - [Offline Video SDK](https://sdk.thewidlarzgroup.com/offline-video?utm_source=rnv&utm_medium=docs&utm_campaign=projects&utm_id=offline-video-sdk): If you're building an app that needs **offline playback** (e.g., downloading HLS videos, subtitles, audio tracks, or DRM-protected content), check out our commercial Offline Video SDK. It integrates with `react-native-video` and is available with a [free trial](https://sdk.thewidlarzgroup.com/signup?utm_source=rnv&utm_medium=docs&utm_campaign=projects&utm_id=start-trial-offline-video-sdk). To get started quickly, you can clone our [Offline Video Starter Project](https://github.com/TheWidlarzGroup/react-native-offline-video-starter?utm_source=rnv&utm_medium=docs&utm_campaign=projects&utm_id=offline-video-starter), which includes a ready-to-run example app demonstrating offline playback, multi-audio, subtitles, and DRM setup. ## Community Libraries - [react-native-corner-video](https://github.com/Lg0gs/react-native-corner-video): A floating video player. - [react-native-track-player](https://github.com/doublesymmetry/react-native-track-player): A toolbox for audio playback. - [react-native-video-controls](https://github.com/itsnubix/react-native-video-controls): A video player UI. - [react-native-media-console](https://github.com/criszz77/react-native-media-console): An updated version of react-native-video-controls, rewritten in TypeScript. --- ## Migration Guide — Upgrading from v6 to v7 # Updating ## Upgrading from react-native-video v6 to v7 Version 7 of `react-native-video` introduces a significant architectural shift, separating the video player logic from the UI rendering. This change unlocks new capabilities like video preloading and a more intuitive, hook-based API. This guide will walk you through the necessary steps to migrate your application from v6 to v7. :::tip Migrate faster with an AI assistant Our agent skill knows the v6→v7 mapping. Install it with `npx skills add TheWidlarzGroup/react-native-video` and let your editor rewrite `Video` calls into the `useVideoPlayer` + `VideoView` model. See [Build with AI](./build-with-ai/overview.mdx). ::: ### Key Changes in v7 The most substantial change in v7 is the move from a monolithic `` component to a more modular approach with two distinct components: * **`VideoPlayer`**: A new class that manages the player's state and playback logic. It is not a UI component. * **`VideoView`**: A UI component responsible for rendering the video on the screen. It takes a `VideoPlayer` instance as a prop. * **`useVideoPlayer` hook**: The recommended way to create and manage the lifecycle of a `VideoPlayer` instance within a functional component. It automatically handles the creation and cleanup of the player. ### New Dependency `react-native-video` v7 is now built on top of [`react-native-nitro-modules`](https://nitro.margelo.com/docs/what-is-nitro) framework. This means that you need to install the Nitro framework to use `react-native-video` v7. ### Step-by-Step Migration Guide #### 1. Installation First, update the `react-native-video` package to the latest v7 release: ```bash npm install react-native-video@next --save ``` Then, install the pods for iOS: ```bash cd ios && pod install ``` #### 2. Updating Your Component The core of the migration involves replacing the `` component with the new `useVideoPlayer` hook and `` component. **v6 Implementation:** ```jsx import React, { useRef } from 'react'; import Video from 'react-native-video'; const VideoPlayerV6 = () => { const videoRef = useRef(null); return ( console.log('Video loaded')} onProgress={(data) => console.log('Progress:', data.currentTime)} /> ); }; ``` **v7 Implementation:** ```jsx import React from 'react'; import { useVideoPlayer, VideoView, useEvent } from 'react-native-video'; const VideoPlayerV7 = () => { const player = useVideoPlayer({ source: { uri: 'https://www.w3schools.com/html/mov_bbb.mp4', }, }); useEvent(player, 'onLoad', () => { console.log('Video loaded'); }); useEvent(player, 'onProgress', (data) => { console.log('Progress:', data.currentTime); }); return ( ); }; ``` ### Prop and Method Migration Many props and methods from the v6 `` component have been moved to the `VideoPlayer` instance in v7. #### Common Props | v6 Prop (``) | v7 Equivalent (`VideoPlayer` properties) | Notes | | :--- | :--- | :--- | | `source` | `source` property in `useVideoPlayer` config | The structure of the source object remains largely the same. | | `paused` | `paused` property on the `VideoPlayer` instance | Can be controlled via `player.pause()` and `player.play()`. | | `muted` | `muted` property on the `VideoPlayer` instance | `player.muted = true/false;` | | `volume` | `volume` property on the `VideoPlayer` instance | `player.volume = 0.5;` | | `rate` | `rate` property on the `VideoPlayer` instance | `player.rate = 1.5;` | | `loop` | `loop` property on the `VideoPlayer` instance | `player.loop = true;` | | `resizeMode` | `resizeMode` prop on `` | This remains a prop on the UI component. | | `controls` | `controls` prop on `` | This also remains on the UI component. | see [VideoPlayer](./player/player.md) for more details. #### Methods Imperative methods previously called on the `` component's ref are now methods on the `VideoPlayer` instance. | v6 Method (`videoRef.current`) | v7 Equivalent (`player`) | | :--- | :--- | | `seek(time)` | `player.seekTo(time)` | | `presentFullscreenPlayer()` | `videoViewRef.current.enterFullscreen()` | Fullscreen is now managed by the `VideoView` ref. | | `dismissFullscreenPlayer()` | `videoViewRef.current.exitFullscreen()` | | | `pause()` | `player.pause()` | | | `resume()` | `player.play()` | | see [VideoPlayer](./player/player.md) for more details. ### Event Handling In v7, event handling is standardized through the `useEvent` hook or by directly assigning callbacks to the `VideoPlayer` instance. The `useEvent` hook is recommended as it automatically handles listener cleanup. **v6 Event Handling:** ```jsx console.log(data)} onProgress={(data) => console.log(data.currentTime)} onError={(error) => console.error(error)} /> ``` **v7 Event Handling with `useEvent`:** ```jsx import { useVideoPlayer, VideoView, useEvent } from 'react-native-video'; const MyPlayer = () => { const player = useVideoPlayer({ source: { uri: '...' } }); useEvent(player, 'onLoad', (data) => console.log(data)); useEvent(player, 'onProgress', (data) => console.log(data.currentTime)); useEvent(player, 'onError', (error) => console.error(error.code, error.message)); return ; } ``` **Directly assigning callbacks in v7:** ```jsx const player = useVideoPlayer('https://example.com/video.mp4', (_player) => { _player.onLoad = (data) => { console.log('Video loaded! Duration:', data.duration); }; _player.onError = (error) => { console.error('Player Error:', error.code, error.message); }; }); ``` ### Benefits of the New Architecture * **Preloading**: You can create a `VideoPlayer` instance and begin loading a video before it's visible in the UI. When you're ready to display it, simply pass the player instance to a ``. * **Improved Performance**: Separating the player logic from the UI rendering can lead to better performance and a more responsive application. * **Cleaner API**: The hook-based API simplifies player management and reduces boilerplate code, especially for handling the player's lifecycle. * **Full New Architecture Support**: Version 7 fully embraces React Native's New Architecture, ensuring better performance and consistency. --- ## Video Chapters — Seekbar Markers & Navigation # Chapters The `VideoView` component supports video chapters, allowing users to navigate through different segments of a video. Chapters appear as visual markers on the seekbar and can be used to jump to specific points in the video. Your browser does not support the video tag. ## Installation To use chapters functionality, you need to install the `@react-native-video/chapters` package: ```bash npm install @react-native-video/chapters ``` ## Getting Started First, enable the chapters functionality by calling `enable()`: ```tsx import { enable } from '@react-native-video/chapters'; enable(); ``` ## API ### `enable()` Enables the chapters functionality. Must be called before using other chapter methods. ### `setChapters(chapters, options?)` Sets the chapters for the video player. **Parameters:** - `chapters`: Array of chapter objects with the following structure: ```tsx { title: string; // Chapter title timeMs: number; // Chapter time in milliseconds }[] ``` - `options` (optional): Configuration object - `markersColor?: string` - Color of the chapter markers (default: platform default) - `showTooltip?: boolean` - Whether to show tooltip when hovering over markers (default: `true`) - `showTimer?: boolean` - Whether to show timer on markers (default: `true`) **Example:** ```tsx import { setChapters } from '@react-native-video/chapters'; const chapters = [ { title: "Introduction", timeMs: 0 }, { title: "Main Content", timeMs: 30000 }, // 30 seconds { title: "Conclusion", timeMs: 120000 }, // 2 minutes ]; setChapters(chapters, { markersColor: "#FF6B35", showTooltip: true, showTimer: true, }); ``` ### `clearChapters()` Removes all chapters from the video player. ```tsx import { clearChapters } from '@react-native-video/chapters'; clearChapters(); ``` ### `goToChapter(title)` Programmatically navigates to a specific chapter by its title. **Parameters:** - `title`: The title of the chapter to navigate to ```tsx import { goToChapter } from '@react-native-video/chapters'; goToChapter("Main Content"); ``` ## Platform Differences - **iOS**: Custom seekbar with visual markers and tooltip - **Android**: Visual markers on seekbar with tooltip --- ## VideoView Events — Fullscreen & PiP Callbacks # Events `VideoView` also accepts several event callback props related to UI state changes: | Event | Type | Description | |-------|------|-------------| | `onPictureInPictureChange?` | `(event: { isActive: boolean }) => void` | Fired when the picture-in-picture mode starts or stops. | | `onFullscreenChange?` | `(event: { isFullscreen: boolean }) => void` | Fired when the fullscreen mode starts or stops. | | `willEnterFullscreen?` | `() => void` | Fired just before the view enters fullscreen mode. | | `willExitFullscreen?` | `() => void` | Fired just before the view exits fullscreen mode. | | `willEnterPictureInPicture?` | `() => void` | Fired just before the view enters picture-in-picture mode. | | `willExitPictureInPicture?` | `() => void` | Fired just before the view exits picture-in-picture mode. | These can be used to update your component's state or UI in response to these changes. ```tsx { console.log(isFullscreen ? 'Entered fullscreen' : 'Exited fullscreen'); }} onPictureInPictureChange={({ isActive }) => { console.log(isActive ? 'PiP active' : 'PiP inactive'); }} /> ``` --- ## VideoView Methods — Fullscreen & PiP Control # Refs and Imperative Methods You can obtain a ref to the `VideoView` component to call imperative methods: ```tsx const videoViewRef = React.useRef(null); // ... // Later, you can call methods like: videoViewRef.current?.enterFullscreen(); ``` Available methods on the `VideoViewRef`: | Method | Type | Description | |--------|------|-------------| | `enterFullscreen()` | `() => void` | Programmatically requests the video view to enter fullscreen mode. | | `exitFullscreen()` | `() => void` | Programmatically requests the video view to exit fullscreen mode. | | `enterPictureInPicture()` | `() => void` | Programmatically requests the video view to enter picture-in-picture mode. | | `exitPictureInPicture()` | `() => void` | Programmatically requests the video view to exit picture-in-picture mode. | | `canEnterPictureInPicture()` | `() => boolean` | Checks if picture-in-picture mode is currently available and supported. Returns `true` if PiP can be entered, `false` otherwise. | --- ## VideoView Props — Controls, PiP & Resize Mode # Props | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | `player` | `VideoPlayer` | Yes | - | The `VideoPlayer` instance that manages the video to be displayed. | | `style` | `ViewStyle` | No | - | Standard React Native styles to control the layout and appearance of the `VideoView`. | | `controls` | `boolean` | No | `false` | Whether to show the native video playback controls (play/pause, seek bar, volume, etc.). | | `pictureInPicture` | `boolean` | No | `false` | Whether to enable and show the picture-in-picture (PiP) button in the native controls (if supported by the platform and controls are visible). | | `autoEnterPictureInPicture` | `boolean` | No | `false` | Whether the video should automatically enter PiP mode when it starts playing and the app is backgrounded (behavior might vary by platform). | | `resizeMode` | `'contain' \| 'cover' \| 'stretch' \| 'none'` | No | `'none'` | How the video should be resized to fit the view. | | `keepScreenAwake` | `boolean` | No | `true` | Whether to keep the device screen awake while the video view is mounted. | | `surfaceType` | `'surface' \| 'texture'` | No (Android only) | `'surface'` | (Android) Underlying native view type. `'surface'` uses a SurfaceView (better performance, no transforms/overlap), `'texture'` uses a TextureView (supports animations, transforms, overlapping UI) at a small performance cost. Ignored on iOS. | ## Android: Choosing a surface type :::info Android Only This section applies only to Android. The `surfaceType` prop is ignored on iOS. ::: On Android the default rendering path uses a `SurfaceView` (set via `surfaceType="surface"`) for optimal decoding performance and lower latency. However `SurfaceView` lives in a separate window and can't be: - Animated with transforms (scale, rotate, opacity fade) - Clipped by parent views (rounded corners, masks) - Overlapped reliably with sibling views (z-order issues) If you need those UI effects, switch to `TextureView`: ```tsx ``` Use `TextureView` only when required, as it can be slightly less performant and may increase power consumption on some devices. --- ## VideoView — Native Video Rendering Component # VideoView Component The `VideoView` component is responsible for rendering the video content managed by a `VideoPlayer` instance onto the screen. It also provides UI functionalities like native controls, fullscreen, and picture-in-picture mode. ## Basic Usage To use `VideoView`, you need to pass a `VideoPlayer` instance to its `player` prop. ```tsx import React from 'react'; import { VideoPlayer, VideoView } from 'react-native-video'; import { StyleSheet } from 'react-native'; const App = () => { const player = useVideoPlayer('https://example.com/video.mp4', (_player) => { // This is optional setup function that will be called when the player is created. _player.play(); }); return ( ); }; const styles = StyleSheet.create({ video: { width: '100%', height: 200, }, }); export default App; ```