Expo Av音频连续播放求助:如何监听音频结束自动播放下一个
解决Expo Audio自动播放下一个音频的问题
要实现音频播放完毕后自动切换下一个,核心是监听音频的播放状态更新事件,通过Expo Audio提供的setOnPlaybackStatusUpdate方法检测播放结束的触发点。以下是针对你现有代码的修改方案:
关键修改点
- 添加状态维护当前播放的音频索引(
currentTrackIndex) - 在创建音频实例后,设置播放状态回调,监听
didJustFinish标记 - 播放结束时自动触发下一个音频的播放逻辑
修改后的完整代码
import { useState, useEffect } from 'react'; import { Audio } from 'expo-av'; export default function AudioPlayer() { const [listView, setListView] = useState(true); const [ayahData, setAyahData] = useState([]); // 假设这里存储音频URL数组,比如[{url: 'xxx'}, ...] const [sound, setSound] = useState(null); const [currentTrackIndex, setCurrentTrackIndex] = useState(0); // 卸载音频的清理逻辑 useEffect(() => { return sound ? () => { sound.setOnPlaybackStatusUpdate(null); // 先清除回调 sound.unloadAsync(); } : undefined; }, [sound]); // 播放指定索引的音频 async function playTrack(index) { // 如果有正在播放的音频,先卸载 if (sound) { await sound.unloadAsync(); } const trackURL = ayahData[index]?.url; if (!trackURL) return; const { sound: newSound } = await Audio.Sound.createAsync({ uri: trackURL }); setSound(newSound); setCurrentTrackIndex(index); // 设置播放状态更新回调 newSound.setOnPlaybackStatusUpdate((status) => { // 检测是否播放完毕(didJustFinish为true表示刚播放结束) if (status.didJustFinish) { // 播放下一个,注意边界判断 if (index < ayahData.length - 1) { playTrack(index + 1); } else { // 可选:播放完最后一个后的逻辑,比如重置索引或停止 console.log('所有音频播放完毕'); } } }); await newSound.playAsync(); } // 示例:点击开始播放第一个音频 return ( <button onClick={() => playTrack(0)}>开始播放</button> ); }
核心逻辑说明
setOnPlaybackStatusUpdate会实时返回音频的播放状态,其中didJustFinish是专门标记播放自然结束的属性(区别于手动暂停)- 每次播放新音频前,先卸载上一个音频实例并清除回调,避免内存泄漏
- 通过
currentTrackIndex维护当前播放位置,方便切换到下一个音频
注意:确保ayahData是包含所有音频URL的数组,比如格式为[{url: 'https://xxx.mp3'}, ...],这样才能正确获取下一个音频的地址。
内容的提问来源于stack exchange,提问作者Hey
相关产品推荐
相关产品推荐

