我使用react-native-video和react-native-media-controls来制作视频播放组件。
我能够运行视频,一切都很好。但我想要一个功能,当点击全屏视图,然后相同的视频必须运行在一个模式。
视频甚至在模态上运行。问题是当背景和模态视频都在运行时,视频的时间条表现不正常。时间条在两个不同的时间之间振荡。
我不知道是什么问题。
const ChatVideoPlayerComponent = () => {
const videoPlayer = useRef<any>(null);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [isFullScreen, setIsFullScreen] = useState(false);
const [isPlayerLoading, setIsPlayerLoading] = useState(true);
const [paused, setPaused] = useState(false);
const [playerState, setPlayerState] = useState(PLAYER_STATES.PLAYING);
const [screenType, setScreenType] = useState('content');
const [modalVisible, setModalVisible] = useState(false);
const onSeek = (seek: any) => {
videoPlayer.current.seek(seek);
console.log('seek');
};
const onPaused = (playerState: any) => {
setPaused(!paused);
setPlayerState(playerState);
};
const onReplay = () => {
setPlayerState(PLAYER_STATES.PLAYING);
videoPlayer.current.seek(0);
};
const onProgress = (data: any) => {
if (!isPlayerLoading && playerState !== PLAYER_STATES.ENDED) {
setCurrentTime(data.currentTime);
}
};
const onLoad = (data: any) => {
setDuration(data.duration);
setIsPlayerLoading(false);
};
const onLoadStart = (data: any) => setIsPlayerLoading(true);
const onEnd = () => setPlayerState(PLAYER_STATES.ENDED);
const onError = () => {
console.log('error');
};
const onFullScreen = () => {
setIsFullScreen(isFullScreen);
setModalVisible(!modalVisible);
if (screenType == 'content') setScreenType('cover');
else setScreenType('content');
};
const renderToolbar = () => {
return (
<View>
<Text style={styles.toolbar}> toolbar </Text>
</View>
);
};
const onSeeking = (currentTime: any) => {
setCurrentTime(currentTime);
console.log('seeking');
};
const fullScreenModal = () => {
return (
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
setModalVisible(!modalVisible);
}}>
<View style={styles.modalContainer2}>
<View style={styles.modalView2}>
<View style={styles.modalCloseContainer}>
<TouchableOpacity
onPress={() => {
setModalVisible(!modalVisible);
}}>
<ImageConfig.CloseCircle height={'25'} width={'25'} />
</TouchableOpacity>
</View>
<View
style={{
alignItems: 'center',
marginVertical: 25,
}}>
<Video
onEnd={onEnd}
onLoad={onLoad}
onLoadStart={onLoadStart}
onProgress={onProgress}
paused={paused}
ref={videoPlayer}
resizeMode={'cover'}
onFullScreen={isFullScreen}
source={{uri: 'https://assets.mixkit.co/videos/download/mixkit-countryside-meadow-4075.mp4'}}
style={{height: 200, width: '100%'}}
volume={10}
onError={onError}
repeat={true}
/>
<View
style={{
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
height: 200,
width: '100%',
}}>
<MediaControls
duration={duration}
isLoading={isPlayerLoading}
mainColor="#333"
onFullScreen={onFullScreen}
onPaused={onPaused}
onReplay={onReplay}
onSeek={onSeek}
onSeeking={onSeeking}
playerState={playerState}
progress={currentTime}
toolbar={renderToolbar()}></MediaControls>
</View>
</View>
</View>
</View>
</Modal>
);
};
return (
<View style={{justifyContent: 'flex-start'}}>
<Video
onEnd={onEnd}
onLoad={onLoad}
onLoadStart={onLoadStart}
onProgress={onProgress}
paused={paused}
ref={videoPlayer}
resizeMode={'cover'}
onFullScreen={isFullScreen}
source={{uri: 'https://assets.mixkit.co/videos/download/mixkit-countryside-meadow-4075.mp4'}}
style={{height: 200, width: 200}}
volume={10}
onError={onError}
repeat={true}
/>
<View
style={{
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
height: 200,
width: '100%',
}}>
<MediaControls
duration={duration}
isLoading={isPlayerLoading}
mainColor="#333"
onFullScreen={onFullScreen}
onPaused={onPaused}
onReplay={onReplay}
onSeek={onSeek}
onSeeking={onSeeking}
playerState={playerState}
progress={currentTime}
toolbar={renderToolbar()}></MediaControls>
{fullScreenModal()}
</View>
</View>
);
};
const styles = StyleSheet.create({
toolbar: {
marginTop: 30,
backgroundColor: 'red',
padding: 10,
borderRadius: 5,
},
modalContainer2: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#000000A0',
},
modalView2: {
marginHorizontal: 10,
backgroundColor: 'white',
borderRadius: 20,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
modalCloseContainer: {
width: '100%',
alignItems: 'flex-end',
paddingHorizontal: 20,
paddingTop: 10,
},
});
export default ChatVideoPlayerComponent;
1条答案
按热度按时间inn6fuwd1#
此问题可能与在组件中使用多个
useState
挂钩有关。您正在使用多个同名的useState
挂钩,这可能会导致混淆并导致意外行为。例如,您将
setIsFullScreen
挂接用于两个不同的目的:设置视频播放器的全屏状态并切换模态的可见性。这可能会导致问题,因为这两种状态不一定相关。一种可能的解决方案是将组件拆分为两个单独的组件:一个用于视频播放器,一个用于模态。这样,你就可以为每个组件使用单独的useState钩子,这将使管理它们的状态变得更容易。
另一个解决方案是为
useState
钩子使用更具描述性的名称,这样就可以清楚地了解它们的用途。例如,您可以使用setVideoPlayerFullScreen
和setModalVisible
,而不是使用setIsFullScreen
来表示视频播放器的全屏状态和模态的可见性。这应该更容易理解每种状态的用途,避免任何混淆。