chore: lint project (#3279)

* chore: update eslint config
* chore: lint lib files
This commit is contained in:
Krzysztof Moch 2023-10-07 12:56:35 +02:00 committed by GitHub
parent e6e8f621fe
commit 067adde124
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 521 additions and 354 deletions

View File

@ -1 +1,2 @@
examples/ examples/
lib/

View File

@ -1,10 +1,13 @@
{ {
"plugins": ["@typescript-eslint"],
"extends": [ "extends": [
"@react-native", "@react-native",
"eslint:recommended", "eslint:recommended",
"plugin:react/recommended" "plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
], ],
"parserOptions": { "parserOptions": {
"requireConfigFile": false "requireConfigFile": false
} }
} }

View File

@ -6,17 +6,21 @@ import React, {
forwardRef, forwardRef,
useImperativeHandle, useImperativeHandle,
type ComponentRef, type ComponentRef,
} from "react"; } from 'react';
import { import {View, StyleSheet, Image, Platform} from 'react-native';
View, import NativeVideoComponent, {RCTVideoConstants} from './VideoNativeComponent';
StyleSheet, import type {
Image, NativeVideoResizeMode,
Platform, OnAudioFocusChangedData,
} from "react-native"; OnAudioTracksData,
import NativeVideoComponent, { RCTVideoConstants } from "./VideoNativeComponent"; OnPlaybackStateChangedData,
import type { NativeVideoResizeMode, OnAudioFocusChangedData, OnAudioTracksData, OnPlaybackStateChangedData, OnTextTracksData, OnTimedMetadataData, OnVideoErrorData, OnVideoTracksData } from './VideoNativeComponent' OnTextTracksData,
OnTimedMetadataData,
OnVideoErrorData,
OnVideoTracksData,
} from './VideoNativeComponent';
import type { StyleProp, ImageStyle, NativeSyntheticEvent } from "react-native"; import type {StyleProp, ImageStyle, NativeSyntheticEvent} from 'react-native';
import { import {
type VideoComponentType, type VideoComponentType,
type OnLoadData, type OnLoadData,
@ -30,9 +34,9 @@ import {
type OnExternalPlaybackChangeData, type OnExternalPlaybackChangeData,
type OnReceiveAdEventData, type OnReceiveAdEventData,
VideoManager, VideoManager,
} from "./VideoNativeComponent"; } from './VideoNativeComponent';
import type { ReactVideoProps } from "./types/video"; import type {ReactVideoProps} from './types/video';
import { getReactTag, resolveAssetSourceForVideo } from "./utils"; import {getReactTag, resolveAssetSourceForVideo} from './utils';
export interface VideoRef { export interface VideoRef {
seek: (time: number, tolerance?: number) => void; seek: (time: number, tolerance?: number) => void;
@ -40,7 +44,9 @@ export interface VideoRef {
pause: () => void; pause: () => void;
presentFullscreenPlayer: () => void; presentFullscreenPlayer: () => void;
dismissFullscreenPlayer: () => void; dismissFullscreenPlayer: () => void;
restoreUserInterfaceForPictureInPictureStopCompleted: (restore: boolean) => void; restoreUserInterfaceForPictureInPictureStopCompleted: (
restore: boolean,
) => void;
} }
const Video = forwardRef<VideoRef, ReactVideoProps>( const Video = forwardRef<VideoRef, ReactVideoProps>(
@ -84,7 +90,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onVideoTracks, onVideoTracks,
...rest ...rest
}, },
ref ref,
) => { ) => {
const nativeRef = useRef<ComponentRef<VideoComponentType>>(null); const nativeRef = useRef<ComponentRef<VideoComponentType>>(null);
const [showPoster, setShowPoster] = useState(!!poster); const [showPoster, setShowPoster] = useState(!!poster);
@ -98,25 +104,31 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
() => ({ () => ({
...StyleSheet.absoluteFillObject, ...StyleSheet.absoluteFillObject,
resizeMode: resizeMode:
posterResizeMode && posterResizeMode !== "none" posterResizeMode && posterResizeMode !== 'none'
? posterResizeMode ? posterResizeMode
: "contain", : 'contain',
}), }),
[posterResizeMode] [posterResizeMode],
); );
const src = useMemo(() => { const src = useMemo(() => {
if (!source) return undefined; if (!source) {
return undefined;
}
const resolvedSource = resolveAssetSourceForVideo(source); const resolvedSource = resolveAssetSourceForVideo(source);
let uri = resolvedSource.uri || ""; let uri = resolvedSource.uri || '';
if (uri && uri.match(/^\//)) uri = `file://${uri}`; if (uri && uri.match(/^\//)) {
if (!uri) console.warn("Trying to load empty source"); uri = `file://${uri}`;
}
if (!uri) {
console.warn('Trying to load empty source');
}
const isNetwork = !!(uri && uri.match(/^https?:/)); const isNetwork = !!(uri && uri.match(/^https?:/));
const isAsset = !!( const isAsset = !!(
uri && uri &&
uri.match( uri.match(
/^(assets-library|ipod-library|file|content|ms-appx|ms-appdata):/ /^(assets-library|ipod-library|file|content|ms-appx|ms-appdata):/,
) )
); );
@ -125,22 +137,22 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
isNetwork, isNetwork,
isAsset, isAsset,
shouldCache: resolvedSource.shouldCache || false, shouldCache: resolvedSource.shouldCache || false,
type: resolvedSource.type || "", type: resolvedSource.type || '',
mainVer: resolvedSource.mainVer || 0, mainVer: resolvedSource.mainVer || 0,
patchVer: resolvedSource.patchVer || 0, patchVer: resolvedSource.patchVer || 0,
requestHeaders: resolvedSource?.headers || {}, requestHeaders: resolvedSource?.headers || {},
startTime: resolvedSource.startTime || 0, startTime: resolvedSource.startTime || 0,
endTime: resolvedSource.endTime endTime: resolvedSource.endTime,
}; };
}, [source]); }, [source]);
const _resizeMode: NativeVideoResizeMode = useMemo(() => { const _resizeMode: NativeVideoResizeMode = useMemo(() => {
switch (resizeMode) { switch (resizeMode) {
case "contain": case 'contain':
return RCTVideoConstants.ScaleAspectFit; return RCTVideoConstants.ScaleAspectFit;
case "cover": case 'cover':
return RCTVideoConstants.ScaleAspectFill; return RCTVideoConstants.ScaleAspectFill;
case "stretch": case 'stretch':
return RCTVideoConstants.ScaleToFill; return RCTVideoConstants.ScaleToFill;
default: default:
return RCTVideoConstants.ScaleNone; return RCTVideoConstants.ScaleNone;
@ -148,7 +160,9 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
}, [resizeMode]); }, [resizeMode]);
const _drm = useMemo(() => { const _drm = useMemo(() => {
if (!drm) return; if (!drm) {
return;
}
return { return {
drmType: drm.type, drmType: drm.type,
licenseServer: drm.licenseServer, licenseServer: drm.licenseServer,
@ -160,59 +174,64 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
}; };
}, [drm]); }, [drm]);
const _selectedTextTrack = useMemo(() => { const _selectedTextTrack = useMemo(() => {
if (!selectedTextTrack) return; if (!selectedTextTrack) {
if (typeof selectedTextTrack?.value === 'number') return { return;
seletedTextType: selectedTextTrack?.type, }
index: selectedTextTrack?.value, if (typeof selectedTextTrack?.value === 'number') {
return {
selectedTextType: selectedTextTrack?.type,
index: selectedTextTrack?.value,
};
} }
return { return {
selectedTextType: selectedTextTrack?.type, selectedTextType: selectedTextTrack?.type,
value: selectedTextTrack?.value, value: selectedTextTrack?.value,
} };
}, [selectedTextTrack]); }, [selectedTextTrack]);
const _selectedAudioTrack = useMemo(() => { const _selectedAudioTrack = useMemo(() => {
if (!selectedAudioTrack) return; if (!selectedAudioTrack) {
if (typeof selectedAudioTrack?.value === 'number') return { return;
selectedAudioType: selectedAudioTrack?.type, }
index: selectedAudioTrack?.value, if (typeof selectedAudioTrack?.value === 'number') {
return {
selectedAudioType: selectedAudioTrack?.type,
index: selectedAudioTrack?.value,
};
} }
return { return {
selectedAudioType: selectedAudioTrack?.type, selectedAudioType: selectedAudioTrack?.type,
value: selectedAudioTrack?.value, value: selectedAudioTrack?.value,
} };
}, [selectedAudioTrack]); }, [selectedAudioTrack]);
const seek = useCallback(async (time: number, tolerance?: number) => {
if (isNaN(time)) {
throw new Error('Specified time is not a number');
}
const seek = useCallback( if (!nativeRef.current) {
async (time: number, tolerance?: number) => { console.warn('Video Component is not mounted');
if (isNaN(time)) throw new Error("Specified time is not a number"); return;
}
if (!nativeRef.current) { Platform.select({
console.warn("Video Component is not mounted"); ios: () => {
return; nativeRef.current?.setNativeProps({
} seek: {
time,
Platform.select({ tolerance,
ios: () => { },
nativeRef.current?.setNativeProps({ });
seek: { },
time, default: () => {
tolerance, nativeRef.current?.setNativeProps({
}, seek: time,
}); });
}, },
default: () => { })();
nativeRef.current?.setNativeProps({ }, []);
seek: time,
});
},
})();
},
[]
);
const presentFullscreenPlayer = useCallback(() => { const presentFullscreenPlayer = useCallback(() => {
setIsFullscreen(true); setIsFullscreen(true);
@ -238,79 +257,93 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
(restored: boolean) => { (restored: boolean) => {
setRestoreUserInterfaceForPIPStopCompletionHandler(restored); setRestoreUserInterfaceForPIPStopCompletionHandler(restored);
}, },
[setRestoreUserInterfaceForPIPStopCompletionHandler] [setRestoreUserInterfaceForPIPStopCompletionHandler],
); );
const onVideoLoadStart = useCallback( const onVideoLoadStart = useCallback(
(e: NativeSyntheticEvent<OnLoadStartData>) => { (e: NativeSyntheticEvent<OnLoadStartData>) => {
onLoadStart?.(e.nativeEvent); onLoadStart?.(e.nativeEvent);
}, },
[onLoadStart] [onLoadStart],
); );
const onVideoLoad = useCallback( const onVideoLoad = useCallback(
(e: NativeSyntheticEvent<OnLoadData>) => { (e: NativeSyntheticEvent<OnLoadData>) => {
if (Platform.OS === "windows") setShowPoster(false); if (Platform.OS === 'windows') {
setShowPoster(false);
}
onLoad?.(e.nativeEvent); onLoad?.(e.nativeEvent);
}, },
[onLoad, setShowPoster] [onLoad, setShowPoster],
); );
const onVideoError = useCallback( const onVideoError = useCallback(
(e: NativeSyntheticEvent<OnVideoErrorData>) => { (e: NativeSyntheticEvent<OnVideoErrorData>) => {
onError?.(e.nativeEvent); onError?.(e.nativeEvent);
}, },
[onError] [onError],
); );
const onVideoProgress = useCallback( const onVideoProgress = useCallback(
(e: NativeSyntheticEvent<OnProgressData>) => { (e: NativeSyntheticEvent<OnProgressData>) => {
onProgress?.(e.nativeEvent); onProgress?.(e.nativeEvent);
}, },
[onProgress] [onProgress],
); );
const onVideoSeek = useCallback( const onVideoSeek = useCallback(
(e: NativeSyntheticEvent<OnSeekData>) => { (e: NativeSyntheticEvent<OnSeekData>) => {
onSeek?.(e.nativeEvent); onSeek?.(e.nativeEvent);
}, },
[onSeek] [onSeek],
); );
// android only // android only
const onVideoPlaybackStateChanged = useCallback((e: NativeSyntheticEvent<OnPlaybackStateChangedData>) => { const onVideoPlaybackStateChanged = useCallback(
onPlaybackStateChanged?.(e.nativeEvent); (e: NativeSyntheticEvent<OnPlaybackStateChangedData>) => {
}, [onPlaybackStateChanged]) onPlaybackStateChanged?.(e.nativeEvent);
},
[onPlaybackStateChanged],
);
// android only // android only
const onVideoIdle = useCallback(() => { const onVideoIdle = useCallback(() => {
onIdle?.() onIdle?.();
}, [onIdle]) }, [onIdle]);
const _onTimedMetadata = useCallback( const _onTimedMetadata = useCallback(
(e: NativeSyntheticEvent<OnTimedMetadataData>) => { (e: NativeSyntheticEvent<OnTimedMetadataData>) => {
onTimedMetadata?.(e.nativeEvent); onTimedMetadata?.(e.nativeEvent);
}, },
[onTimedMetadata] [onTimedMetadata],
); );
const _onAudioTracks = useCallback((e: NativeSyntheticEvent<OnAudioTracksData>) => { const _onAudioTracks = useCallback(
onAudioTracks?.(e.nativeEvent) (e: NativeSyntheticEvent<OnAudioTracksData>) => {
}, [onAudioTracks]) onAudioTracks?.(e.nativeEvent);
},
[onAudioTracks],
);
const _onTextTracks = useCallback((e: NativeSyntheticEvent<OnTextTracksData>) => { const _onTextTracks = useCallback(
onTextTracks?.(e.nativeEvent) (e: NativeSyntheticEvent<OnTextTracksData>) => {
}, [onTextTracks]) onTextTracks?.(e.nativeEvent);
},
[onTextTracks],
);
const _onVideoTracks = useCallback((e: NativeSyntheticEvent<OnVideoTracksData>) => { const _onVideoTracks = useCallback(
onVideoTracks?.(e.nativeEvent) (e: NativeSyntheticEvent<OnVideoTracksData>) => {
}, [onVideoTracks]) onVideoTracks?.(e.nativeEvent);
},
[onVideoTracks],
);
const _onPlaybackRateChange = useCallback( const _onPlaybackRateChange = useCallback(
(e: NativeSyntheticEvent<Readonly<{ playbackRate: number }>>) => { (e: NativeSyntheticEvent<Readonly<{playbackRate: number}>>) => {
onPlaybackRateChange?.(e.nativeEvent); onPlaybackRateChange?.(e.nativeEvent);
}, },
[onPlaybackRateChange] [onPlaybackRateChange],
); );
const _onReadyForDisplay = useCallback(() => { const _onReadyForDisplay = useCallback(() => {
@ -322,51 +355,91 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
(e: NativeSyntheticEvent<OnPictureInPictureStatusChangedData>) => { (e: NativeSyntheticEvent<OnPictureInPictureStatusChangedData>) => {
onPictureInPictureStatusChanged?.(e.nativeEvent); onPictureInPictureStatusChanged?.(e.nativeEvent);
}, },
[onPictureInPictureStatusChanged] [onPictureInPictureStatusChanged],
); );
const _onAudioFocusChanged = useCallback((e: NativeSyntheticEvent<OnAudioFocusChangedData>) => { const _onAudioFocusChanged = useCallback(
onAudioFocusChanged?.(e.nativeEvent) (e: NativeSyntheticEvent<OnAudioFocusChangedData>) => {
}, [onAudioFocusChanged]) onAudioFocusChanged?.(e.nativeEvent);
},
[onAudioFocusChanged],
);
const onVideoBuffer = useCallback((e: NativeSyntheticEvent<OnBufferData>) => { const onVideoBuffer = useCallback(
onBuffer?.(e.nativeEvent); (e: NativeSyntheticEvent<OnBufferData>) => {
}, [onBuffer]); onBuffer?.(e.nativeEvent);
},
[onBuffer],
);
const onVideoExternalPlaybackChange = useCallback((e: NativeSyntheticEvent<OnExternalPlaybackChangeData>) => { const onVideoExternalPlaybackChange = useCallback(
onExternalPlaybackChange?.(e.nativeEvent); (e: NativeSyntheticEvent<OnExternalPlaybackChangeData>) => {
}, [onExternalPlaybackChange]) onExternalPlaybackChange?.(e.nativeEvent);
},
[onExternalPlaybackChange],
);
const _onBandwidthUpdate = useCallback((e: NativeSyntheticEvent<OnBandwidthUpdateData>) => { const _onBandwidthUpdate = useCallback(
onBandwidthUpdate?.(e.nativeEvent); (e: NativeSyntheticEvent<OnBandwidthUpdateData>) => {
}, [onBandwidthUpdate]); onBandwidthUpdate?.(e.nativeEvent);
},
[onBandwidthUpdate],
);
const _onReceiveAdEvent = useCallback((e: NativeSyntheticEvent<OnReceiveAdEventData>) => { const _onReceiveAdEvent = useCallback(
onReceiveAdEvent?.(e.nativeEvent); (e: NativeSyntheticEvent<OnReceiveAdEventData>) => {
}, [onReceiveAdEvent]); onReceiveAdEvent?.(e.nativeEvent);
},
[onReceiveAdEvent],
);
const onGetLicense = useCallback( const onGetLicense = useCallback(
(event: NativeSyntheticEvent<OnGetLicenseData>) => { (event: NativeSyntheticEvent<OnGetLicenseData>) => {
if (drm && drm.getLicense instanceof Function) { if (drm && drm.getLicense instanceof Function) {
const data = event.nativeEvent; const data = event.nativeEvent;
if (data && data.spcBase64) { if (data && data.spcBase64) {
const getLicenseOverride = drm.getLicense(data.spcBase64, data.contentId, data.licenseUrl); const getLicenseOverride = drm.getLicense(
data.spcBase64,
data.contentId,
data.licenseUrl,
);
const getLicensePromise = Promise.resolve(getLicenseOverride); // Handles both scenarios, getLicenseOverride being a promise and not. const getLicensePromise = Promise.resolve(getLicenseOverride); // Handles both scenarios, getLicenseOverride being a promise and not.
getLicensePromise.then((result => { getLicensePromise
if (result !== undefined) { .then((result) => {
nativeRef.current && VideoManager.setLicenseResult(result, data.licenseUrl, getReactTag(nativeRef)); if (result !== undefined) {
} else { nativeRef.current &&
nativeRef.current && VideoManager.setLicenseResultError('Empty license result', data.licenseUrl, getReactTag(nativeRef)); VideoManager.setLicenseResult(
} result,
})).catch(() => { data.licenseUrl,
nativeRef.current && VideoManager.setLicenseResultError('fetch error', data.licenseUrl, getReactTag(nativeRef)); getReactTag(nativeRef),
}); );
} else {
nativeRef.current &&
VideoManager.setLicenseResultError(
'Empty license result',
data.licenseUrl,
getReactTag(nativeRef),
);
}
})
.catch(() => {
nativeRef.current &&
VideoManager.setLicenseResultError(
'fetch error',
data.licenseUrl,
getReactTag(nativeRef),
);
});
} else { } else {
VideoManager.setLicenseResultError('No spc received', data.licenseUrl, getReactTag(nativeRef)); VideoManager.setLicenseResultError(
'No spc received',
data.licenseUrl,
getReactTag(nativeRef),
);
} }
} }
}, },
[drm] [drm],
); );
useImperativeHandle( useImperativeHandle(
@ -388,7 +461,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
pause, pause,
resume, resume,
restoreUserInterfaceForPictureInPictureStopCompleted, restoreUserInterfaceForPictureInPictureStopCompleted,
] ],
); );
return ( return (
@ -438,12 +511,12 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onReceiveAdEvent={_onReceiveAdEvent} onReceiveAdEvent={_onReceiveAdEvent}
/> />
{showPoster ? ( {showPoster ? (
<Image style={posterStyle} source={{ uri: poster }} /> <Image style={posterStyle} source={{uri: poster}} />
) : null} ) : null}
</View> </View>
); );
} },
); );
Video.displayName = "Video"; Video.displayName = 'Video';
export default Video; export default Video;

