javascriptreactjsreact-nativeexpoexpo-av

Expo-av Audio just play only the first time but not when click the button again


I'm new to react-native and expo-av. I'm using Expo-av to create an Audio Player. The problem is the audio only play the first time the button clicked. After it finished, it won't play again although I click on the play button. I already try to unload the audio but its not work. Please give me some advises.

function SeriesAudioPlayer() {
  const {colors} = useTheme();
  const [audioStatus, setAudioStatus] = useState({
    isPlaying: false,
    isPaused: false,
    duration: 0,
  });
  const setupAudio = async () => {
    Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      interruptionModeAndroid: InterruptionModeAndroid.DuckOthers,
      interruptionModeIOS: InterruptionModeIOS.DoNotMix,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      staysActiveInBackground: true,
      playThroughEarpieceAndroid: true,
    });
  };
  const [sound, setSound] = useState(new Audio.Sound());
  const status = {shouldPlay: false};
  useEffect(() => {
    setupAudio();
    sound.loadAsync(
      require('../../../../../assets/audio/cat-meow.wav'),
      status,
      false,
    );
    return () => sound.unloadAsync();
  }, [sound]);
  const playSound = () => {
    sound.playAsync();
    setAudioStatus({...audioStatus, isPlaying: true, isPaused: false});
  };
  const pauseSound = () => {
    sound.pauseAsync();
    setAudioStatus({...audioStatus, isPlaying: false, isPaused: true});
    console.log(audioStatus.isPlaying, audioStatus.isPaused);
  };

  return (
    <View style={styles.container}>
      <Pressable
        style={{paddingRight: 15}}
        onPress={audioStatus.isPlaying === false ? playSound : pauseSound}
      >
        <Icon name="play" size={17}></Icon>
      </Pressable>

      <Text style={styles.playTime}>0:00</Text>
      <Slider
        style={styles.slider}
        minimumValue={1}
        maximumValue={5}
        step={1}
        minimumTrackTintColor={colors.highlight}
        maximumTrackTintColor={colors.card}
        thumbTintColor={Colors.fuelOrange}
        tapToSeek={true}
      />
      <Text style={[styles.playTime, {paddingRight: 15}]}>2:32</Text>
      <Icon name="volume" size={17}></Icon>
    </View>
  );
}

Solution

  • It could help someone like me. For my usecase, setting the position to 0 before playing the sound worked for me.

    Since we have already played the sound first time, we have to reset the position for the upcoming plays

    const playSound = async () => {
      await sound.setPositionAsync(0);
      await sound.playAsync();
    }