chore: rework typescript integration (#3304)

* create few new types
* Add missing api

---------

Co-authored-by: olivier <olivier.bouillet@ifeelsmart.com>
Co-authored-by: Krzysztof Moch <krzysmoch.programs@gmail.com>
This commit is contained in:
Olivier Bouillet 2023-10-26 08:46:04 +02:00 committed by GitHub
parent 286418e4a5
commit 0f8467f51d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 404 additions and 169 deletions

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { FunctionComponent } from 'react';
import { import {
StyleSheet, StyleSheet,
@ -12,16 +12,16 @@ import {
* MultiValueControl displays a list clickable text view * MultiValueControl displays a list clickable text view
*/ */
interface MultiValueControlType { interface MultiValueControlType<T> {
// a list a string or number to be displayed // a list a string or number to be displayed
values: Array<string | number> values: Array<T>
// The selected value in values // The selected value in values
selected?: string | number selected?: T
// callback to press onPress // callback to press onPress
onPress: (arg: string | number) => any onPress: (arg: T) => any
} }
const MultiValueControl = ({ values, selected, onPress }: MultiValueControlType) => { const MultiValueControl: FunctionComponent<MultiValueControlType<any>> = ({ values, selected, onPress }) => {
const selectedStyle: TextStyle = StyleSheet.flatten([ const selectedStyle: TextStyle = StyleSheet.flatten([
styles.option, styles.option,
{fontWeight: 'bold'}, {fontWeight: 'bold'},

View File

@ -17,7 +17,21 @@ import {
import {Picker} from '@react-native-picker/picker'; import {Picker} from '@react-native-picker/picker';
import Video, {VideoDecoderProperties} from 'react-native-video'; import Video, {
AudioTrack,
OnAudioTracksData,
OnLoadData,
OnProgressData,
OnTextTracksData,
OnVideoAspectRatioData,
TextTrack,
VideoDecoderProperties,
OnBufferData,
OnAudioFocusChangedData,
OnVideoErrorData,
VideoRef,
ResizeMode
} from 'react-native-video';
import ToggleControl from './ToggleControl'; import ToggleControl from './ToggleControl';
import MultiValueControl from './MultiValueControl'; import MultiValueControl from './MultiValueControl';
@ -26,7 +40,7 @@ class VideoPlayer extends Component {
rate: 1, rate: 1,
volume: 1, volume: 1,
muted: false, muted: false,
resizeMode: 'contain', resizeMode: ResizeMode.CONTAIN,
duration: 0.0, duration: 0.0,
currentTime: 0.0, currentTime: 0.0,
videoWidth: 0, videoWidth: 0,
@ -106,7 +120,7 @@ class VideoPlayer extends Component {
Platform.OS === 'android' ? this.srcAndroidList : this.srcIosList, Platform.OS === 'android' ? this.srcAndroidList : this.srcIosList,
); );
video?: Video; video?: VideoRef;
seekPanResponder?: PanResponderInstance; seekPanResponder?: PanResponderInstance;
popupInfo = () => { popupInfo = () => {
@ -129,13 +143,13 @@ class VideoPlayer extends Component {
}); });
}; };
onLoad = (data: any) => { onLoad = (data: OnLoadData) => {
this.setState({duration: data.duration, loading: false}); this.setState({duration: data.duration, loading: false});
this.onAudioTracks(data); this.onAudioTracks(data);
this.onTextTracks(data); this.onTextTracks(data);
}; };
onProgress = (data: any) => { onProgress = (data: OnProgressData) => {
if (!this.state.seeking) { if (!this.state.seeking) {
const position = this.calculateSeekerPosition(); const position = this.calculateSeekerPosition();
this.setSeekerPosition(position); this.setSeekerPosition(position);
@ -148,8 +162,8 @@ class VideoPlayer extends Component {
this.setState({isLoading: true}); this.setState({isLoading: true});
}; };
onAudioTracks = (data: any) => { onAudioTracks = (data: OnAudioTracksData) => {
const selectedTrack = data.audioTracks?.find((x: any) => { const selectedTrack = data.audioTracks?.find((x: AudioTrack) => {
return x.selected; return x.selected;
}); });
this.setState({ this.setState({
@ -165,8 +179,8 @@ class VideoPlayer extends Component {
} }
}; };
onTextTracks = (data: any) => { onTextTracks = (data: OnTextTracksData) => {
const selectedTrack = data.textTracks?.find((x: any) => { const selectedTrack = data.textTracks?.find((x: TextTrack) => {
return x.selected; return x.selected;
}); });
@ -184,7 +198,7 @@ class VideoPlayer extends Component {
} }
}; };
onAspectRatio = (data: any) => { onAspectRatio = (data: OnVideoAspectRatioData) => {
console.log('onAspectRadio called ' + JSON.stringify(data)); console.log('onAspectRadio called ' + JSON.stringify(data));
this.setState({ this.setState({
videoWidth: data.width, videoWidth: data.width,
@ -192,7 +206,7 @@ class VideoPlayer extends Component {
}); });
}; };
onVideoBuffer = (param: any) => { onVideoBuffer = (param: OnBufferData) => {
console.log('onVideoBuffer'); console.log('onVideoBuffer');
this.setState({isLoading: param.isBuffering}); this.setState({isLoading: param.isBuffering});
}; };
@ -206,7 +220,7 @@ class VideoPlayer extends Component {
this.setState({paused: true}); this.setState({paused: true});
}; };
onAudioFocusChanged = (event: {hasAudioFocus: boolean}) => { onAudioFocusChanged = (event: OnAudioFocusChangedData) => {
this.setState({paused: !event.hasAudioFocus}); this.setState({paused: !event.hasAudioFocus});
}; };
@ -233,9 +247,9 @@ class VideoPlayer extends Component {
} }
}; };
onError = (err: any) => { onError = (err: OnVideoErrorData) => {
console.log(JSON.stringify(err?.error.errorCode)); console.log(JSON.stringify(err));
this.toast(true, 'error: ' + err?.error.errorCode); this.toast(true, 'error: ' + JSON.stringify(err));
}; };
onEnd = () => { onEnd = () => {
@ -488,7 +502,7 @@ class VideoPlayer extends Component {
onVolumeSelected = (value: string | number) => { onVolumeSelected = (value: string | number) => {
this.setState({volume: value}); this.setState({volume: value});
} }
onResizeModeSelected = (value: string | number) => { onResizeModeSelected = (value: ResizeMode) => {
this.setState({resizeMode: value}); this.setState({resizeMode: value});
} }
@ -572,7 +586,7 @@ class VideoPlayer extends Component {
selected={this.state.volume} selected={this.state.volume}
/> />
<MultiValueControl <MultiValueControl
values={['cover', 'contain', 'stretch']} values={[ResizeMode.COVER, ResizeMode.CONTAIN, ResizeMode.STRETCH]}
onPress={this.onResizeModeSelected} onPress={this.onResizeModeSelected}
selected={this.state.resizeMode} selected={this.state.resizeMode}
/> />
@ -648,7 +662,7 @@ class VideoPlayer extends Component {
return ( return (
<TouchableOpacity style={viewStyle}> <TouchableOpacity style={viewStyle}>
<Video <Video
ref={(ref: Video) => { ref={(ref: VideoRef) => {
this.video = ref; this.video = ref;
}} }}
source={this.srcList[this.state.srcListId]} source={this.srcList[this.state.srcListId]}

View File

@ -8,34 +8,38 @@ import React, {
type ComponentRef, type ComponentRef,
} from 'react'; } from 'react';
import {View, StyleSheet, Image, Platform} from 'react-native'; import {View, StyleSheet, Image, Platform} from 'react-native';
import NativeVideoComponent from './VideoNativeComponent'; import NativeVideoComponent, {
import type { type VideoComponentType,
OnAudioFocusChangedData,
OnAudioTracksData,
OnPlaybackStateChangedData,
OnTextTracksData,
OnTimedMetadataData,
OnVideoErrorData,
OnVideoTracksData,
} from './VideoNativeComponent'; } from './VideoNativeComponent';
import type {StyleProp, ImageStyle, NativeSyntheticEvent} from 'react-native'; import type {StyleProp, ImageStyle, NativeSyntheticEvent} from 'react-native';
import {
type VideoComponentType,
type OnLoadData,
type OnGetLicenseData,
type OnLoadStartData,
type OnProgressData,
type OnSeekData,
type OnPictureInPictureStatusChangedData,
type OnBandwidthUpdateData,
type OnBufferData,
type OnExternalPlaybackChangeData,
type OnReceiveAdEventData,
VideoManager,
} from './VideoNativeComponent';
import type {ReactVideoProps} from './types/video'; import type {ReactVideoProps} from './types/video';
import {getReactTag, resolveAssetSourceForVideo} from './utils'; import {getReactTag, resolveAssetSourceForVideo} from './utils';
import {VideoManager} from './VideoNativeComponent';
import type {
OnAudioFocusChangedData,
OnAudioTracksData,
OnBandwidthUpdateData,
OnBufferData,
OnExternalPlaybackChangeData,
OnGetLicenseData,
OnLoadData,
OnLoadStartData,
OnPictureInPictureStatusChangedData,
OnPlaybackStateChangedData,
OnProgressData,
OnReceiveAdEventData,
OnSeekData,
OnTextTracksData,
OnTimedMetadataData,
OnVideoAspectRatioData,
OnVideoErrorData,
OnVideoTracksData,
} from './types/events';
export type VideoSaveData = {
uri: string;
};
export interface VideoRef { export interface VideoRef {
seek: (time: number, tolerance?: number) => void; seek: (time: number, tolerance?: number) => void;
@ -46,6 +50,7 @@ export interface VideoRef {
restoreUserInterfaceForPictureInPictureStopCompleted: ( restoreUserInterfaceForPictureInPictureStopCompleted: (
restore: boolean, restore: boolean,
) => void; ) => void;
save: () => Promise<VideoSaveData>;
} }
const Video = forwardRef<VideoRef, ReactVideoProps>( const Video = forwardRef<VideoRef, ReactVideoProps>(
@ -88,6 +93,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onAudioTracks, onAudioTracks,
onTextTracks, onTextTracks,
onVideoTracks, onVideoTracks,
onAspectRatio,
...rest ...rest
}, },
ref, ref,
@ -122,7 +128,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
uri = `file://${uri}`; uri = `file://${uri}`;
} }
if (!uri) { if (!uri) {
console.warn('Trying to load empty source'); console.log('Trying to load empty source');
} }
const isNetwork = !!(uri && uri.match(/^https?:/)); const isNetwork = !!(uri && uri.match(/^https?:/));
const isAsset = !!( const isAsset = !!(
@ -214,7 +220,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
nativeRef.current?.setNativeProps({ nativeRef.current?.setNativeProps({
seek: { seek: {
time, time,
tolerance, tolerance: tolerance || 0,
}, },
}); });
}, },
@ -234,16 +240,16 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
setIsFullscreen(false); setIsFullscreen(false);
}, [setIsFullscreen]); }, [setIsFullscreen]);
const save = useCallback(async () => { const save = useCallback(() => {
await VideoManager.save(getReactTag(nativeRef)); return VideoManager.save(getReactTag(nativeRef));
}, []); }, []);
const pause = useCallback(async () => { const pause = useCallback(() => {
await VideoManager.setPlayerPauseState(true, getReactTag(nativeRef)); return VideoManager.setPlayerPauseState(true, getReactTag(nativeRef));
}, []); }, []);
const resume = useCallback(async () => { const resume = useCallback(() => {
await VideoManager.setPlayerPauseState(false, getReactTag(nativeRef)); return VideoManager.setPlayerPauseState(false, getReactTag(nativeRef));
}, []); }, []);
const restoreUserInterfaceForPictureInPictureStopCompleted = useCallback( const restoreUserInterfaceForPictureInPictureStopCompleted = useCallback(
@ -385,6 +391,13 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
[onReceiveAdEvent], [onReceiveAdEvent],
); );
const _onVideoAspectRatio = useCallback(
(e: NativeSyntheticEvent<OnVideoAspectRatioData>) => {
onAspectRatio?.(e.nativeEvent);
},
[onAspectRatio],
);
const onGetLicense = useCallback( const onGetLicense = useCallback(
(event: NativeSyntheticEvent<OnGetLicenseData>) => { (event: NativeSyntheticEvent<OnGetLicenseData>) => {
if (drm && drm.getLicense instanceof Function) { if (drm && drm.getLicense instanceof Function) {
@ -482,7 +495,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onVideoEnd={onEnd} onVideoEnd={onEnd}
onVideoBuffer={onVideoBuffer} onVideoBuffer={onVideoBuffer}
onVideoPlaybackStateChanged={onVideoPlaybackStateChanged} onVideoPlaybackStateChanged={onVideoPlaybackStateChanged}
onBandwidthUpdate={_onBandwidthUpdate} onVideoBandwidthUpdate={_onBandwidthUpdate}
onTimedMetadata={_onTimedMetadata} onTimedMetadata={_onTimedMetadata}
onAudioTracks={_onAudioTracks} onAudioTracks={_onAudioTracks}
onTextTracks={_onTextTracks} onTextTracks={_onTextTracks}
@ -501,6 +514,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
onRestoreUserInterfaceForPictureInPictureStop={ onRestoreUserInterfaceForPictureInPictureStop={
onRestoreUserInterfaceForPictureInPictureStop onRestoreUserInterfaceForPictureInPictureStop
} }
onVideoAspectRatio={_onVideoAspectRatio}
onReceiveAdEvent={_onReceiveAdEvent} onReceiveAdEvent={_onReceiveAdEvent}
/> />
{showPoster ? ( {showPoster ? (

View File

@ -4,6 +4,10 @@ import type {
ViewProps, ViewProps,
} from 'react-native'; } from 'react-native';
import {NativeModules, requireNativeComponent} from 'react-native'; import {NativeModules, requireNativeComponent} from 'react-native';
import type ResizeMode from './types/ResizeMode';
import type FilterType from './types/FilterType';
import type Orientation from './types/Orientation';
import type {OnTextTracksTypeData} from './types';
// -------- 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
@ -119,9 +123,11 @@ export type OnLoadData = Readonly<{
naturalSize: Readonly<{ naturalSize: Readonly<{
width: number; width: number;
height: number; height: number;
orientation: 'portrait' | 'landscape'; orientation: Orientation;
}>;
}>; }>;
}> &
OnAudioTracksData &
OnTextTracksData;
export type OnLoadStartData = Readonly<{ export type OnLoadStartData = Readonly<{
isNetwork: boolean; isNetwork: boolean;
@ -129,6 +135,11 @@ export type OnLoadStartData = Readonly<{
uri: string; uri: string;
}>; }>;
export type OnVideoAspectRatioData = Readonly<{
width: number;
height: number;
}>;
export type OnBufferData = Readonly<{isBuffering: boolean}>; export type OnBufferData = Readonly<{isBuffering: boolean}>;
export type OnProgressData = Readonly<{ export type OnProgressData = Readonly<{
@ -139,6 +150,9 @@ export type OnProgressData = Readonly<{
export type OnBandwidthUpdateData = Readonly<{ export type OnBandwidthUpdateData = Readonly<{
bitrate: number; bitrate: number;
width: number;
height: number;
trackId: number;
}>; }>;
export type OnSeekData = Readonly<{ export type OnSeekData = Readonly<{
@ -181,7 +195,7 @@ export type OnTextTracksData = Readonly<{
/** /**
* iOS only supports VTT, Android supports all 3 * iOS only supports VTT, Android supports all 3
*/ */
type?: 'srt' | 'ttml' | 'vtt'; type?: OnTextTracksTypeData;
selected?: boolean; selected?: boolean;
}> }>
>; >;
@ -223,19 +237,24 @@ export type OnReceiveAdEventData = Readonly<{
}>; }>;
export type OnVideoErrorData = Readonly<{ export type OnVideoErrorData = Readonly<{
errorString: string;
errorException: string;
errorStackTrace: string;
errorCode: string;
error: string; error: string;
}>; }>;
export type OnAudioFocusChangedData = Readonly<{ export type OnAudioFocusChangedData = Readonly<{
hasFocus: boolean; hasAudioFocus: boolean;
}>; }>;
export interface VideoNativeProps extends ViewProps { export interface VideoNativeProps extends ViewProps {
src?: VideoSrc; src?: VideoSrc;
drm?: Drm; drm?: Drm;
adTagUrl?: string; adTagUrl?: string;
allowsExternalPlayback?: boolean; // ios, true allowsExternalPlayback?: boolean; // ios, true
maxBitRate?: number; maxBitRate?: number;
resizeMode?: 'none' | 'cover' | 'contain' | 'stretch'; resizeMode?: ResizeMode;
repeat?: boolean; repeat?: boolean;
automaticallyWaitsToMinimizeStalling?: boolean; automaticallyWaitsToMinimizeStalling?: boolean;
textTracks?: TextTracks; textTracks?: TextTracks;
@ -244,7 +263,7 @@ export interface VideoNativeProps extends ViewProps {
paused?: boolean; paused?: boolean;
muted?: boolean; muted?: boolean;
controls?: boolean; controls?: boolean;
filter?: Filter; filter?: FilterType;
filterEnabled?: boolean; filterEnabled?: boolean;
volume?: number; // default 1.0 volume?: number; // default 1.0
playInBackground?: boolean; playInBackground?: boolean;
@ -277,13 +296,15 @@ export interface VideoNativeProps extends ViewProps {
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;
onVideoAspectRatio?: (
event: NativeSyntheticEvent<OnVideoAspectRatioData>,
) => 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?: ( onVideoBandwidthUpdate?: (
event: NativeSyntheticEvent<OnBandwidthUpdateData>, event: NativeSyntheticEvent<OnBandwidthUpdateData>,
) => void; ) => void;
onVideoSeek?: (event: NativeSyntheticEvent<OnSeekData>) => void; onVideoSeek?: (event: NativeSyntheticEvent<OnSeekData>) => void;
@ -333,8 +354,12 @@ export interface VideoNativeProps extends ViewProps {
export type VideoComponentType = HostComponent<VideoNativeProps>; export type VideoComponentType = HostComponent<VideoNativeProps>;
export type VideoSaveData = {
uri: string;
};
export interface VideoManagerType { export interface VideoManagerType {
save: (reactTag: number) => Promise<void>; save: (reactTag: number) => Promise<VideoSaveData>;
setPlayerPauseState: (paused: boolean, reactTag: number) => Promise<void>; setPlayerPauseState: (paused: boolean, reactTag: number) => Promise<void>;
setLicenseResult: ( setLicenseResult: (
result: string, result: string,

View File

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

View File

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

View File

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

View File

@ -1,5 +0,0 @@
export default {
SRT: 'application/x-subrip',
TTML: 'application/ttml+xml',
VTT: 'text/vtt',
} as const;

View File

@ -1,5 +0,0 @@
export default {
contain: 'contain',
cover: 'cover',
stretch: 'stretch',
} as const;

20
src/types/FilterType.ts Normal file
View File

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

6
src/types/Orientation.ts Normal file
View File

@ -0,0 +1,6 @@
enum Orientation {
PORTRAIT = 'portrait',
LANDSCAPE = 'landscape',
}
export default Orientation;

8
src/types/ResizeMode.ts Normal file
View File

@ -0,0 +1,8 @@
enum ResizeMode {
NONE = 'none',
CONTAIN = 'contain',
COVER = 'cover',
STRETCH = 'stretch',
}
export default ResizeMode;

View File

@ -0,0 +1,7 @@
enum TextTrackType {
SRT = 'application/x-subrip',
TTML = 'application/ttml+xml',
VTT = 'text/vtt',
}
export default TextTrackType;

View File

@ -1,22 +1,138 @@
import type { import type Orientation from './Orientation';
OnBandwidthUpdateData,
OnBufferData, export type OnLoadData = Readonly<{
OnLoadData, currentTime: number;
OnLoadStartData, duration: number;
OnProgressData, naturalSize: Readonly<{
OnSeekData, width: number;
OnPlaybackData, height: number;
OnExternalPlaybackChangeData, orientation: Orientation;
OnPictureInPictureStatusChangedData, }>;
OnReceiveAdEventData, }> &
OnVideoErrorData, OnAudioTracksData &
OnPlaybackStateChangedData, OnTextTracksData;
OnAudioFocusChangedData,
OnTimedMetadataData, export type OnVideoAspectRatioData = Readonly<{
OnAudioTracksData, width: number;
OnTextTracksData, height: number;
OnVideoTracksData, }>;
} from '../VideoNativeComponent';
export type OnLoadStartData = Readonly<{
isNetwork: boolean;
type: string;
uri: string;
}>;
export type OnProgressData = Readonly<{
currentTime: number;
playableDuration: number;
seekableDuration: number;
}>;
export type OnSeekData = Readonly<{
currentTime: number;
seekTime: number;
}>;
export type OnPlaybackStateChangedData = Readonly<{
isPlaying: boolean;
}>;
export type OnTimedMetadataData = Readonly<{
metadata: ReadonlyArray<
Readonly<{
value?: string;
identifier: string;
}>
>;
}>;
export type AudioTrack = Readonly<{
index: number;
title?: string;
language?: string;
bitrate?: number;
type?: string;
selected?: boolean;
}>;
export type OnAudioTracksData = Readonly<{
audioTracks: ReadonlyArray<AudioTrack>;
}>;
export enum OnTextTracksTypeData {
SRT = 'srt',
TTML = 'ttml',
VTT = 'vtt',
}
export type TextTrack = Readonly<{
index: number;
title?: string;
language?: string;
type?: OnTextTracksTypeData;
selected?: boolean;
}>;
export type OnTextTracksData = Readonly<{
textTracks: ReadonlyArray<TextTrack>;
}>;
export type OnVideoTracksData = Readonly<{
videoTracks: ReadonlyArray<
Readonly<{
trackId: number;
codecs?: string;
width?: number;
height?: number;
bitrate?: number;
selected?: boolean;
}>
>;
}>;
export type OnPlaybackData = Readonly<{
playbackRate: number;
}>;
export type OnExternalPlaybackChangeData = Readonly<{
isExternalPlaybackActive: boolean;
}>;
export type OnGetLicenseData = Readonly<{
licenseUrl: string;
contentId: string;
spcBase64: string;
}>;
export type OnPictureInPictureStatusChangedData = Readonly<{
isActive: boolean;
}>;
export type OnReceiveAdEventData = Readonly<{
event: string;
}>;
export type OnVideoErrorData = Readonly<{
errorString: string;
errorException: string;
errorStackTrace: string;
errorCode: string;
error: string;
}>;
export type OnAudioFocusChangedData = Readonly<{
hasAudioFocus: boolean;
}>;
export type OnBufferData = Readonly<{isBuffering: boolean}>;
export type OnBandwidthUpdateData = Readonly<{
bitrate: number;
width: number;
height: number;
trackId: number;
}>;
export interface ReactVideoEvents { export interface ReactVideoEvents {
onAudioBecomingNoisy?: () => void; //Android, iOS onAudioBecomingNoisy?: () => void; //Android, iOS
@ -47,4 +163,5 @@ export interface ReactVideoEvents {
onAudioTracks?: (e: OnAudioTracksData) => void; // Android onAudioTracks?: (e: OnAudioTracksData) => void; // Android
onTextTracks?: (e: OnTextTracksData) => void; //Android onTextTracks?: (e: OnTextTracksData) => void; //Android
onVideoTracks?: (e: OnVideoTracksData) => void; //Android onVideoTracks?: (e: OnVideoTracksData) => void; //Android
onAspectRatio?: (e: OnVideoAspectRatioData) => void;
} }

7
src/types/index.ts Normal file
View File

@ -0,0 +1,7 @@
export * from './events';
export {default as FilterType} from './FilterType';
export * from './language';
export {default as Orientation} from './Orientation';
export {default as ResizeMode} from './ResizeMode';
export {default as TextTrackType} from './TextTrackType';
export * from './video';

View File

@ -1,26 +1,10 @@
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';
import type VideoResizeMode from './ResizeMode';
import type FilterType from './FilterType';
type Filter = export type Headers = Record<string, string>;
| 'None'
| 'CIColorInvert'
| 'CIColorMonochrome'
| 'CIColorPosterize'
| 'CIFalseColor'
| 'CIMaximumComponent'
| 'CIMinimumComponent'
| 'CIPhotoEffectChrome'
| 'CIPhotoEffectFade'
| 'CIPhotoEffectInstant'
| 'CIPhotoEffectMono'
| 'CIPhotoEffectNoir'
| 'CIPhotoEffectProcess'
| 'CIPhotoEffectTonal'
| 'CIPhotoEffectTransfer'
| 'CISepiaTone';
type Headers = Record<string, string>;
export type ReactVideoSource = Readonly<{ export type ReactVideoSource = Readonly<{
uri?: string; uri?: string;
@ -39,13 +23,20 @@ export type ReactVideoSource = Readonly<{
customImageUri?: string; customImageUri?: string;
}>; }>;
type DebugConfig = Readonly<{ export type DebugConfig = Readonly<{
enable?: boolean; enable?: boolean;
thread?: boolean; thread?: boolean;
}>; }>;
export type ReactVideoDrm = Readonly<{ export enum DrmType {
type?: 'widevine' | 'playready' | 'clearkey' | 'fairplay'; WIDEVINE = 'widevine',
PLAYREADY = 'playready',
CLEARKEY = 'clearkey',
FAIRPLAY = 'fairplay',
}
export type Drm = Readonly<{
type?: DrmType;
licenseServer?: string; licenseServer?: string;
headers?: Headers; headers?: Headers;
contentId?: string; // ios contentId?: string; // ios
@ -60,7 +51,7 @@ export type ReactVideoDrm = Readonly<{
/* eslint-enable @typescript-eslint/no-unused-vars */ /* eslint-enable @typescript-eslint/no-unused-vars */
}>; }>;
type BufferConfig = { export type BufferConfig = {
minBufferMs?: number; minBufferMs?: number;
maxBufferMs?: number; maxBufferMs?: number;
bufferForPlaybackMs?: number; bufferForPlaybackMs?: number;
@ -70,17 +61,32 @@ type BufferConfig = {
minBufferMemoryReservePercent?: number; minBufferMemoryReservePercent?: number;
}; };
type SelectedTrack = { export enum SelectedTrackType {
type: 'system' | 'disabled' | 'title' | 'language' | 'index'; SYSTEM = 'system',
DISABLED = 'disabled',
TITLE = 'title',
LANGUAGE = 'language',
INDEX = 'index',
}
export type SelectedTrack = {
type: SelectedTrackType;
value?: string | number; value?: string | number;
}; };
type SelectedVideoTrack = { export enum SelectedVideoTrackType {
type: 'auto' | 'disabled' | 'resolution' | 'index'; AUDO = 'auto',
DISABLED = 'disabled',
RESOLUTION = 'resolution',
IUNDEX = 'index',
}
export type SelectedVideoTrack = {
type: SelectedVideoTrackType;
value?: number; value?: number;
}; };
type SubtitleStyle = { export type SubtitleStyle = {
fontSize?: number; fontSize?: number;
paddingTop?: number; paddingTop?: number;
paddingBottom?: number; paddingBottom?: number;
@ -88,23 +94,80 @@ type SubtitleStyle = {
paddingRight?: number; paddingRight?: number;
}; };
type TextTracks = { export enum TextTracksType {
SUBRIP = 'application/x-subrip',
TTML = 'application/ttml+xml',
VTT = 'text/vtt',
}
export type TextTracks = {
title: string; title: string;
language: ISO639_1; language: ISO639_1;
type: 'application/x-subrip' | 'application/ttml+xml' | 'text/vtt'; type: TextTracksType;
uri: string; uri: string;
}[]; }[];
type Chapters = { export type TextTrackType =
| 'system'
| 'disabled'
| 'title'
| 'language'
| 'index';
export type SelectedTextTrack = Readonly<{
type: TextTrackType;
value?: string | number;
}>;
export type AudioTrackType =
| 'system'
| 'disabled'
| 'title'
| 'language'
| 'index';
export type SelectedAudioTrack = Readonly<{
type: AudioTrackType;
value?: string | number;
}>;
export type Chapters = {
title: string; title: string;
startTime: number; startTime: number;
endTime: number; endTime: number;
uri?: string; uri?: string;
}; };
export enum FullscreenOrientationType {
ALL = 'all',
LANDSCAPE = 'landscape',
PORTRAIT = 'portrait',
}
export enum IgnoreSilentSwitchType {
INHERIT = 'inherit',
IGNORE = 'ignore',
OBEY = 'obey',
}
export enum MixWithOthersType {
INHERIT = 'inherit',
MIX = 'mix',
DUCK = 'duck',
}
export enum PosterResizeModeType {
CONTAIN = 'contain',
CENTER = 'center',
COVER = 'cover',
NONE = 'none',
REPEAT = 'repeat',
STRETCH = 'stretch',
}
export interface ReactVideoProps extends ReactVideoEvents { export interface ReactVideoProps extends ReactVideoEvents {
source?: ReactVideoSource; source?: ReactVideoSource;
drm?: ReactVideoDrm; drm?: Drm;
style?: StyleProp<ViewStyle>; style?: StyleProp<ViewStyle>;
adTagUrl?: string; // iOS adTagUrl?: string; // iOS
audioOnly?: boolean; audioOnly?: boolean;
@ -117,37 +180,31 @@ export interface ReactVideoProps extends ReactVideoEvents {
currentPlaybackTime?: number; // Android currentPlaybackTime?: number; // Android
disableFocus?: boolean; disableFocus?: boolean;
disableDisconnectError?: boolean; // Android disableDisconnectError?: boolean; // Android
filter?: Filter; // iOS filter?: FilterType; // 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?: FullscreenOrientationType; // iOS
hideShutterView?: boolean; // Android hideShutterView?: boolean; // Android
ignoreSilentSwitch?: 'inherit' | 'ignore' | 'obey'; // iOS ignoreSilentSwitch?: IgnoreSilentSwitchType; // iOS
minLoadRetryCount?: number; // Android minLoadRetryCount?: number; // Android
maxBitRate?: number; maxBitRate?: number;
mixWithOthers?: 'inherit' | 'mix' | 'duck'; // iOS mixWithOthers?: MixWithOthersType; // 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?: posterResizeMode?: PosterResizeModeType;
| 'contain'
| 'center'
| 'cover'
| 'none'
| 'repeat'
| 'stretch';
preferredForwardBufferDuration?: number; // iOS preferredForwardBufferDuration?: number; // iOS
preventsDisplaySleepDuringVideoPlayback?: boolean; preventsDisplaySleepDuringVideoPlayback?: boolean;
progressUpdateInterval?: number; progressUpdateInterval?: number;
rate?: number; rate?: number;
repeat?: boolean; repeat?: boolean;
reportBandwidth?: boolean; //Android reportBandwidth?: boolean; //Android
resizeMode?: 'none' | 'contain' | 'cover' | 'stretch'; resizeMode?: VideoResizeMode;
selectedAudioTrack?: SelectedTrack; selectedAudioTrack?: SelectedTrack;
selectedTextTrack?: SelectedTrack; selectedTextTrack?: SelectedTrack;
selectedVideoTrack?: SelectedVideoTrack; // android selectedVideoTrack?: SelectedVideoTrack; // android