试图通过参与一个项目来学习 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()”,但这似乎是某种异步问题之类的。
参考资料:
对这个问题的任何帮助将不胜感激!谢谢!
答案 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);
}
};