View File

@ -1,11 +1,15 @@
import type { HostComponent, NativeSyntheticEvent, ViewProps } from 'react-native'; import type {
import { NativeModules, requireNativeComponent } from 'react-native'; HostComponent,
import { getViewManagerConfig } from './utils'; NativeSyntheticEvent,
ViewProps,
} from 'react-native';
import {NativeModules, requireNativeComponent} from 'react-native';
import {getViewManagerConfig} from './utils';
// -------- There are types for native component (future codegen) -------- // -------- There are types for native component (future codegen) --------
// if you are looking for types for react component, see src/types/video.ts // if you are looking for types for react component, see src/types/video.ts
type Headers = Record<string, any> type Headers = Record<string, string>;
type VideoSrc = Readonly<{ type VideoSrc = Readonly<{
uri?: string; uri?: string;
@ -18,25 +22,25 @@ type VideoSrc = Readonly<{
requestHeaders?: Headers; requestHeaders?: Headers;
startTime?: number; startTime?: number;
endTime?: number; endTime?: number;
}> }>;
export type Filter =
export type Filter = 'None' | | 'None'
'CIColorInvert' | | 'CIColorInvert'
'CIColorMonochrome' | | 'CIColorMonochrome'
'CIColorPosterize' | | 'CIColorPosterize'
'CIFalseColor' | | 'CIFalseColor'
'CIMaximumComponent' | | 'CIMaximumComponent'
'CIMinimumComponent' | | 'CIMinimumComponent'
'CIPhotoEffectChrome' | | 'CIPhotoEffectChrome'
'CIPhotoEffectFade' | | 'CIPhotoEffectFade'
'CIPhotoEffectInstant' | | 'CIPhotoEffectInstant'
'CIPhotoEffectMono' | | 'CIPhotoEffectMono'
'CIPhotoEffectNoir' | | 'CIPhotoEffectNoir'
'CIPhotoEffectProcess' | | 'CIPhotoEffectProcess'
'CIPhotoEffectTonal' | | 'CIPhotoEffectTonal'
'CIPhotoEffectTransfer' | | 'CIPhotoEffectTransfer'
'CISepiaTone'; | 'CISepiaTone';
export type DrmType = 'widevine' | 'playready' | 'clearkey' | 'fairplay'; export type DrmType = 'widevine' | 'playready' | 'clearkey' | 'fairplay';
@ -48,14 +52,16 @@ type Drm = Readonly<{
certificateUrl?: string; // ios certificateUrl?: string; // ios
base64Certificate?: boolean; // ios default: false base64Certificate?: boolean; // ios default: false
useExternalGetLicense?: boolean; // ios useExternalGetLicense?: boolean; // ios
}> }>;
type TextTracks = ReadonlyArray<Readonly<{ type TextTracks = ReadonlyArray<
title: string; Readonly<{
language: string; title: string;
type: string; language: string;
uri: string; type: string;
}>> uri: string;
}>
>;
type TextTrackType = 'system' | 'disabled' | 'title' | 'language' | 'index'; type TextTrackType = 'system' | 'disabled' | 'title' | 'language' | 'index';
@ -63,7 +69,7 @@ type SelectedTextTrack = Readonly<{
selectedTextType: TextTrackType; selectedTextType: TextTrackType;
value?: string; value?: string;
index?: number; index?: number;
}> }>;
type AudioTrackType = 'system' | 'disabled' | 'title' | 'language' | 'index'; type AudioTrackType = 'system' | 'disabled' | 'title' | 'language' | 'index';
@ -71,12 +77,12 @@ type SelectedAudioTrack = Readonly<{
selectedAudioType: AudioTrackType; selectedAudioType: AudioTrackType;
value?: string; value?: string;
index?: number; index?: number;
}> }>;
export type Seek = Readonly<{ export type Seek = Readonly<{
time: number; time: number;
tolerance?: number; tolerance?: number;
}> }>;
type BufferConfig = Readonly<{ type BufferConfig = Readonly<{
minBufferMs?: number; minBufferMs?: number;
@ -86,12 +92,12 @@ type BufferConfig = Readonly<{
maxHeapAllocationPercent?: number; maxHeapAllocationPercent?: number;
minBackBufferMemoryReservePercent?: number; minBackBufferMemoryReservePercent?: number;
minBufferMemoryReservePercent?: number; minBufferMemoryReservePercent?: number;
}> }>;
type SelectedVideoTrack = Readonly<{ type SelectedVideoTrack = Readonly<{
type: 'auto' | 'disabled' | 'resolution' | 'index'; type: 'auto' | 'disabled' | 'resolution' | 'index';
value?: number; value?: number;
}> }>;
type SubtitleStyle = Readonly<{ type SubtitleStyle = Readonly<{
fontSize?: number; fontSize?: number;
@ -99,7 +105,7 @@ type SubtitleStyle = Readonly<{
paddingBottom?: number; paddingBottom?: number;
paddingLeft?: number; paddingLeft?: number;
paddingRight?: number; paddingRight?: number;
}> }>;
export type OnLoadData = Readonly<{ export type OnLoadData = Readonly<{
currentTime: number; currentTime: number;
@ -109,22 +115,21 @@ export type OnLoadData = Readonly<{
height: number; height: number;
orientation: 'portrait' | 'landscape'; orientation: 'portrait' | 'landscape';
}>; }>;
}> }>;
export type OnLoadStartData = Readonly<{ export type OnLoadStartData = Readonly<{
isNetwork: boolean; isNetwork: boolean;
type: string; type: string;
uri: string; uri: string;
}> }>;
export type OnBufferData = Readonly<{ isBuffering: boolean }>;
export type OnBufferData = Readonly<{isBuffering: boolean}>;
export type OnProgressData = Readonly<{ export type OnProgressData = Readonly<{
currentTime: number; currentTime: number;
playableDuration: number; playableDuration: number;
seekableDuration: number; seekableDuration: number;
}> }>;
export type OnBandwidthUpdateData = Readonly<{ export type OnBandwidthUpdateData = Readonly<{
bitrate: number; bitrate: number;
@ -134,54 +139,61 @@ export type OnSeekData = Readonly<{
currentTime: number; currentTime: number;
seekTime: number; seekTime: number;
finished: boolean; finished: boolean;
}> }>;
export type OnPlaybackStateChangedData = Readonly<{ export type OnPlaybackStateChangedData = Readonly<{
isPlaying: boolean; isPlaying: boolean;
}> }>;
export type OnTimedMetadataData = Readonly<{ export type OnTimedMetadataData = Readonly<{
metadata: ReadonlyArray<Readonly<{ metadata: ReadonlyArray<
value?: string Readonly<{
identifier: string value?: string;
}>> identifier: string;
}> }>
>;
}>;
export type OnAudioTracksData = Readonly<{ export type OnAudioTracksData = Readonly<{
audioTracks: ReadonlyArray<Readonly<{ audioTracks: ReadonlyArray<
index: number Readonly<{
title?: string index: number;
language?: string title?: string;
bitrate?: number language?: string;
type?: string bitrate?: number;
selected?: boolean type?: string;
}>> selected?: boolean;
}> }>
>;
}>;
export type OnTextTracksData = Readonly<{ export type OnTextTracksData = Readonly<{
textTracks: ReadonlyArray<Readonly<{ textTracks: ReadonlyArray<
index: number Readonly<{
title?: string index: number;
language?: string title?: string;
/** language?: string;
* iOS only supports VTT, Android supports all 3 /**
*/ * iOS only supports VTT, Android supports all 3
type?: 'srt' | 'ttml' | 'vtt' */
selected?: boolean type?: 'srt' | 'ttml' | 'vtt';
}>> selected?: boolean;
}> }>
>;
}>;
export type OnVideoTracksData = Readonly<{ export type OnVideoTracksData = Readonly<{
videoTracks: ReadonlyArray<Readonly<{ videoTracks: ReadonlyArray<
trackId: number Readonly<{
codecs?: string trackId: number;
width?: number codecs?: string;
height?: number width?: number;
bitrate?: number height?: number;
selected?: boolean bitrate?: number;
}>> selected?: boolean;
}> }>
>;
}>;
export type OnPlaybackData = Readonly<{ export type OnPlaybackData = Readonly<{
playbackRate: number; playbackRate: number;
@ -189,31 +201,31 @@ export type OnPlaybackData = Readonly<{
export type OnExternalPlaybackChangeData = Readonly<{ export type OnExternalPlaybackChangeData = Readonly<{
isExternalPlaybackActive: boolean; isExternalPlaybackActive: boolean;
}> }>;
export type OnGetLicenseData = Readonly<{ export type OnGetLicenseData = Readonly<{
licenseUrl: string; licenseUrl: string;
contentId: string; contentId: string;
spcBase64: string; spcBase64: string;
}> }>;
export type OnPictureInPictureStatusChangedData = Readonly<{ export type OnPictureInPictureStatusChangedData = Readonly<{
isActive: boolean; isActive: boolean;
}> }>;
export type OnReceiveAdEventData = Readonly<{ export type OnReceiveAdEventData = Readonly<{
event: string; event: string;
}> }>;
export type OnVideoErrorData = Readonly<{ export type OnVideoErrorData = Readonly<{
error: string; error: string;
}> }>;
export type OnAudioFocusChangedData = Readonly<{ export type OnAudioFocusChangedData = Readonly<{
hasFocus: boolean; hasFocus: boolean;
}> }>;
export type NativeVideoResizeMode = 'ScaleNone' | 'ScaleToFill' | 'ScaleAspectFit' | 'ScaleAspectFill'; export type NativeVideoResizeMode = unknown;
export interface VideoNativeProps extends ViewProps { export interface VideoNativeProps extends ViewProps {
src?: VideoSrc; src?: VideoSrc;
drm?: Drm; drm?: Drm;
@ -222,7 +234,7 @@ export interface VideoNativeProps extends ViewProps {
maxBitRate?: number; maxBitRate?: number;
resizeMode?: NativeVideoResizeMode; resizeMode?: NativeVideoResizeMode;
repeat?: boolean; repeat?: boolean;
automaticallyWaitsToMinimizeStalling?: boolean automaticallyWaitsToMinimizeStalling?: boolean;
textTracks?: TextTracks; textTracks?: TextTracks;
selectedTextTrack?: SelectedTextTrack; selectedTextTrack?: SelectedTextTrack;
selectedAudioTrack?: SelectedAudioTrack; selectedAudioTrack?: SelectedAudioTrack;
@ -252,39 +264,63 @@ export interface VideoNativeProps extends ViewProps {
contentStartTime?: number; // Android contentStartTime?: number; // Android
currentPlaybackTime?: number; // Android currentPlaybackTime?: number; // Android
disableDisconnectError?: boolean; // Android disableDisconnectError?: boolean; // Android
focusable?: boolean; // Android focusable?: boolean; // Android
hideShutterView?: boolean; // Android hideShutterView?: boolean; // Android
minLoadRetryCount?: number; // Android minLoadRetryCount?: number; // Android
reportBandwidth?: boolean; //Android reportBandwidth?: boolean; //Android
selectedVideoTrack?: SelectedVideoTrack; // android selectedVideoTrack?: SelectedVideoTrack; // android
subtitleStyle?: SubtitleStyle // android subtitleStyle?: SubtitleStyle; // android
trackId?: string; // Android trackId?: string; // Android
useTextureView?: boolean; // Android useTextureView?: boolean; // Android
useSecureView?: boolean; // Android useSecureView?: boolean; // Android
onVideoLoad?: (event: NativeSyntheticEvent<OnLoadData>) => void; onVideoLoad?: (event: NativeSyntheticEvent<OnLoadData>) => void;
onVideoLoadStart?: (event: NativeSyntheticEvent<OnLoadStartData>) => void; onVideoLoadStart?: (event: NativeSyntheticEvent<OnLoadStartData>) => void;
onVideoBuffer?: (event: NativeSyntheticEvent<OnBufferData>) => void; onVideoBuffer?: (event: NativeSyntheticEvent<OnBufferData>) => void;
onVideoError?: (event: NativeSyntheticEvent<OnVideoErrorData>) => void; onVideoError?: (event: NativeSyntheticEvent<OnVideoErrorData>) => void;
onVideoProgress?: (event: NativeSyntheticEvent<OnProgressData>) => void; onVideoProgress?: (event: NativeSyntheticEvent<OnProgressData>) => void;
onBandwidthUpdate?: (event: NativeSyntheticEvent<OnBandwidthUpdateData>) => void; onBandwidthUpdate?: (
event: NativeSyntheticEvent<OnBandwidthUpdateData>,
) => void;
onVideoSeek?: (event: NativeSyntheticEvent<OnSeekData>) => void; onVideoSeek?: (event: NativeSyntheticEvent<OnSeekData>) => void;
onVideoEnd?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; // all onVideoEnd?: (event: NativeSyntheticEvent<Readonly<object>>) => void; // all
onVideoAudioBecomingNoisy?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; onVideoAudioBecomingNoisy?: (
onVideoFullscreenPlayerWillPresent?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; // ios, android event: NativeSyntheticEvent<Readonly<object>>,
onVideoFullscreenPlayerDidPresent?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; // ios, android ) => void;
onVideoFullscreenPlayerWillDismiss?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; // ios, android onVideoFullscreenPlayerWillPresent?: (
onVideoFullscreenPlayerDidDismiss?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; // ios, android event: NativeSyntheticEvent<Readonly<object>>,
onReadyForDisplay?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; ) => void; // ios, android
onVideoFullscreenPlayerDidPresent?: (
event: NativeSyntheticEvent<Readonly<object>>,
) => void; // ios, android
onVideoFullscreenPlayerWillDismiss?: (
event: NativeSyntheticEvent<Readonly<object>>,
) => void; // ios, android
onVideoFullscreenPlayerDidDismiss?: (
event: NativeSyntheticEvent<Readonly<object>>,
) => void; // ios, android
onReadyForDisplay?: (event: NativeSyntheticEvent<Readonly<object>>) => void;
onPlaybackRateChange?: (event: NativeSyntheticEvent<OnPlaybackData>) => void; // all onPlaybackRateChange?: (event: NativeSyntheticEvent<OnPlaybackData>) => void; // all
onVideoExternalPlaybackChange?: (event: NativeSyntheticEvent<OnExternalPlaybackChangeData>) => void; onVideoExternalPlaybackChange?: (
event: NativeSyntheticEvent<OnExternalPlaybackChangeData>,
) => void;
onGetLicense?: (event: NativeSyntheticEvent<OnGetLicenseData>) => void; onGetLicense?: (event: NativeSyntheticEvent<OnGetLicenseData>) => void;
onPictureInPictureStatusChanged?: (event: NativeSyntheticEvent<OnPictureInPictureStatusChangedData>) => void; onPictureInPictureStatusChanged?: (
onRestoreUserInterfaceForPictureInPictureStop?: (event: NativeSyntheticEvent<Readonly<{}>>) => void; event: NativeSyntheticEvent<OnPictureInPictureStatusChangedData>,
onReceiveAdEvent?: (event: NativeSyntheticEvent<OnReceiveAdEventData>) => void; ) => void;
onVideoPlaybackStateChanged?: (event: NativeSyntheticEvent<OnPlaybackStateChangedData>) => void; // android only onRestoreUserInterfaceForPictureInPictureStop?: (
onVideoIdle?: (event: NativeSyntheticEvent<{}>) => void; // android only (nowhere in document, so do not use as props. just type declaration) event: NativeSyntheticEvent<Readonly<object>>,
onAudioFocusChanged?: (event: NativeSyntheticEvent<OnAudioFocusChangedData>) => void; // android only (nowhere in document, so do not use as props. just type declaration) ) => void;
onReceiveAdEvent?: (
event: NativeSyntheticEvent<OnReceiveAdEventData>,
) => void;
onVideoPlaybackStateChanged?: (
event: NativeSyntheticEvent<OnPlaybackStateChangedData>,
) => void; // android only
onVideoIdle?: (event: NativeSyntheticEvent<object>) => void; // android only (nowhere in document, so do not use as props. just type declaration)
onAudioFocusChanged?: (
event: NativeSyntheticEvent<OnAudioFocusChangedData>,
) => void; // android only (nowhere in document, so do not use as props. just type declaration)
onTimedMetadata?: (event: NativeSyntheticEvent<OnTimedMetadataData>) => void; // ios, android onTimedMetadata?: (event: NativeSyntheticEvent<OnTimedMetadataData>) => void; // ios, android
onAudioTracks?: (event: NativeSyntheticEvent<OnAudioTracksData>) => void; // android onAudioTracks?: (event: NativeSyntheticEvent<OnAudioTracksData>) => void; // android
onTextTracks?: (event: NativeSyntheticEvent<OnTextTracksData>) => void; // android onTextTracks?: (event: NativeSyntheticEvent<OnTextTracksData>) => void; // android
@ -296,28 +332,45 @@ export type VideoComponentType = HostComponent<VideoNativeProps>;
export interface VideoManagerType { export interface VideoManagerType {
save: (reactTag: number) => Promise<void>; save: (reactTag: number) => Promise<void>;
setPlayerPauseState: (paused: boolean, reactTag: number) => Promise<void>; setPlayerPauseState: (paused: boolean, reactTag: number) => Promise<void>;
setLicenseResult: (result: string, licenseUrl: string, reactTag: number) => Promise<void>; setLicenseResult: (
setLicenseResultError: (error: string, licenseUrl: string, reactTag: number) => Promise<void>; result: string,
licenseUrl: string,
reactTag: number,
) => Promise<void>;
setLicenseResultError: (
error: string,
licenseUrl: string,
reactTag: number,
) => Promise<void>;
} }
export interface VideoDecoderPropertiesType { export interface VideoDecoderPropertiesType {
getWidevineLevel: () => Promise<number>; getWidevineLevel: () => Promise<number>;
isCodecSupported: (mimeType: string, width: number, height: number) => Promise<'unsupported' | 'hardware' | 'software'>; isCodecSupported: (
mimeType: string,
width: number,
height: number,
) => Promise<'unsupported' | 'hardware' | 'software'>;
isHEVCSupported: () => Promise<'unsupported' | 'hardware' | 'software'>; isHEVCSupported: () => Promise<'unsupported' | 'hardware' | 'software'>;
} }
export type VideoViewManagerConfig = { export type VideoViewManagerConfig = {
Constants: { Constants: {
ScaleNone: any; ScaleNone: unknown;
ScaleToFill: any; ScaleToFill: unknown;
ScaleAspectFit: any; ScaleAspectFit: unknown;
ScaleAspectFill: any; ScaleAspectFill: unknown;
}; };
Commands: { [key: string]: number; }; Commands: {[key: string]: number};
}; };
export const VideoManager = NativeModules.VideoManager as VideoManagerType; export const VideoManager = NativeModules.VideoManager as VideoManagerType;
export const VideoDecoderProperties = NativeModules.VideoDecoderProperties as VideoDecoderPropertiesType; export const VideoDecoderProperties =
export const RCTVideoConstants = (getViewManagerConfig('RCTVideo') as VideoViewManagerConfig).Constants; NativeModules.VideoDecoderProperties as VideoDecoderPropertiesType;
export const RCTVideoConstants = (
getViewManagerConfig('RCTVideo') as VideoViewManagerConfig
).Constants;
export default requireNativeComponent<VideoNativeProps>('RCTVideo') as VideoComponentType; export default requireNativeComponent<VideoNativeProps>(
'RCTVideo',
) as VideoComponentType;

View File

@ -1,11 +1,11 @@
import Video from "./Video"; import Video from './Video';
export { default as FilterType } from './lib/FilterType'; export {default as FilterType} from './lib/FilterType';
export { default as VideoResizeMode } from './lib/VideoResizeMode'; export {default as VideoResizeMode} from './lib/VideoResizeMode';
export { default as TextTrackType } from './lib/TextTrackType'; export {default as TextTrackType} from './lib/TextTrackType';
export { default as DRMType } from './lib/DRMType'; export {default as DRMType} from './lib/DRMType';
export { VideoDecoderProperties } from './VideoNativeComponent'; export {VideoDecoderProperties} from './VideoNativeComponent';
export type { VideoRef } from './Video'; export type {VideoRef} from './Video';
export default Video; export default Video;

View File

@ -1,6 +1,6 @@
export default { export default {
WIDEVINE: 'widevine', WIDEVINE: 'widevine',
PLAYREADY: 'playready', PLAYREADY: 'playready',
CLEARKEY: 'clearkey', CLEARKEY: 'clearkey',
FAIRPLAY: 'fairplay', FAIRPLAY: 'fairplay',
} as const; } as const;

View File

@ -1,18 +1,18 @@
export default { export default {
NONE: '', NONE: '',
INVERT: 'CIColorInvert', INVERT: 'CIColorInvert',
MONOCHROME: 'CIColorMonochrome', MONOCHROME: 'CIColorMonochrome',
POSTERIZE: 'CIColorPosterize', POSTERIZE: 'CIColorPosterize',
FALSE: 'CIFalseColor', FALSE: 'CIFalseColor',
MAXIMUMCOMPONENT: 'CIMaximumComponent', MAXIMUMCOMPONENT: 'CIMaximumComponent',
MINIMUMCOMPONENT: 'CIMinimumComponent', MINIMUMCOMPONENT: 'CIMinimumComponent',
CHROME: 'CIPhotoEffectChrome', CHROME: 'CIPhotoEffectChrome',
FADE: 'CIPhotoEffectFade', FADE: 'CIPhotoEffectFade',
INSTANT: 'CIPhotoEffectInstant', INSTANT: 'CIPhotoEffectInstant',
MONO: 'CIPhotoEffectMono', MONO: 'CIPhotoEffectMono',
NOIR: 'CIPhotoEffectNoir', NOIR: 'CIPhotoEffectNoir',
PROCESS: 'CIPhotoEffectProcess', PROCESS: 'CIPhotoEffectProcess',
TONAL: 'CIPhotoEffectTonal', TONAL: 'CIPhotoEffectTonal',
TRANSFER: 'CIPhotoEffectTransfer', TRANSFER: 'CIPhotoEffectTransfer',
SEPIA: 'CISepiaTone', SEPIA: 'CISepiaTone',
} as const; } as const;

View File

@ -2,4 +2,4 @@ export default {
contain: 'contain', contain: 'contain',
cover: 'cover', cover: 'cover',
stretch: 'stretch', stretch: 'stretch',
} as const; } as const;

View File

@ -1,30 +1,50 @@
import type { OnBandwidthUpdateData, OnBufferData, OnLoadData, OnLoadStartData, OnProgressData, OnSeekData, OnPlaybackData, OnExternalPlaybackChangeData, OnPictureInPictureStatusChangedData, OnReceiveAdEventData, OnVideoErrorData, OnPlaybackStateChangedData, OnAudioFocusChangedData, OnTimedMetadataData, OnAudioTracksData, OnTextTracksData, OnVideoTracksData } from "../VideoNativeComponent"; import type {
OnBandwidthUpdateData,
OnBufferData,
OnLoadData,
OnLoadStartData,
OnProgressData,
OnSeekData,
OnPlaybackData,
OnExternalPlaybackChangeData,
OnPictureInPictureStatusChangedData,
OnReceiveAdEventData,
OnVideoErrorData,
OnPlaybackStateChangedData,
OnAudioFocusChangedData,
OnTimedMetadataData,
OnAudioTracksData,
OnTextTracksData,
OnVideoTracksData,
} from '../VideoNativeComponent';
export interface ReactVideoEvents { export interface ReactVideoEvents {
onAudioBecomingNoisy?: () => void //Android, iOS onAudioBecomingNoisy?: () => void; //Android, iOS
onAudioFocusChanged?: (e: OnAudioFocusChangedData) => void // Android onAudioFocusChanged?: (e: OnAudioFocusChangedData) => void; // Android
onIdle?: () => void // Android onIdle?: () => void; // Android
onBandwidthUpdate?: (e: OnBandwidthUpdateData) => void //Android onBandwidthUpdate?: (e: OnBandwidthUpdateData) => void; //Android
onBuffer?: (e: OnBufferData) => void //Android, iOS onBuffer?: (e: OnBufferData) => void; //Android, iOS
onEnd?: () => void //All onEnd?: () => void; //All
onError?: (e: OnVideoErrorData) => void //Android, iOS onError?: (e: OnVideoErrorData) => void; //Android, iOS
onExternalPlaybackChange?: (e: OnExternalPlaybackChangeData) => void //iOS onExternalPlaybackChange?: (e: OnExternalPlaybackChangeData) => void; //iOS
onFullscreenPlayerWillPresent?: () => void //Android, iOS onFullscreenPlayerWillPresent?: () => void; //Android, iOS
onFullscreenPlayerDidPresent?: () => void //Android, iOS onFullscreenPlayerDidPresent?: () => void; //Android, iOS
onFullscreenPlayerWillDismiss?: () => void //Android, iOS onFullscreenPlayerWillDismiss?: () => void; //Android, iOS
onFullscreenPlayerDidDismiss?: () => void //Android, iOS onFullscreenPlayerDidDismiss?: () => void; //Android, iOS
onLoad?: (e: OnLoadData) => void //All onLoad?: (e: OnLoadData) => void; //All
onLoadStart?: (e: OnLoadStartData) => void //All onLoadStart?: (e: OnLoadStartData) => void; //All
onPictureInPictureStatusChanged?: (e: OnPictureInPictureStatusChangedData) => void //iOS onPictureInPictureStatusChanged?: (
onPlaybackRateChange?: (e: OnPlaybackData) => void //All e: OnPictureInPictureStatusChangedData,
onProgress?: (e: OnProgressData) => void //All ) => void; //iOS
onReadyForDisplay?: () => void //Android, iOS, Web onPlaybackRateChange?: (e: OnPlaybackData) => void; //All
onReceiveAdEvent?: (e: OnReceiveAdEventData) => void //Android, iOS onProgress?: (e: OnProgressData) => void; //All
onRestoreUserInterfaceForPictureInPictureStop?: () => void //iOS onReadyForDisplay?: () => void; //Android, iOS, Web
onSeek?: (e: OnSeekData) => void //Android, iOS, Windows UWP onReceiveAdEvent?: (e: OnReceiveAdEventData) => void; //Android, iOS
onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void // Android onRestoreUserInterfaceForPictureInPictureStop?: () => void; //iOS
onTimedMetadata?: (e: OnTimedMetadataData) => void //Android, iOS onSeek?: (e: OnSeekData) => void; //Android, iOS, Windows UWP
onAudioTracks?: (e: OnAudioTracksData) => void // Android onPlaybackStateChanged?: (e: OnPlaybackStateChangedData) => void; // Android
onTextTracks?: (e: OnTextTracksData) => void //Android onTimedMetadata?: (e: OnTimedMetadataData) => void; //Android, iOS
onVideoTracks?: (e: OnVideoTracksData) => void //Android onAudioTracks?: (e: OnAudioTracksData) => void; // Android
} onTextTracks?: (e: OnTextTracksData) => void; //Android
onVideoTracks?: (e: OnVideoTracksData) => void; //Android
}

View File

@ -181,4 +181,4 @@ export type ISO639_1 =
| 'yo' | 'yo'
| 'za' | 'za'
| 'zh' | 'zh'
| 'zu'; | 'zu';

View File

@ -1,25 +1,24 @@
import type { ISO639_1 } from './language'; import type {ISO639_1} from './language';
import type { ReactVideoEvents } from './events'; import type {ReactVideoEvents} from './events';
import type { StyleProp, ViewStyle } from 'react-native' import type {StyleProp, ViewStyle} from 'react-native';
type Filter = | 'None'
| 'CIColorInvert'
| 'CIColorMonochrome'
| 'CIColorPosterize'
| 'CIFalseColor'
| 'CIMaximumComponent'
| 'CIMinimumComponent'
| 'CIPhotoEffectChrome'
| 'CIPhotoEffectFade'
| 'CIPhotoEffectInstant'
| 'CIPhotoEffectMono'
| 'CIPhotoEffectNoir'
| 'CIPhotoEffectProcess'
| 'CIPhotoEffectTonal'
| 'CIPhotoEffectTransfer'
| 'CISepiaTone'
type Filter =
| 'None'
| 'CIColorInvert'
| 'CIColorMonochrome'
| 'CIColorPosterize'
| 'CIFalseColor'
| 'CIMaximumComponent'
| 'CIMinimumComponent'
| 'CIPhotoEffectChrome'
| 'CIPhotoEffectFade'
| 'CIPhotoEffectInstant'
| 'CIPhotoEffectMono'
| 'CIPhotoEffectNoir'
| 'CIPhotoEffectProcess'
| 'CIPhotoEffectTonal'
| 'CIPhotoEffectTransfer'
| 'CISepiaTone';
type Headers = Record<string, string>; type Headers = Record<string, string>;
@ -43,8 +42,14 @@ export type ReactVideoDrm = Readonly<{
contentId?: string; // ios contentId?: string; // ios
certificateUrl?: string; // ios certificateUrl?: string; // ios
base64Certificate?: boolean; // ios default: false base64Certificate?: boolean; // ios default: false
getLicense?: (licenseUrl: string, contentId: string, spcBase64: string) => void; // ios /* eslint-disable @typescript-eslint/no-unused-vars */
}> getLicense?: (
licenseUrl: string,
contentId: string,
spcBase64: string,
) => void; // ios
/* eslint-enable @typescript-eslint/no-unused-vars */
}>;
type BufferConfig = { type BufferConfig = {
minBufferMs?: number; minBufferMs?: number;
@ -54,17 +59,17 @@ type BufferConfig = {
maxHeapAllocationPercent?: number; maxHeapAllocationPercent?: number;
minBackBufferMemoryReservePercent?: number; minBackBufferMemoryReservePercent?: number;
minBufferMemoryReservePercent?: number; minBufferMemoryReservePercent?: number;
} };
type SelectedTrack = { type SelectedTrack = {
type: 'system' | 'disabled' | 'title' | 'language' | 'index'; type: 'system' | 'disabled' | 'title' | 'language' | 'index';
value?: string | number; value?: string | number;
} };
type SelectedVideoTrack = { type SelectedVideoTrack = {
type: 'auto' | 'disabled' | 'resolution' | 'index' type: 'auto' | 'disabled' | 'resolution' | 'index';
value?: number; value?: number;
} };
type SubtitleStyle = { type SubtitleStyle = {
fontSize?: number; fontSize?: number;
@ -72,16 +77,14 @@ type SubtitleStyle = {
paddingBottom?: number; paddingBottom?: number;
paddingLeft?: number; paddingLeft?: number;
paddingRight?: number; paddingRight?: number;
} };
type TextTracks = { type TextTracks = {
title: string; title: string;
language: ISO639_1; language: ISO639_1;
type: | 'application/x-subrip' type: 'application/x-subrip' | 'application/ttml+xml' | 'text/vtt';
| 'application/ttml+xml'
| 'text/vtt';
uri: string; uri: string;
}[] }[];
export interface ReactVideoProps extends ReactVideoEvents { export interface ReactVideoProps extends ReactVideoEvents {
source?: ReactVideoSource; source?: ReactVideoSource;
@ -98,24 +101,30 @@ export interface ReactVideoProps extends ReactVideoEvents {
disableFocus?: boolean; disableFocus?: boolean;
disableDisconnectError?: boolean; // Android disableDisconnectError?: boolean; // Android
filter?: Filter; // iOS filter?: Filter; // iOS
filterEnabled?: boolean; // iOS filterEnabled?: boolean; // iOS
focusable?: boolean; // Android focusable?: boolean; // Android
fullscreen?: boolean; // iOS fullscreen?: boolean; // iOS
fullscreenAutorotate?: boolean; // iOS fullscreenAutorotate?: boolean; // iOS
fullscreenOrientation?: 'all' | 'landscape' | 'portrait'; // iOS fullscreenOrientation?: 'all' | 'landscape' | 'portrait'; // iOS
hideShutterView?: boolean; // Android hideShutterView?: boolean; // Android
ignoreSilentSwitch?: 'inherit' | 'ignore' | 'obey' // iOS ignoreSilentSwitch?: 'inherit' | 'ignore' | 'obey'; // iOS
minLoadRetryCount?: number; // Android minLoadRetryCount?: number; // Android
maxBitRate?: number; maxBitRate?: number;
mixWithOthers?: 'inherit' | 'mix' | 'duck'; // iOS mixWithOthers?: 'inherit' | 'mix' | 'duck'; // iOS
muted?: boolean; muted?: boolean;
paused?: boolean; paused?: boolean;
pictureInPicture?: boolean // iOS pictureInPicture?: boolean; // iOS
playInBackground?: boolean; playInBackground?: boolean;
playWhenInactive?: boolean // iOS playWhenInactive?: boolean; // iOS
poster?: string; poster?: string;
posterResizeMode?: 'contain' | 'center' | 'cover' | 'none' | 'repeat' | 'stretch'; posterResizeMode?:
preferredForwardBufferDuration?: number// iOS | 'contain'
| 'center'
| 'cover'
| 'none'
| 'repeat'
| 'stretch';
preferredForwardBufferDuration?: number; // iOS
preventsDisplaySleepDuringVideoPlayback?: boolean; preventsDisplaySleepDuringVideoPlayback?: boolean;
progressUpdateInterval?: number; progressUpdateInterval?: number;
rate?: number; rate?: number;
@ -125,11 +134,11 @@ export interface ReactVideoProps extends ReactVideoEvents {
selectedAudioTrack?: SelectedTrack; selectedAudioTrack?: SelectedTrack;
selectedTextTrack?: SelectedTrack; selectedTextTrack?: SelectedTrack;
selectedVideoTrack?: SelectedVideoTrack; // android selectedVideoTrack?: SelectedVideoTrack; // android
subtitleStyle?: SubtitleStyle // android subtitleStyle?: SubtitleStyle; // android
textTracks?: TextTracks; textTracks?: TextTracks;
trackId?: string; // Android trackId?: string; // Android
useTextureView?: boolean; // Android useTextureView?: boolean; // Android
useSecureView?: boolean; // Android useSecureView?: boolean; // Android
volume?: number; volume?: number;
localSourceEncryptionKeyScheme?: string; localSourceEncryptionKeyScheme?: string;
} }

View File

@ -1,7 +1,7 @@
import type { Component, RefObject, ComponentClass } from 'react'; import type {Component, RefObject, ComponentClass} from 'react';
import { Image, UIManager, findNodeHandle } from "react-native"; import {Image, UIManager, findNodeHandle} from 'react-native';
import type { ImageSourcePropType } from 'react-native'; import type {ImageSourcePropType} from 'react-native';
import type { ReactVideoSource } from './types/video'; import type {ReactVideoSource} from './types/video';
type Source = ImageSourcePropType | ReactVideoSource; type Source = ImageSourcePropType | ReactVideoSource;
@ -14,24 +14,32 @@ export function resolveAssetSourceForVideo(source: Source): ReactVideoSource {
return source as ReactVideoSource; return source as ReactVideoSource;
} }
export function getReactTag(ref: RefObject<Component<any, any, any> | ComponentClass<any, any> | null>): number { export function getReactTag(
ref: RefObject<
| Component<unknown, unknown, unknown>
| ComponentClass<unknown, unknown>
| null
>,
): number {
if (!ref.current) { if (!ref.current) {
throw new Error("Video Component is not mounted"); throw new Error('Video Component is not mounted');
} }
const reactTag = findNodeHandle(ref.current); const reactTag = findNodeHandle(ref.current);
if (!reactTag) { if (!reactTag) {
throw new Error("Cannot find reactTag for Video Component in components tree"); throw new Error(
'Cannot find reactTag for Video Component in components tree',
);
} }
return reactTag; return reactTag;
} }
export function getViewManagerConfig(name: string) { export function getViewManagerConfig(name: string) {
if('getViewManagerConfig' in UIManager) { if ('getViewManagerConfig' in UIManager) {
return UIManager.getViewManagerConfig(name); return UIManager.getViewManagerConfig(name);
} }
return UIManager[name]; return UIManager[name];
} }