268 lines
7.3 KiB
TypeScript
Raw Normal View History

2015-12-06 22:25:18 -08:00
'use strict';
import React, {FC, useRef, useState} from 'react';
2016-04-22 00:01:44 -04:00
import {TouchableOpacity, View} from 'react-native';
2016-02-10 11:39:54 +00:00
import Video, {
AudioTrack,
OnAudioTracksData,
OnLoadData,
OnProgressData,
OnTextTracksData,
OnVideoAspectRatioData,
TextTrack,
OnBufferData,
OnAudioFocusChangedData,
OnVideoErrorData,
VideoRef,
OnTextTrackDataChangedData,
OnSeekData,
OnPlaybackStateChangedData,
OnPlaybackRateChangeData,
OnVideoTracksData,
SelectedVideoTrackType,
BufferingStrategyType,
ReactVideoSource,
SelectedTrackType,
} from 'react-native-video';
import styles from './styles';
import {AdditionalSourceInfo} from './types';
import {
bufferConfig,
defaultValue,
srcList,
textTracksSelectionBy,
} from './constants';
import {Overlay, toast} from './components';
type Props = NonNullable<unknown>;
const VideoPlayer: FC<Props> = ({}) => {
const [state, setState] = useState(defaultValue);
const videoRef = useRef<VideoRef>(null);
const viewStyle = state.fullscreen ? styles.fullScreen : styles.halfScreen;
const currentSrc = srcList[state.srcListId];
const additional = currentSrc as AdditionalSourceInfo;
const onAudioTracks = (data: OnAudioTracksData) => {
const selectedTrack = data.audioTracks?.find((x: AudioTrack) => {
return x.selected;
});
if (selectedTrack?.index) {
setState({
...state,
audioTracks: data.audioTracks,
selectedAudioTrack: {
type: SelectedTrackType.INDEX,
value: selectedTrack?.index,
},
});
} else {
setState({
...state,
audioTracks: data.audioTracks,
});
}
};
const onVideoTracks = (data: OnVideoTracksData) => {
console.log('onVideoTracks', data.videoTracks);
setState({
...state,
videoTracks: data.videoTracks,
});
};
const onTextTracks = (data: OnTextTracksData) => {
const selectedTrack = data.textTracks?.find((x: TextTrack) => {
return x?.selected;
});
if (selectedTrack?.language) {
setState({
...state,
textTracks: data.textTracks,
selectedTextTrack:
textTracksSelectionBy === 'index'
? {
type: SelectedTrackType.INDEX,
value: selectedTrack?.index,
}
: {
type: SelectedTrackType.LANGUAGE,
value: selectedTrack?.language,
},
});
} else {
setState({
...state,
textTracks: data.textTracks,
});
}
};
const onLoad = (data: OnLoadData) => {
onAudioTracks(data);
onTextTracks(data);
onVideoTracks(data);
setState({...state, duration: data.duration});
};
const onProgress = (data: OnProgressData) => {
setState({...state, currentTime: data.currentTime});
};
const onSeek = (data: OnSeekData) => {
setState({...state, currentTime: data.currentTime, isSeeking: false});
};
const onVideoLoadStart = () => {
console.log('onVideoLoadStart');
setState({...state, isLoading: true});
};
const onTextTrackDataChanged = (data: OnTextTrackDataChangedData) => {
console.log(`Subtitles: ${JSON.stringify(data, null, 2)}`);
};
const onAspectRatio = (data: OnVideoAspectRatioData) => {
console.log('onAspectRadio called ' + JSON.stringify(data));
setState({
...state,
videoWidth: data.width,
videoHeight: data.height,
});
};
const onVideoBuffer = (param: OnBufferData) => {
console.log('onVideoBuffer');
setState({...state, isLoading: param.isBuffering});
};
const onReadyForDisplay = () => {
console.log('onReadyForDisplay');
setState({...state, isLoading: false});
2017-01-11 12:51:45 +00:00
};
const onAudioBecomingNoisy = () => {
setState({...state, paused: true});
2017-01-11 12:51:45 +00:00
};
2015-12-06 22:25:18 -08:00
const onAudioFocusChanged = (event: OnAudioFocusChangedData) => {
setState({...state, paused: !event.hasAudioFocus});
};
const onError = (err: OnVideoErrorData) => {
console.log(JSON.stringify(err));
toast(true, 'error: ' + JSON.stringify(err));
};
const onEnd = () => {
if (!state.loop) {
channelUp();
}
};
const onPlaybackRateChange = (data: OnPlaybackRateChangeData) => {
console.log('onPlaybackRateChange', data);
};
const onPlaybackStateChanged = (data: OnPlaybackStateChangedData) => {
console.log('onPlaybackStateChanged', data);
};
const goToChannel = (channel: number) => {
setState({
...state,
srcListId: channel,
duration: 0.0,
currentTime: 0.0,
videoWidth: 0,
videoHeight: 0,
isLoading: false,
audioTracks: [],
textTracks: [],
selectedAudioTrack: undefined,
selectedTextTrack: undefined,
selectedVideoTrack: {
type: SelectedVideoTrackType.AUTO,
},
});
};
const channelUp = () => {
console.log('channel up');
goToChannel((state.srcListId + 1) % srcList.length);
};
const channelDown = () => {
console.log('channel down');
goToChannel((state.srcListId + srcList.length - 1) % srcList.length);
};
return (
<View style={styles.container}>
{(srcList[state.srcListId] as AdditionalSourceInfo)?.noView ? null : (
<TouchableOpacity style={viewStyle}>
<Video
showNotificationControls={state.showNotificationControls}
ref={videoRef}
source={currentSrc as ReactVideoSource}
textTracks={additional?.textTracks}
adTagUrl={additional?.adTagUrl}
drm={additional?.drm}
style={viewStyle}
rate={state.rate}
paused={state.paused}
volume={state.volume}
muted={state.muted}
fullscreen={state.fullscreen}
controls={state.showRNVControls}
resizeMode={state.resizeMode}
onLoad={onLoad}
onAudioTracks={onAudioTracks}
onTextTracks={onTextTracks}
onVideoTracks={onVideoTracks}
onTextTrackDataChanged={onTextTrackDataChanged}
onProgress={onProgress}
onEnd={onEnd}
progressUpdateInterval={1000}
onError={onError}
onAudioBecomingNoisy={onAudioBecomingNoisy}
onAudioFocusChanged={onAudioFocusChanged}
onLoadStart={onVideoLoadStart}
onAspectRatio={onAspectRatio}
onReadyForDisplay={onReadyForDisplay}
onBuffer={onVideoBuffer}
onSeek={onSeek}
repeat={state.loop}
selectedTextTrack={state.selectedTextTrack}
selectedAudioTrack={state.selectedAudioTrack}
selectedVideoTrack={state.selectedVideoTrack}
playInBackground={false}
bufferConfig={{
...bufferConfig,
cacheSizeMB: state.useCache ? 200 : 0,
}}
preventsDisplaySleepDuringVideoPlayback={true}
poster={state.poster}
onPlaybackRateChange={onPlaybackRateChange}
onPlaybackStateChanged={onPlaybackStateChanged}
bufferingStrategy={BufferingStrategyType.DEFAULT}
debug={{enable: true, thread: true}}
/>
</TouchableOpacity>
)}
<Overlay
channelDown={channelDown}
channelUp={channelUp}
setState={setState}
state={state}
ref={videoRef}
/>
</View>
);
};
export default VideoPlayer;