音频博览会库不暂停音频文件

时间:2021-04-25 01:16:02

标签: react-native expo audio-player

试图通过参与一个项目来学习 React Native,但遇到了阻碍。

目标:尝试创建一种自动播放功能,当按下按钮时音频文件一个接一个连续播放,再次按下该按钮时也可以暂停。

当前进展:我能够让音频一个接一个地连续播放,没有任何问题。如果你看下面的截图,音频文件是在“useEffect”中加载的,当按下按钮时,它会调用“handlePlayPause”函数,音频会持续播放。

const [autoPlayIndex, setAutoPlayIndex] = useState(0);
const [playBackInstance, setPlayBackInstance] = useState(null);
const [clickNum, setClickNum] = useState(0);

const loadAudio = async () => {
  if(autoPlayIndex < data.length) {
    if(data[autoPlayIndex].id == 101) {
      const { sound } = await Audio.Sound.createAsync(require("../assets/zoning.mp3"), {progressUpdateIntervalMillis: 100});
      sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
      setPlayBackInstance(sound);
    } else if (data[autoPlayIndex].id == 103) {
      const { sound } = await Audio.Sound.createAsync(require("../assets/draymond_green.mp3"), {progressUpdateIntervalMillis: 100});
      sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
      setPlayBackInstance(sound);
    } else {
      const { sound } = await Audio.Sound.createAsync({uri: data[autoPlayIndex].file}, {progressUpdateIntervalMillis: 100});
      sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
      setPlayBackInstance(sound);
    }
    if(clickNum % 2 != 0) {
      await playBackInstance.playAsync();
    }
  }

}

const handlePlayPause = () => {
  if(clickNum % 2 == 0) {
    playBackInstance.playAsync();
  } else {
    playBackInstance.pauseAsync()
  }

  setClickNum(clickNum => clickNum + 1);
}

const handleNext = async () => {
  setAutoPlayIndex(autoPlayIndex => autoPlayIndex + 1);
}

const onPlaybackStatusUpdate = async (status) => {
  if(status.isPlaying) {
    const duration = status.positionMillis;
    const length = status.durationMillis;
    const diff = length - duration;
    setTimeRemaining(Moment.utc(diff).format("m:ss"));
  }
  if(status.didJustFinish) {
    handleNext();
  }
}

useEffect(() => {
  if(data.length != 0 ) {
    loadAudio();
  }
}, [autoPlayIndex, clickNum]);

问题:音频文件不会立即暂停,而是在播放完当前音频剪辑后暂停。不知道究竟是为什么,因为我指定了“pauseAsync()”,但这似乎是某种异步问题之类的。

参考资料

对这个问题的任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:0)

我为您需要的实现创建了一个 Snack。希望它有所帮助。非常适合我..

不要创建 state 变量并将 Audio 实例存储在其中。这不是实现播放列表音频功能的正确方法

看,您首先必须将 Audio 实例更改为 ref。这样您就可以从代码的任何位置pause/play

在顶部创建 sound 这样的变量

const sound = useRef(new Audio.Sound());

像这样加载音频文件 -

  const LoadAudio = async (index) => {
    SetLoading(true);
    const checkLoading = await sound.current.getStatusAsync();
    if (checkLoading.isLoaded === false) {
      try {
        const result = await sound.current.loadAsync(
          Files[index].file,
          {},
          true
        );
        if (result.isLoaded === false) {
          SetLoading(false);
          SetLoaded(false);
        } else {
          sound.current.setOnPlaybackStatusUpdate(UpdateStatus);
          SetLoading(false);
          SetLoaded(true);
          SetDuration(result.durationMillis);
          PlayAudio();
        }
      } catch (error) {
        SetLoading(false);
        SetLoaded(false);
      }
    } else {
      SetLoading(false);
      SetLoaded(true);
    }
  };

Pause 函数 -

 const PauseAudio = async () => {
    try {
      const result = await sound.current.getStatusAsync();
      if (result.isLoaded) {
        if (result.isPlaying === true) {
          sound.current.pauseAsync();
          SetPlaying(false);
        }
      }
    } catch (error) {
      SetPlaying(true);
    }
  };

Play 函数 -

  const PlayAudio = async () => {
    try {
      const result = await sound.current.getStatusAsync();
      if (result.isLoaded) {
        if (result.isPlaying === false) {
          sound.current.playAsync();
          SetPlaying(true);
        }
      }
    } catch (error) {
      SetPlaying(false);
    }
  };