chore(example/basic): refactor state variable (#3949)
* refactor: basic example from class component to functional component * refactor: toast component path * refactor: bufferConfig prop * refacotr: import component path * fix: seekbar issue on iOS * refactor: state variable * chore: refactor overlay component according to new state structure
This commit is contained in:
parent
7562669fd6
commit
a3ecc0108c
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {FC, useRef, useState} from 'react';
|
import React, {FC, useCallback, useRef, useState} from 'react';
|
||||||
|
|
||||||
import {TouchableOpacity, View} from 'react-native';
|
import {TouchableOpacity, View} from 'react-native';
|
||||||
|
|
||||||
@ -25,24 +25,55 @@ import Video, {
|
|||||||
BufferingStrategyType,
|
BufferingStrategyType,
|
||||||
ReactVideoSource,
|
ReactVideoSource,
|
||||||
SelectedTrackType,
|
SelectedTrackType,
|
||||||
|
ResizeMode,
|
||||||
|
VideoTrack,
|
||||||
|
SelectedTrack,
|
||||||
|
SelectedVideoTrack,
|
||||||
} from 'react-native-video';
|
} from 'react-native-video';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import {AdditionalSourceInfo} from './types';
|
import {AdditionalSourceInfo} from './types';
|
||||||
import {
|
import {bufferConfig, srcList, textTracksSelectionBy} from './constants';
|
||||||
bufferConfig,
|
|
||||||
defaultValue,
|
|
||||||
srcList,
|
|
||||||
textTracksSelectionBy,
|
|
||||||
} from './constants';
|
|
||||||
import {Overlay, toast} from './components';
|
import {Overlay, toast} from './components';
|
||||||
|
|
||||||
type Props = NonNullable<unknown>;
|
type Props = NonNullable<unknown>;
|
||||||
|
|
||||||
const VideoPlayer: FC<Props> = ({}) => {
|
const VideoPlayer: FC<Props> = ({}) => {
|
||||||
const [state, setState] = useState(defaultValue);
|
const [rate, setRate] = useState(1);
|
||||||
|
const [volume, setVolume] = useState(1);
|
||||||
|
const [muted, setMuted] = useState(false);
|
||||||
|
const [resizeMode, setResizeMode] = useState(ResizeMode.CONTAIN);
|
||||||
|
const [duration, setDuration] = useState(0);
|
||||||
|
const [currentTime, setCurrentTime] = useState(0);
|
||||||
|
const [_, setVideoSize] = useState({videoWidth: 0, videoHeight: 0});
|
||||||
|
const [paused, setPaused] = useState(false);
|
||||||
|
const [fullscreen, setFullscreen] = useState(true);
|
||||||
|
const [decoration, setDecoration] = useState(true);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [audioTracks, setAudioTracks] = useState<AudioTrack[]>([]);
|
||||||
|
const [textTracks, setTextTracks] = useState<TextTrack[]>([]);
|
||||||
|
const [videoTracks, setVideoTracks] = useState<VideoTrack[]>([]);
|
||||||
|
const [selectedAudioTrack, setSelectedAudioTrack] = useState<
|
||||||
|
SelectedTrack | undefined
|
||||||
|
>(undefined);
|
||||||
|
const [selectedTextTrack, setSelectedTextTrack] = useState<
|
||||||
|
SelectedTrack | undefined
|
||||||
|
>(undefined);
|
||||||
|
const [selectedVideoTrack, setSelectedVideoTrack] =
|
||||||
|
useState<SelectedVideoTrack>({
|
||||||
|
type: SelectedVideoTrackType.AUTO,
|
||||||
|
});
|
||||||
|
const [srcListId, setSrcListId] = useState(0);
|
||||||
|
const [repeat, setRepeat] = useState(false);
|
||||||
|
const [controls, setControls] = useState(false);
|
||||||
|
const [useCache, setUseCache] = useState(false);
|
||||||
|
const [poster, setPoster] = useState<string | undefined>(undefined);
|
||||||
|
const [showNotificationControls, setShowNotificationControls] =
|
||||||
|
useState(false);
|
||||||
|
const [isSeeking, setIsSeeking] = useState(false);
|
||||||
|
|
||||||
const videoRef = useRef<VideoRef>(null);
|
const videoRef = useRef<VideoRef>(null);
|
||||||
const viewStyle = state.fullscreen ? styles.fullScreen : styles.halfScreen;
|
const viewStyle = fullscreen ? styles.fullScreen : styles.halfScreen;
|
||||||
const currentSrc = srcList[state.srcListId];
|
const currentSrc = srcList[srcListId];
|
||||||
const additional = currentSrc as AdditionalSourceInfo;
|
const additional = currentSrc as AdditionalSourceInfo;
|
||||||
|
|
||||||
const onAudioTracks = (data: OnAudioTracksData) => {
|
const onAudioTracks = (data: OnAudioTracksData) => {
|
||||||
@ -50,28 +81,19 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
return x.selected;
|
return x.selected;
|
||||||
});
|
});
|
||||||
if (selectedTrack?.index) {
|
if (selectedTrack?.index) {
|
||||||
setState({
|
setAudioTracks(data.audioTracks);
|
||||||
...state,
|
setSelectedAudioTrack({
|
||||||
audioTracks: data.audioTracks,
|
type: SelectedTrackType.INDEX,
|
||||||
selectedAudioTrack: {
|
value: selectedTrack.index,
|
||||||
type: SelectedTrackType.INDEX,
|
|
||||||
value: selectedTrack?.index,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setAudioTracks(data.audioTracks);
|
||||||
...state,
|
|
||||||
audioTracks: data.audioTracks,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVideoTracks = (data: OnVideoTracksData) => {
|
const onVideoTracks = (data: OnVideoTracksData) => {
|
||||||
console.log('onVideoTracks', data.videoTracks);
|
console.log('onVideoTracks', data.videoTracks);
|
||||||
setState({
|
setVideoTracks(data.videoTracks);
|
||||||
...state,
|
|
||||||
videoTracks: data.videoTracks,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onTextTracks = (data: OnTextTracksData) => {
|
const onTextTracks = (data: OnTextTracksData) => {
|
||||||
@ -80,46 +102,42 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (selectedTrack?.language) {
|
if (selectedTrack?.language) {
|
||||||
setState({
|
setTextTracks(data.textTracks);
|
||||||
...state,
|
if (textTracksSelectionBy === 'index') {
|
||||||
textTracks: data.textTracks,
|
setSelectedTextTrack({
|
||||||
selectedTextTrack:
|
type: SelectedTrackType.INDEX,
|
||||||
textTracksSelectionBy === 'index'
|
value: selectedTrack?.index,
|
||||||
? {
|
});
|
||||||
type: SelectedTrackType.INDEX,
|
} else {
|
||||||
value: selectedTrack?.index,
|
setSelectedTextTrack({
|
||||||
}
|
type: SelectedTrackType.LANGUAGE,
|
||||||
: {
|
value: selectedTrack?.language,
|
||||||
type: SelectedTrackType.LANGUAGE,
|
});
|
||||||
value: selectedTrack?.language,
|
}
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setTextTracks(data.textTracks);
|
||||||
...state,
|
|
||||||
textTracks: data.textTracks,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLoad = (data: OnLoadData) => {
|
const onLoad = (data: OnLoadData) => {
|
||||||
|
setDuration(data.duration);
|
||||||
onAudioTracks(data);
|
onAudioTracks(data);
|
||||||
onTextTracks(data);
|
onTextTracks(data);
|
||||||
onVideoTracks(data);
|
onVideoTracks(data);
|
||||||
setState({...state, duration: data.duration});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onProgress = (data: OnProgressData) => {
|
const onProgress = (data: OnProgressData) => {
|
||||||
setState({...state, currentTime: data.currentTime});
|
setCurrentTime(data.currentTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSeek = (data: OnSeekData) => {
|
const onSeek = (data: OnSeekData) => {
|
||||||
setState({...state, currentTime: data.currentTime, isSeeking: false});
|
setCurrentTime(data.currentTime);
|
||||||
|
setIsSeeking(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVideoLoadStart = () => {
|
const onVideoLoadStart = () => {
|
||||||
console.log('onVideoLoadStart');
|
console.log('onVideoLoadStart');
|
||||||
setState({...state, isLoading: true});
|
setIsLoading(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onTextTrackDataChanged = (data: OnTextTrackDataChangedData) => {
|
const onTextTrackDataChanged = (data: OnTextTrackDataChangedData) => {
|
||||||
@ -128,29 +146,25 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
|
|
||||||
const onAspectRatio = (data: OnVideoAspectRatioData) => {
|
const onAspectRatio = (data: OnVideoAspectRatioData) => {
|
||||||
console.log('onAspectRadio called ' + JSON.stringify(data));
|
console.log('onAspectRadio called ' + JSON.stringify(data));
|
||||||
setState({
|
setVideoSize({videoWidth: data.width, videoHeight: data.height});
|
||||||
...state,
|
|
||||||
videoWidth: data.width,
|
|
||||||
videoHeight: data.height,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVideoBuffer = (param: OnBufferData) => {
|
const onVideoBuffer = (param: OnBufferData) => {
|
||||||
console.log('onVideoBuffer');
|
console.log('onVideoBuffer');
|
||||||
setState({...state, isLoading: param.isBuffering});
|
setIsLoading(param.isBuffering);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onReadyForDisplay = () => {
|
const onReadyForDisplay = () => {
|
||||||
console.log('onReadyForDisplay');
|
console.log('onReadyForDisplay');
|
||||||
setState({...state, isLoading: false});
|
setIsLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onAudioBecomingNoisy = () => {
|
const onAudioBecomingNoisy = () => {
|
||||||
setState({...state, paused: true});
|
setPaused(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onAudioFocusChanged = (event: OnAudioFocusChangedData) => {
|
const onAudioFocusChanged = (event: OnAudioFocusChangedData) => {
|
||||||
setState({...state, paused: !event.hasAudioFocus});
|
setPaused(!event.hasAudioFocus);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onError = (err: OnVideoErrorData) => {
|
const onError = (err: OnVideoErrorData) => {
|
||||||
@ -159,7 +173,7 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onEnd = () => {
|
const onEnd = () => {
|
||||||
if (!state.loop) {
|
if (!repeat) {
|
||||||
channelUp();
|
channelUp();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -173,53 +187,49 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const goToChannel = (channel: number) => {
|
const goToChannel = (channel: number) => {
|
||||||
setState({
|
setSrcListId(channel);
|
||||||
...state,
|
setDuration(0);
|
||||||
srcListId: channel,
|
setCurrentTime(0);
|
||||||
duration: 0.0,
|
setVideoSize({videoWidth: 0, videoHeight: 0});
|
||||||
currentTime: 0.0,
|
setIsLoading(false);
|
||||||
videoWidth: 0,
|
setAudioTracks([]);
|
||||||
videoHeight: 0,
|
setTextTracks([]);
|
||||||
isLoading: false,
|
setSelectedAudioTrack(undefined);
|
||||||
audioTracks: [],
|
setSelectedTextTrack(undefined);
|
||||||
textTracks: [],
|
setSelectedVideoTrack({
|
||||||
selectedAudioTrack: undefined,
|
type: SelectedVideoTrackType.AUTO,
|
||||||
selectedTextTrack: undefined,
|
|
||||||
selectedVideoTrack: {
|
|
||||||
type: SelectedVideoTrackType.AUTO,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const channelUp = () => {
|
const channelUp = useCallback(() => {
|
||||||
console.log('channel up');
|
console.log('channel up');
|
||||||
goToChannel((state.srcListId + 1) % srcList.length);
|
goToChannel((srcListId + 1) % srcList.length);
|
||||||
};
|
}, [srcListId]);
|
||||||
|
|
||||||
const channelDown = () => {
|
const channelDown = useCallback(() => {
|
||||||
console.log('channel down');
|
console.log('channel down');
|
||||||
goToChannel((state.srcListId + srcList.length - 1) % srcList.length);
|
goToChannel((srcListId + srcList.length - 1) % srcList.length);
|
||||||
};
|
}, [srcListId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{(srcList[state.srcListId] as AdditionalSourceInfo)?.noView ? null : (
|
{(srcList[srcListId] as AdditionalSourceInfo)?.noView ? null : (
|
||||||
<TouchableOpacity style={viewStyle}>
|
<TouchableOpacity style={viewStyle}>
|
||||||
<Video
|
<Video
|
||||||
showNotificationControls={state.showNotificationControls}
|
showNotificationControls={showNotificationControls}
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
source={currentSrc as ReactVideoSource}
|
source={currentSrc as ReactVideoSource}
|
||||||
textTracks={additional?.textTracks}
|
textTracks={additional?.textTracks}
|
||||||
adTagUrl={additional?.adTagUrl}
|
adTagUrl={additional?.adTagUrl}
|
||||||
drm={additional?.drm}
|
drm={additional?.drm}
|
||||||
style={viewStyle}
|
style={viewStyle}
|
||||||
rate={state.rate}
|
rate={rate}
|
||||||
paused={state.paused}
|
paused={paused}
|
||||||
volume={state.volume}
|
volume={volume}
|
||||||
muted={state.muted}
|
muted={muted}
|
||||||
fullscreen={state.fullscreen}
|
fullscreen={fullscreen}
|
||||||
controls={state.showRNVControls}
|
controls={controls}
|
||||||
resizeMode={state.resizeMode}
|
resizeMode={resizeMode}
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
onAudioTracks={onAudioTracks}
|
onAudioTracks={onAudioTracks}
|
||||||
onTextTracks={onTextTracks}
|
onTextTracks={onTextTracks}
|
||||||
@ -236,17 +246,17 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
onReadyForDisplay={onReadyForDisplay}
|
onReadyForDisplay={onReadyForDisplay}
|
||||||
onBuffer={onVideoBuffer}
|
onBuffer={onVideoBuffer}
|
||||||
onSeek={onSeek}
|
onSeek={onSeek}
|
||||||
repeat={state.loop}
|
repeat={repeat}
|
||||||
selectedTextTrack={state.selectedTextTrack}
|
selectedTextTrack={selectedTextTrack}
|
||||||
selectedAudioTrack={state.selectedAudioTrack}
|
selectedAudioTrack={selectedAudioTrack}
|
||||||
selectedVideoTrack={state.selectedVideoTrack}
|
selectedVideoTrack={selectedVideoTrack}
|
||||||
playInBackground={false}
|
playInBackground={false}
|
||||||
bufferConfig={{
|
bufferConfig={{
|
||||||
...bufferConfig,
|
...bufferConfig,
|
||||||
cacheSizeMB: state.useCache ? 200 : 0,
|
cacheSizeMB: useCache ? 200 : 0,
|
||||||
}}
|
}}
|
||||||
preventsDisplaySleepDuringVideoPlayback={true}
|
preventsDisplaySleepDuringVideoPlayback={true}
|
||||||
poster={state.poster}
|
poster={poster}
|
||||||
onPlaybackRateChange={onPlaybackRateChange}
|
onPlaybackRateChange={onPlaybackRateChange}
|
||||||
onPlaybackStateChanged={onPlaybackStateChanged}
|
onPlaybackStateChanged={onPlaybackStateChanged}
|
||||||
bufferingStrategy={BufferingStrategyType.DEFAULT}
|
bufferingStrategy={BufferingStrategyType.DEFAULT}
|
||||||
@ -257,9 +267,46 @@ const VideoPlayer: FC<Props> = ({}) => {
|
|||||||
<Overlay
|
<Overlay
|
||||||
channelDown={channelDown}
|
channelDown={channelDown}
|
||||||
channelUp={channelUp}
|
channelUp={channelUp}
|
||||||
setState={setState}
|
|
||||||
state={state}
|
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
|
videoTracks={videoTracks}
|
||||||
|
selectedVideoTrack={selectedVideoTrack}
|
||||||
|
setSelectedTextTrack={setSelectedTextTrack}
|
||||||
|
audioTracks={audioTracks}
|
||||||
|
controls={controls}
|
||||||
|
resizeMode={resizeMode}
|
||||||
|
textTracks={textTracks}
|
||||||
|
selectedTextTrack={selectedTextTrack}
|
||||||
|
selectedAudioTrack={selectedAudioTrack}
|
||||||
|
setSelectedAudioTrack={setSelectedAudioTrack}
|
||||||
|
setSelectedVideoTrack={setSelectedVideoTrack}
|
||||||
|
currentTime={currentTime}
|
||||||
|
setMuted={setMuted}
|
||||||
|
muted={muted}
|
||||||
|
fullscreen={fullscreen}
|
||||||
|
duration={duration}
|
||||||
|
decoration={decoration}
|
||||||
|
paused={paused}
|
||||||
|
volume={volume}
|
||||||
|
setControls={setControls}
|
||||||
|
poster={poster}
|
||||||
|
setDecoration={setDecoration}
|
||||||
|
rate={rate}
|
||||||
|
setFullscreen={setFullscreen}
|
||||||
|
setPaused={setPaused}
|
||||||
|
isLoading={isLoading}
|
||||||
|
isSeeking={isSeeking}
|
||||||
|
setIsSeeking={setIsSeeking}
|
||||||
|
repeat={repeat}
|
||||||
|
setRepeat={setRepeat}
|
||||||
|
setPoster={setPoster}
|
||||||
|
setRate={setRate}
|
||||||
|
setResizeMode={setResizeMode}
|
||||||
|
setShowNotificationControls={setShowNotificationControls}
|
||||||
|
showNotificationControls={showNotificationControls}
|
||||||
|
setUseCache={setUseCache}
|
||||||
|
setVolume={setVolume}
|
||||||
|
useCache={useCache}
|
||||||
|
srcListId={srcListId}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -13,13 +13,17 @@ import MultiValueControl, {
|
|||||||
MultiValueControlPropType,
|
MultiValueControlPropType,
|
||||||
} from '../MultiValueControl.tsx';
|
} from '../MultiValueControl.tsx';
|
||||||
import {
|
import {
|
||||||
|
AudioTrack,
|
||||||
ResizeMode,
|
ResizeMode,
|
||||||
|
SelectedTrack,
|
||||||
SelectedTrackType,
|
SelectedTrackType,
|
||||||
|
SelectedVideoTrack,
|
||||||
SelectedVideoTrackType,
|
SelectedVideoTrackType,
|
||||||
|
TextTrack,
|
||||||
VideoDecoderProperties,
|
VideoDecoderProperties,
|
||||||
VideoRef,
|
VideoRef,
|
||||||
|
VideoTrack,
|
||||||
} from 'react-native-video';
|
} from 'react-native-video';
|
||||||
import {StateType} from '../types';
|
|
||||||
import {
|
import {
|
||||||
toast,
|
toast,
|
||||||
Seeker,
|
Seeker,
|
||||||
@ -32,12 +36,91 @@ import {
|
|||||||
type Props = {
|
type Props = {
|
||||||
channelDown: () => void;
|
channelDown: () => void;
|
||||||
channelUp: () => void;
|
channelUp: () => void;
|
||||||
setState: (value: StateType) => void;
|
fullscreen: boolean;
|
||||||
state: StateType;
|
setFullscreen: (value: boolean) => void;
|
||||||
|
controls: boolean;
|
||||||
|
setControls: (value: boolean) => void;
|
||||||
|
decoration: boolean;
|
||||||
|
setDecoration: (value: boolean) => void;
|
||||||
|
showNotificationControls: boolean;
|
||||||
|
setShowNotificationControls: (value: boolean) => void;
|
||||||
|
selectedAudioTrack: SelectedTrack | undefined;
|
||||||
|
setSelectedAudioTrack: (value: SelectedTrack | undefined) => void;
|
||||||
|
selectedTextTrack: SelectedTrack | undefined;
|
||||||
|
setSelectedTextTrack: (value: SelectedTrack | undefined) => void;
|
||||||
|
selectedVideoTrack: SelectedVideoTrack;
|
||||||
|
setSelectedVideoTrack: (value: SelectedVideoTrack) => void;
|
||||||
|
setIsSeeking: (value: boolean) => void;
|
||||||
|
rate: number;
|
||||||
|
setRate: (value: number) => void;
|
||||||
|
volume: number;
|
||||||
|
setVolume: (value: number) => void;
|
||||||
|
resizeMode: ResizeMode;
|
||||||
|
setResizeMode: (value: ResizeMode) => void;
|
||||||
|
isLoading: boolean;
|
||||||
|
srcListId: number;
|
||||||
|
useCache: boolean;
|
||||||
|
setUseCache: (value: boolean) => void;
|
||||||
|
paused: boolean;
|
||||||
|
setPaused: (value: boolean) => void;
|
||||||
|
repeat: boolean;
|
||||||
|
setRepeat: (value: boolean) => void;
|
||||||
|
poster: string | undefined;
|
||||||
|
setPoster: (value: string | undefined) => void;
|
||||||
|
muted: boolean;
|
||||||
|
setMuted: (value: boolean) => void;
|
||||||
|
currentTime: number;
|
||||||
|
duration: number;
|
||||||
|
isSeeking: boolean;
|
||||||
|
audioTracks: AudioTrack[];
|
||||||
|
textTracks: TextTrack[];
|
||||||
|
videoTracks: VideoTrack[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
||||||
const {state, setState, channelUp, channelDown} = props;
|
const {
|
||||||
|
channelUp,
|
||||||
|
channelDown,
|
||||||
|
setFullscreen,
|
||||||
|
fullscreen,
|
||||||
|
setControls,
|
||||||
|
controls,
|
||||||
|
setDecoration,
|
||||||
|
decoration,
|
||||||
|
setShowNotificationControls,
|
||||||
|
showNotificationControls,
|
||||||
|
setSelectedAudioTrack,
|
||||||
|
setSelectedTextTrack,
|
||||||
|
setSelectedVideoTrack,
|
||||||
|
setIsSeeking,
|
||||||
|
rate,
|
||||||
|
setRate,
|
||||||
|
volume,
|
||||||
|
setVolume,
|
||||||
|
resizeMode,
|
||||||
|
setResizeMode,
|
||||||
|
isLoading,
|
||||||
|
srcListId,
|
||||||
|
setUseCache,
|
||||||
|
useCache,
|
||||||
|
paused,
|
||||||
|
setPaused,
|
||||||
|
setRepeat,
|
||||||
|
repeat,
|
||||||
|
setPoster,
|
||||||
|
poster,
|
||||||
|
setMuted,
|
||||||
|
muted,
|
||||||
|
duration,
|
||||||
|
isSeeking,
|
||||||
|
currentTime,
|
||||||
|
textTracks,
|
||||||
|
videoTracks,
|
||||||
|
audioTracks,
|
||||||
|
selectedAudioTrack,
|
||||||
|
selectedVideoTrack,
|
||||||
|
selectedTextTrack,
|
||||||
|
} = props;
|
||||||
const popupInfo = useCallback(() => {
|
const popupInfo = useCallback(() => {
|
||||||
VideoDecoderProperties.getWidevineLevel().then((widevineLevel: number) => {
|
VideoDecoderProperties.getWidevineLevel().then((widevineLevel: number) => {
|
||||||
VideoDecoderProperties.isHEVCSupported().then((hevc: string) => {
|
VideoDecoderProperties.isHEVCSupported().then((hevc: string) => {
|
||||||
@ -59,82 +142,62 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const toggleFullscreen = () => {
|
const toggleFullscreen = () => {
|
||||||
setState({...state, fullscreen: !state.fullscreen});
|
setFullscreen(!fullscreen);
|
||||||
};
|
};
|
||||||
const toggleControls = () => {
|
const toggleControls = () => {
|
||||||
setState({...state, showRNVControls: !state.showRNVControls});
|
setControls(!controls);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleDecoration = () => {
|
const toggleDecoration = () => {
|
||||||
setState({...state, decoration: !state.decoration});
|
setDecoration(!decoration);
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
ref.current?.setFullScreen(!state.decoration);
|
ref.current?.setFullScreen(!decoration);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleShowNotificationControls = () => {
|
const toggleShowNotificationControls = () => {
|
||||||
setState({
|
setShowNotificationControls(!showNotificationControls);
|
||||||
...state,
|
|
||||||
showNotificationControls: !state.showNotificationControls,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelectedAudioTrackChange = (itemValue: string) => {
|
const onSelectedAudioTrackChange = (itemValue: string) => {
|
||||||
console.log('on audio value change ' + itemValue);
|
console.log('on audio value change ' + itemValue);
|
||||||
if (itemValue === 'none') {
|
if (itemValue === 'none') {
|
||||||
setState({
|
setSelectedAudioTrack({
|
||||||
...state,
|
type: SelectedTrackType.DISABLED,
|
||||||
selectedAudioTrack: {
|
|
||||||
type: SelectedTrackType.DISABLED,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setSelectedAudioTrack({
|
||||||
...state,
|
type: SelectedTrackType.INDEX,
|
||||||
selectedAudioTrack: {
|
value: itemValue,
|
||||||
type: SelectedTrackType.INDEX,
|
|
||||||
value: itemValue,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelectedTextTrackChange = (itemValue: string) => {
|
const onSelectedTextTrackChange = (itemValue: string) => {
|
||||||
console.log('on value change ' + itemValue);
|
console.log('on value change ' + itemValue);
|
||||||
setState({
|
const type =
|
||||||
...state,
|
textTracksSelectionBy === 'index'
|
||||||
selectedTextTrack: {
|
? SelectedTrackType.INDEX
|
||||||
type:
|
: SelectedTrackType.LANGUAGE;
|
||||||
textTracksSelectionBy === 'index'
|
setSelectedTextTrack({type, value: itemValue});
|
||||||
? SelectedTrackType.INDEX
|
|
||||||
: SelectedTrackType.LANGUAGE,
|
|
||||||
value: itemValue,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelectedVideoTrackChange = (itemValue: string) => {
|
const onSelectedVideoTrackChange = (itemValue: string) => {
|
||||||
console.log('on value change ' + itemValue);
|
console.log('on value change ' + itemValue);
|
||||||
if (itemValue === undefined || itemValue === 'auto') {
|
if (itemValue === undefined || itemValue === 'auto') {
|
||||||
setState({
|
setSelectedVideoTrack({
|
||||||
...state,
|
type: SelectedVideoTrackType.AUTO,
|
||||||
selectedVideoTrack: {
|
|
||||||
type: SelectedVideoTrackType.AUTO,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState({
|
setSelectedVideoTrack({
|
||||||
...state,
|
type: SelectedVideoTrackType.INDEX,
|
||||||
selectedVideoTrack: {
|
value: itemValue,
|
||||||
type: SelectedVideoTrackType.INDEX,
|
|
||||||
value: itemValue,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const videoSeek = (position: number) => {
|
const videoSeek = (position: number) => {
|
||||||
setState({...state, isSeeking: true});
|
setIsSeeking(true);
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
ref.current?.seek(position);
|
ref.current?.seek(position);
|
||||||
@ -142,33 +205,45 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
|||||||
|
|
||||||
const onRateSelected = (value: MultiValueControlPropType) => {
|
const onRateSelected = (value: MultiValueControlPropType) => {
|
||||||
if (typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
setState({...state, rate: value});
|
setRate(value);
|
||||||
}
|
|
||||||
};
|
|
||||||
const onVolumeSelected = (value: MultiValueControlPropType) => {
|
|
||||||
if (typeof value === 'number') {
|
|
||||||
setState({...state, volume: value});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const onResizeModeSelected = (value: MultiValueControlPropType) => {
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
setState({...state, resizeMode: value});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onVolumeSelected = (value: MultiValueControlPropType) => {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
setVolume(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onResizeModeSelected = (value: MultiValueControlPropType) => {
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
setResizeMode(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleCache = () => setUseCache(!useCache);
|
||||||
|
|
||||||
|
const togglePause = () => setPaused(!paused);
|
||||||
|
|
||||||
|
const toggleRepeat = () => setRepeat(!repeat);
|
||||||
|
|
||||||
|
const togglePoster = () => setPoster(poster ? undefined : samplePoster);
|
||||||
|
|
||||||
|
const toggleMuted = () => setMuted(!muted);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Indicator isLoading={state.isLoading} />
|
<Indicator isLoading={isLoading} />
|
||||||
<View style={styles.topControls}>
|
<View style={styles.topControls}>
|
||||||
<View style={styles.resizeModeControl}>
|
<View style={styles.resizeModeControl}>
|
||||||
<TopControl
|
<TopControl
|
||||||
srcListId={state.srcListId}
|
srcListId={srcListId}
|
||||||
showRNVControls={state.showRNVControls}
|
showRNVControls={controls}
|
||||||
toggleControls={toggleControls}
|
toggleControls={toggleControls}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
{!state.showRNVControls ? (
|
{!controls ? (
|
||||||
<>
|
<>
|
||||||
<View style={styles.leftControls}>
|
<View style={styles.leftControls}>
|
||||||
<ToggleControl onPress={channelDown} text="ChDown" />
|
<ToggleControl onPress={channelDown} text="ChDown" />
|
||||||
@ -182,46 +257,35 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
|||||||
<View style={styles.generalControls}>
|
<View style={styles.generalControls}>
|
||||||
<ToggleControl onPress={popupInfo} text="decoderInfo" />
|
<ToggleControl onPress={popupInfo} text="decoderInfo" />
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={state.useCache}
|
isSelected={useCache}
|
||||||
onPress={() => {
|
onPress={toggleCache}
|
||||||
setState({...state, useCache: !state.useCache});
|
|
||||||
}}
|
|
||||||
selectedText="enable cache"
|
selectedText="enable cache"
|
||||||
unselectedText="disable cache"
|
unselectedText="disable cache"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={state.paused}
|
isSelected={paused}
|
||||||
onPress={() => {
|
onPress={togglePause}
|
||||||
setState({...state, paused: !state.paused});
|
|
||||||
}}
|
|
||||||
selectedText="pause"
|
selectedText="pause"
|
||||||
unselectedText="playing"
|
unselectedText="playing"
|
||||||
/>
|
/>
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={state.loop}
|
isSelected={repeat}
|
||||||
onPress={() => {
|
onPress={toggleRepeat}
|
||||||
setState({...state, loop: !state.loop});
|
|
||||||
}}
|
|
||||||
selectedText="loop enable"
|
selectedText="loop enable"
|
||||||
unselectedText="loop disable"
|
unselectedText="loop disable"
|
||||||
/>
|
/>
|
||||||
<ToggleControl onPress={toggleFullscreen} text="fullscreen" />
|
<ToggleControl onPress={toggleFullscreen} text="fullscreen" />
|
||||||
<ToggleControl onPress={toggleDecoration} text="decoration" />
|
<ToggleControl onPress={toggleDecoration} text="decoration" />
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={!!state.poster}
|
isSelected={!!poster}
|
||||||
onPress={() => {
|
onPress={togglePoster}
|
||||||
setState({
|
|
||||||
...state,
|
|
||||||
poster: state.poster ? undefined : samplePoster,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
selectedText="poster"
|
selectedText="poster"
|
||||||
unselectedText="no poster"
|
unselectedText="no poster"
|
||||||
/>
|
/>
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={state.showNotificationControls}
|
isSelected={showNotificationControls}
|
||||||
onPress={toggleShowNotificationControls}
|
onPress={toggleShowNotificationControls}
|
||||||
selectedText="hide notification controls"
|
selectedText="hide notification controls"
|
||||||
unselectedText="show notification controls"
|
unselectedText="show notification controls"
|
||||||
@ -232,13 +296,13 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
|||||||
<MultiValueControl
|
<MultiValueControl
|
||||||
values={[0, 0.25, 0.5, 1.0, 1.5, 2.0]}
|
values={[0, 0.25, 0.5, 1.0, 1.5, 2.0]}
|
||||||
onPress={onRateSelected}
|
onPress={onRateSelected}
|
||||||
selected={state.rate}
|
selected={rate}
|
||||||
/>
|
/>
|
||||||
{/* shall be replaced by slider */}
|
{/* shall be replaced by slider */}
|
||||||
<MultiValueControl
|
<MultiValueControl
|
||||||
values={[0.5, 1, 1.5]}
|
values={[0.5, 1, 1.5]}
|
||||||
onPress={onVolumeSelected}
|
onPress={onVolumeSelected}
|
||||||
selected={state.volume}
|
selected={volume}
|
||||||
/>
|
/>
|
||||||
<MultiValueControl
|
<MultiValueControl
|
||||||
values={[
|
values={[
|
||||||
@ -247,18 +311,16 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
|||||||
ResizeMode.STRETCH,
|
ResizeMode.STRETCH,
|
||||||
]}
|
]}
|
||||||
onPress={onResizeModeSelected}
|
onPress={onResizeModeSelected}
|
||||||
selected={state.resizeMode}
|
selected={resizeMode}
|
||||||
/>
|
/>
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={state.muted}
|
isSelected={muted}
|
||||||
onPress={() => {
|
onPress={toggleMuted}
|
||||||
setState({...state, muted: !state.muted});
|
|
||||||
}}
|
|
||||||
text="muted"
|
text="muted"
|
||||||
/>
|
/>
|
||||||
{isIos ? (
|
{isIos ? (
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
isSelected={state.paused}
|
isSelected={paused}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@ -276,27 +338,27 @@ const _Overlay = forwardRef<VideoRef, Props>((props, ref) => {
|
|||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
<Seeker
|
<Seeker
|
||||||
currentTime={state.currentTime}
|
currentTime={currentTime}
|
||||||
duration={state.duration}
|
duration={duration}
|
||||||
isLoading={state.isLoading}
|
isLoading={isLoading}
|
||||||
videoSeek={prop => videoSeek(prop)}
|
videoSeek={prop => videoSeek(prop)}
|
||||||
isUISeeking={state.isSeeking}
|
isUISeeking={isSeeking}
|
||||||
/>
|
/>
|
||||||
<View style={styles.generalControls}>
|
<View style={styles.generalControls}>
|
||||||
<AudioTrackSelector
|
<AudioTrackSelector
|
||||||
audioTracks={state.audioTracks}
|
audioTracks={audioTracks}
|
||||||
selectedAudioTrack={state.selectedAudioTrack}
|
selectedAudioTrack={selectedAudioTrack}
|
||||||
onValueChange={onSelectedAudioTrackChange}
|
onValueChange={onSelectedAudioTrackChange}
|
||||||
/>
|
/>
|
||||||
<TextTrackSelector
|
<TextTrackSelector
|
||||||
textTracks={state.textTracks}
|
textTracks={textTracks}
|
||||||
selectedTextTrack={state.selectedTextTrack}
|
selectedTextTrack={selectedTextTrack}
|
||||||
onValueChange={onSelectedTextTrackChange}
|
onValueChange={onSelectedTextTrackChange}
|
||||||
textTracksSelectionBy={textTracksSelectionBy}
|
textTracksSelectionBy={textTracksSelectionBy}
|
||||||
/>
|
/>
|
||||||
<VideoTrackSelector
|
<VideoTrackSelector
|
||||||
videoTracks={state.videoTracks}
|
videoTracks={videoTracks}
|
||||||
selectedVideoTrack={state.selectedVideoTrack}
|
selectedVideoTrack={selectedVideoTrack}
|
||||||
onValueChange={onSelectedVideoTrackChange}
|
onValueChange={onSelectedVideoTrackChange}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -2,11 +2,9 @@ import {
|
|||||||
BufferConfig,
|
BufferConfig,
|
||||||
DRMType,
|
DRMType,
|
||||||
ISO639_1,
|
ISO639_1,
|
||||||
ResizeMode,
|
|
||||||
SelectedVideoTrackType,
|
|
||||||
TextTrackType,
|
TextTrackType,
|
||||||
} from 'react-native-video';
|
} from 'react-native-video';
|
||||||
import {SampleVideoSource, StateType} from '../types';
|
import {SampleVideoSource} from '../types';
|
||||||
import {localeVideo} from '../assets';
|
import {localeVideo} from '../assets';
|
||||||
import {Platform} from 'react-native';
|
import {Platform} from 'react-native';
|
||||||
|
|
||||||
@ -159,36 +157,6 @@ export const srcList: SampleVideoSource[] = srcAllPlatformList.concat(
|
|||||||
isAndroid ? srcAndroidList : srcIosList,
|
isAndroid ? srcAndroidList : srcIosList,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const defaultValue: StateType = {
|
|
||||||
rate: 1,
|
|
||||||
volume: 1,
|
|
||||||
muted: false,
|
|
||||||
resizeMode: ResizeMode.CONTAIN,
|
|
||||||
duration: 0.0,
|
|
||||||
currentTime: 0.0,
|
|
||||||
videoWidth: 0,
|
|
||||||
videoHeight: 0,
|
|
||||||
paused: false,
|
|
||||||
fullscreen: true,
|
|
||||||
decoration: true,
|
|
||||||
isLoading: false,
|
|
||||||
audioTracks: [],
|
|
||||||
textTracks: [],
|
|
||||||
videoTracks: [],
|
|
||||||
selectedAudioTrack: undefined,
|
|
||||||
selectedTextTrack: undefined,
|
|
||||||
selectedVideoTrack: {
|
|
||||||
type: SelectedVideoTrackType.AUTO,
|
|
||||||
},
|
|
||||||
srcListId: 0,
|
|
||||||
loop: false,
|
|
||||||
showRNVControls: false,
|
|
||||||
useCache: false,
|
|
||||||
poster: undefined,
|
|
||||||
showNotificationControls: false,
|
|
||||||
isSeeking: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const bufferConfig: BufferConfig = {
|
export const bufferConfig: BufferConfig = {
|
||||||
minBufferMs: 15000,
|
minBufferMs: 15000,
|
||||||
maxBufferMs: 50000,
|
maxBufferMs: 50000,
|
||||||
@ -197,4 +165,4 @@ export const bufferConfig: BufferConfig = {
|
|||||||
live: {
|
live: {
|
||||||
targetOffsetMs: 500,
|
targetOffsetMs: 500,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
@ -1,14 +1,4 @@
|
|||||||
import {
|
import {Drm, ReactVideoSource, TextTracks} from 'react-native-video';
|
||||||
AudioTrack,
|
|
||||||
Drm,
|
|
||||||
ReactVideoSource,
|
|
||||||
ResizeMode,
|
|
||||||
SelectedTrack,
|
|
||||||
SelectedVideoTrack,
|
|
||||||
TextTrack,
|
|
||||||
TextTracks,
|
|
||||||
VideoTrack,
|
|
||||||
} from 'react-native-video';
|
|
||||||
|
|
||||||
export type AdditionalSourceInfo = {
|
export type AdditionalSourceInfo = {
|
||||||
textTracks: TextTracks;
|
textTracks: TextTracks;
|
||||||
@ -19,31 +9,3 @@ export type AdditionalSourceInfo = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type SampleVideoSource = ReactVideoSource | AdditionalSourceInfo;
|
export type SampleVideoSource = ReactVideoSource | AdditionalSourceInfo;
|
||||||
|
|
||||||
export interface StateType {
|
|
||||||
rate: number;
|
|
||||||
volume: number;
|
|
||||||
muted: boolean;
|
|
||||||
resizeMode: ResizeMode;
|
|
||||||
duration: number;
|
|
||||||
currentTime: number;
|
|
||||||
videoWidth: number;
|
|
||||||
videoHeight: number;
|
|
||||||
paused: boolean;
|
|
||||||
fullscreen: boolean;
|
|
||||||
decoration: boolean;
|
|
||||||
isLoading: boolean;
|
|
||||||
audioTracks: Array<AudioTrack>;
|
|
||||||
textTracks: Array<TextTrack>;
|
|
||||||
videoTracks: Array<VideoTrack>;
|
|
||||||
selectedAudioTrack: SelectedTrack | undefined;
|
|
||||||
selectedTextTrack: SelectedTrack | undefined;
|
|
||||||
selectedVideoTrack: SelectedVideoTrack;
|
|
||||||
srcListId: number;
|
|
||||||
loop: boolean;
|
|
||||||
showRNVControls: boolean;
|
|
||||||
useCache: boolean;
|
|
||||||
poster?: string;
|
|
||||||
showNotificationControls: boolean;
|
|
||||||
isSeeking: boolean;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user