chore: lint project (#3279)
* chore: update eslint config * chore: lint lib files
This commit is contained in:
parent
e6e8f621fe
commit
067adde124
@ -1 +1,2 @@
|
|||||||
examples/
|
examples/
|
||||||
|
lib/
|
@ -1,8 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"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
|
||||||
|
257
src/Video.tsx
257
src/Video.tsx
@ -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,38 +174,45 @@ 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,
|
}
|
||||||
|
if (typeof selectedTextTrack?.value === 'number') {
|
||||||
|
return {
|
||||||
|
selectedTextType: selectedTextTrack?.type,
|
||||||
index: selectedTextTrack?.value,
|
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;
|
||||||
|
}
|
||||||
|
if (typeof selectedAudioTrack?.value === 'number') {
|
||||||
|
return {
|
||||||
selectedAudioType: selectedAudioTrack?.type,
|
selectedAudioType: selectedAudioTrack?.type,
|
||||||
index: selectedAudioTrack?.value,
|
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) => {
|
||||||
const seek = useCallback(
|
if (isNaN(time)) {
|
||||||
async (time: number, tolerance?: number) => {
|
throw new Error('Specified time is not a number');
|
||||||
if (isNaN(time)) throw new Error("Specified time is not a number");
|
}
|
||||||
|
|
||||||
if (!nativeRef.current) {
|
if (!nativeRef.current) {
|
||||||
console.warn("Video Component is not mounted");
|
console.warn('Video Component is not mounted');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,9 +231,7 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
})();
|
})();
|
||||||
},
|
}, []);
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
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(
|
||||||
|
(e: NativeSyntheticEvent<OnPlaybackStateChangedData>) => {
|
||||||
onPlaybackStateChanged?.(e.nativeEvent);
|
onPlaybackStateChanged?.(e.nativeEvent);
|
||||||
}, [onPlaybackStateChanged])
|
},
|
||||||
|
[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(
|
||||||
|
(e: NativeSyntheticEvent<OnBufferData>) => {
|
||||||
onBuffer?.(e.nativeEvent);
|
onBuffer?.(e.nativeEvent);
|
||||||
}, [onBuffer]);
|
},
|
||||||
|
[onBuffer],
|
||||||
|
);
|
||||||
|
|
||||||
const onVideoExternalPlaybackChange = useCallback((e: NativeSyntheticEvent<OnExternalPlaybackChangeData>) => {
|
const onVideoExternalPlaybackChange = useCallback(
|
||||||
|
(e: NativeSyntheticEvent<OnExternalPlaybackChangeData>) => {
|
||||||
onExternalPlaybackChange?.(e.nativeEvent);
|
onExternalPlaybackChange?.(e.nativeEvent);
|
||||||
}, [onExternalPlaybackChange])
|
},
|
||||||
|
[onExternalPlaybackChange],
|
||||||
|
);
|
||||||
|
|
||||||
const _onBandwidthUpdate = useCallback((e: NativeSyntheticEvent<OnBandwidthUpdateData>) => {
|
const _onBandwidthUpdate = useCallback(
|
||||||
|
(e: NativeSyntheticEvent<OnBandwidthUpdateData>) => {
|
||||||
onBandwidthUpdate?.(e.nativeEvent);
|
onBandwidthUpdate?.(e.nativeEvent);
|
||||||
}, [onBandwidthUpdate]);
|
},
|
||||||
|
[onBandwidthUpdate],
|
||||||
|
);
|
||||||
|
|
||||||
const _onReceiveAdEvent = useCallback((e: NativeSyntheticEvent<OnReceiveAdEventData>) => {
|
const _onReceiveAdEvent = useCallback(
|
||||||
|
(e: NativeSyntheticEvent<OnReceiveAdEventData>) => {
|
||||||
onReceiveAdEvent?.(e.nativeEvent);
|
onReceiveAdEvent?.(e.nativeEvent);
|
||||||
}, [onReceiveAdEvent]);
|
},
|
||||||
|
[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
|
||||||
|
.then((result) => {
|
||||||
if (result !== undefined) {
|
if (result !== undefined) {
|
||||||
nativeRef.current && VideoManager.setLicenseResult(result, data.licenseUrl, getReactTag(nativeRef));
|
nativeRef.current &&
|
||||||
|
VideoManager.setLicenseResult(
|
||||||
|
result,
|
||||||
|
data.licenseUrl,
|
||||||
|
getReactTag(nativeRef),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
nativeRef.current && VideoManager.setLicenseResultError('Empty license result', data.licenseUrl, getReactTag(nativeRef));
|
nativeRef.current &&
|
||||||
|
VideoManager.setLicenseResultError(
|
||||||
|
'Empty license result',
|
||||||
|
data.licenseUrl,
|
||||||
|
getReactTag(nativeRef),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})).catch(() => {
|
})
|
||||||
nativeRef.current && VideoManager.setLicenseResultError('fetch error', 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;
|
@ -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<
|
||||||
|
Readonly<{
|
||||||
title: string;
|
title: string;
|
||||||
language: string;
|
language: string;
|
||||||
type: string;
|
type: string;
|
||||||
uri: 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'
|
type?: 'srt' | 'ttml' | 'vtt';
|
||||||
selected?: boolean
|
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;
|
||||||
@ -257,7 +269,7 @@ export interface VideoNativeProps extends ViewProps {
|
|||||||
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
|
||||||
@ -267,24 +279,48 @@ export interface VideoNativeProps extends ViewProps {
|
|||||||
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;
|
||||||
|
14
src/index.ts
14
src/index.ts
@ -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;
|
@ -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
|
||||||
}
|
}
|
@ -1,8 +1,9 @@
|
|||||||
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'
|
type Filter =
|
||||||
|
| 'None'
|
||||||
| 'CIColorInvert'
|
| 'CIColorInvert'
|
||||||
| 'CIColorMonochrome'
|
| 'CIColorMonochrome'
|
||||||
| 'CIColorPosterize'
|
| 'CIColorPosterize'
|
||||||
@ -17,9 +18,7 @@ type Filter = | 'None'
|
|||||||
| 'CIPhotoEffectProcess'
|
| 'CIPhotoEffectProcess'
|
||||||
| 'CIPhotoEffectTonal'
|
| 'CIPhotoEffectTonal'
|
||||||
| 'CIPhotoEffectTransfer'
|
| 'CIPhotoEffectTransfer'
|
||||||
| 'CISepiaTone'
|
| '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;
|
||||||
@ -104,18 +107,24 @@ export interface ReactVideoProps extends ReactVideoEvents {
|
|||||||
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,7 +134,7 @@ 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
|
||||||
|
24
src/utils.ts
24
src/utils.ts
@ -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,22 +14,30 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user