React Native Sound change speed time

1.1k Views Asked by At

I'm using react-native-sound library to play audio in my app. I would like to add option to control speed time of listening.

in my AudioPlayer component I have:

const [music, setMusic] = useState(null)
const [isPlaying, setPlaying] = useState(false)
const [duration, setDuration] = useState(0)
const [currentTime, setCurrentTime] = useState(0)

useEffect(() => {
    const audio = new Sound(decodeURI(props.track.url), null, (err) => {
      if (err) {
        return
      }
    })
    Sound.setActive(true)
    Sound.setCategory('Playback', true)
    Sound.setMode('Default')
    setMusic(audio)
    return function cleanup() {
      Sound.setActive(false)
      audio.release()
    }
  }, [props.track])

  useEffect(() => {
    const interval = setInterval(() => {
      if (music && duration <= 0) {
        setDuration(music.getDuration())
      }
      if (music && isPlaying) {
        music.getCurrentTime((seconds: number) => {
          setCurrentTime(seconds)
        })
      }
    }, 100)

    return () => clearInterval(interval)
  })

  const onPlayPausePress = async () => {
    if (music.isPlaying()) {
      music.pause()
      setPlaying(false)
    } else {
      music.play(success => {
        setPlaying(false)
        // setCurrentTime(0)
        // music.setCurrentTime((0))
      })
      setPlaying(true)
    }
  }

  const manageSpeedTime = (speed) => {
    if (music.isPlaying()) {
      music.pause()
      setPlaying(false)
      music.setSpeed(speed)
      music.getCurrentTime((seconds: number) => {
        setCurrentTime(seconds)
      })
      music.setCurrentTime(currentTime)
      await music.play(success => {
        setPlaying(false)
      })
      setPlaying(true)
    }
  }

And later in my code:

        <Slider
          style={{ width: '55%', height: 40}}
          minimumValue={0}
          maximumValue={duration}
          minimumTrackTintColor={props.audioStylesProps.sliderRunColor}
          maximumTrackTintColor={props.audioStylesProps.sliderStartColor}
          thumbTintColor={props.audioStylesProps.sliderCircleColor}
          value={currentTime}
          onValueChange={onSliderChange}
        />


<View style={{flexDirection: "column"}}>
        <Button title={"1x"} onPress={() => {manageSpeedTime(1)}} color={"red"}/>
        <Button title={"1.25x"} onPress={() => {manageSpeedTime(1.25)}} color={"red"}/>
        <Button title={"2x"} onPress={() => {manageSpeedTime(2)}} color={"red"}/>
</View>

My problem is, when I speed time x2 it works fine, but when I want come back to normal speed, I got delay. For example, Im listening with x2 speed and at 40seconds I change speed to 1x, instead of starting from 40sec, my slider goes back to around 34-36 seconds and starts playing music at 40. My idea was to stop music when I change speed time, set speed, set current time and start playing, but looks like music.seetCurrentTime(currentTime) in manageSpeedTime doesn't work. Could somebody help my with solving this issue?

0

There are 0 best solutions below