React-Sound - Go back to saved position seems imprecise?

770 Views Asked by At

I have a Component which uses 'react-sound' (which uses soundmanager2) in order to play a file. When I pause, the file pauses and when I then press play, it starts at exactly the position I left off at.

However, I tried to implement a button which always goes back to the position at which I previously paused. So I would pause the file, then listen to it for another 5 seconds, press that replay button, and then would listen to the exact thing again from the last position I paused at. At least that's the idea.

What I implemented below does work. However, sometimes (not always, it seems to me), it does not go to the exact position, but starts a tiny bit earlier.

Why might this be? I first thought that mp3 might not be the most precise file format, but I have also have this happen with .wav files & more importantly, it does not happen whenever I press play/pause.

// Import React
import React from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import Sound from 'react-sound';

class AudioPlayer extends React.Component{

  constructor(props) {
    super(props);

    this.state = {
       playStatus: Sound.status.STOPPED,
       elapsed: 0,
       total: 0,
       playFromPosition: 0,
       lastPause: 0,
     }
  }

  togglePlay() {
    if(this.state.playStatus === Sound.status.PLAYING){
     // Pause if playing
     this.setState({playStatus: Sound.status.PAUSED})

     this.setState({playStatus: Sound.status.PAUSED, lastPause: this.state.elapsed});
   } else {
     // Resume if paused
     this.setState({playStatus: Sound.status.PLAYING})
   }
  }

  repeat() {
    if(this.state.playFromPosition != this.state.lastPause) {
        this.setState({playFromPosition: this.state.lastPause});
    } else {
        var newPos = this.state.lastPause + 0.0001;
        this.setState({playFromPosition: newPos});
    }
  }

  forward(){
    this.setState({playFromPosition: this.state.elapsed + 1000*10});
  }

  backward(){
    this.setState({playFromPosition: this.state.elapsed - 1000*10});
  }

  handleSongPlaying(audio){
     this.setState({
                      elapsed: audio.position,
                      total: audio.duration})
   }

  render() {
    return (
      <div className="row handle">
        <Sound
            url="./sound.mp3"
            playStatus={this.state.playStatus}
            onPlaying={this.handleSongPlaying.bind(this)}
            playFromPosition={this.state.playFromPosition}
            />

        <button onClick={this.togglePlay.bind(this)}>Play / Pause</button>
        <button onClick={this.repeat.bind(this)}>Replay</button>
        <button onClick={this.backward.bind(this)}>Rewind 2 sec</button>
        <button onClick={this.forward.bind(this)}>Forward 2 sec</button>
      </div>
    );
  }
}
...
0

There are 0 best solutions below