时间条问题React-本机-视频

icnyk63a  于 2022-12-04  发布在  React
关注(0)|答案(1)|浏览(138)

我使用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;
inn6fuwd

inn6fuwd1#

此问题可能与在组件中使用多个useState挂钩有关。您正在使用多个同名的useState挂钩,这可能会导致混淆并导致意外行为。
例如,您将setIsFullScreen挂接用于两个不同的目的:设置视频播放器的全屏状态并切换模态的可见性。这可能会导致问题,因为这两种状态不一定相关。
一种可能的解决方案是将组件拆分为两个单独的组件:一个用于视频播放器,一个用于模态。这样,你就可以为每个组件使用单独的useState钩子,这将使管理它们的状态变得更容易。
另一个解决方案是为useState钩子使用更具描述性的名称,这样就可以清楚地了解它们的用途。例如,您可以使用setVideoPlayerFullScreensetModalVisible,而不是使用setIsFullScreen来表示视频播放器的全屏状态和模态的可见性。这应该更容易理解每种状态的用途,避免任何混淆。

相关问题