skypower
skypower

Reputation: 159

Unexpected behaviour using seek in react-native-video

In react-native-video, whenever I click on the (custom) progress bar on a value less than 50% (half of it), the video jumps to start instead of seeking to the right time. When I click above 50%, it goes to 50%. It's not actually 50, more like 55-60 but whatever. This is really weird, was not able to find anything online!

import Video from 'react-native-video';
import ProgressBar from "react-native-progress/Bar";


class Welcome extends React.Component {

  player;

  constructor(props) {
    super(props)
    //this.player = React.createRef();
    this.state = {
      paused: false,
      loaded: false,
      progress: 0,
      duration: 0,
      pressed:false,
      screenType: 'contain',
    };

    console.log("--- Screen --- Welcome")
  }

 componentDidMount = () => {
   setTimeout(() => {
     this.player.seek(8)
   },8000)
 }


   handleMainButtonTouch = () => {
     console.log("inside handleMainButtonTouch")
     console.log(this.state.progress)
     if (this.state.progress >= 1) {
       this.player.seek(0);
     }
     this.setState(state => {
       return {
         paused: !state.paused,
       };
     });
   };

   handleProgressPress = e => {
     const position = e.nativeEvent.locationX;
     const progress = parseFloat(position / 250) * this.state.duration;
     const isPlaying = !this.state.paused;

     this.player.seek(progress);
   };

   handleProgress = progress => {
     this.setState({
       progress: parseFloat(progress.currentTime) / parseFloat(this.state.duration),
     });

   };

   handleEnd = () => {
     this.setState({
       paused: true ,
       progress: 0 ,
     });
     this.player.seek(0);
   };

   handleLoad = meta => {
     this.setState({
       loaded: true,
       duration: meta.duration,
     });
   };

   handleFullScreen = () => {
     if (this.state.screenType == 'contain')
       this.setState({ screenType: 'cover' });
     else this.setState({ screenType: 'contain' });
   };


  render() {

      return (
        <View style={styles.container}>
          <View style={this.handleOuterViewStyle()}>

            <Video
              paused={this.state.paused}
              source={{uri: "https://res.cloudinary.com/dy6bbey4u/video/upload/v1565532579/fam/videos/sample.mp4"}}
              resizeMode={this.state.screenType}
              onLoad={this.handleLoad}
              onProgress={this.handleProgress}
              onEnd={this.handleEnd}
              ref={ref => {
                this.player = ref;
              }}
            />
            { this.state.loaded &&
              <View style={styles.controls}>
                <TouchableWithoutFeedback onPress={this.handleMainButtonTouch}>
                  <Text>Play</Text>
                </TouchableWithoutFeedback>
                <TouchableWithoutFeedback onPress={this.handleProgressPress}>
                  <View>
                    <ProgressBar
                      animated={false}
                      progress={this.state.progress}
                      color="#FFF"
                      borderColor="#FFF"
                      width={250}
                      height={20}
                    />
                  </View>
                </TouchableWithoutFeedback>
                <TouchableWithoutFeedback onPress={this.handleFullScreen}>
                  <Text style={styles.fullscreenButton}>Full</Text>
                </TouchableWithoutFeedback>
              </View>
            }
          </View>

        </View>
      )

  }
}

export default Welcome

Upvotes: 3

Views: 6124

Answers (4)

Irmak Coşar Şahna
Irmak Coşar Şahna

Reputation: 204

I have experienced this problem myself, and after some effort, I found the cause of the problem. When you click on the unfilled part of the progress bar that you used, you are getting the locationX data of the width you gave, and it works correctly. However, when you click on the filled part, it gives the width of the proportion of the filled part, so it assigns it to the corresponding slice. Actually, the working principle is correct, and if I come to how I solved it.

You can solve the problem by adding pointerEvents="box-only" to the View component that you used as a wrapper.

<View pointerEvents="box-only">
    <Progress.Bar
        progress={state.progress}
        color={"#fff"}
        unfilledColor={"rgba(255,255,255,0.5)"}
        width={250}
        height={15}
    />
</View>

Upvotes: 0

Ovidiu Cristescu
Ovidiu Cristescu

Reputation: 1043

So the solution for me was changing line 640 from android/src/main/java/com/brentvatne/react/ReactVideoView.java

- super.seekTo(msec);
+ mMediaPlayer.seekTo(msec,3);

Original response: https://github.com/react-native-video/react-native-video/issues/2230#issuecomment-892982288

Upvotes: 0

Oh Kilho
Oh Kilho

Reputation: 11

ffmpeg -i input.mp4 -force_key_frames "expr:gte(t,n_forced*1)"  output.mp4

Solved by forcing adding keyframes to the video.

Upvotes: 1

hamza ajaz
hamza ajaz

Reputation: 1244

I was also facing the same problem. Whenever i backward the video, it goes forward. The problem is depending on the video format. I was using the Webm format. Now the mp4 format solved the problem. P.S. Sorry for the late reply.

Upvotes: 1

Related Questions