在React Native中如何按顺序连续播放数组内的音频轨道?
React Native 音频数组顺序连续播放解决方案
你现有代码无法连续播放的核心原因有两个:
- Sound 实例仅在组件首次渲染时初始化了一次,后续 id 变更不会自动创建新的音频实例加载对应文件
- 第一个音频播放完成后触发 setId 更新,没有自动触发新音频的加载和播放逻辑
修复后的可运行代码
import { useState, useEffect, useRef } from 'react'; import { View, Image, TouchableOpacity } from 'react-native'; import Sound from 'react-native-sound'; Sound.setCategory('Playback'); const AudioPlayer = () => { // 替换为实际的音频总数量 const TOTAL_AUDIO_COUNT = 10; const [id, setId] = useState(1); // 用ref存储音频实例和播放状态,避免渲染丢失 const soundRef = useRef(null); const isPlayingRef = useRef(false); // 监听id变化,自动加载对应音频并播放 useEffect(() => { // 超出音频总数停止播放 if (id > TOTAL_AUDIO_COUNT) { isPlayingRef.current = false; return; } // 销毁旧实例释放内存 if (soundRef.current) { soundRef.current.release(); } // 初始化新音频实例 const newSound = new Sound(`/data/user/0/com.hay/cache/${id}.mp3`, Sound.MAIN_BUNDLE, (error) => { if (error) { console.log('音频加载失败:', error); // 加载失败自动跳转下一个 setId(prev => prev + 1); return; } // 加载完成自动播放 newSound.play((success) => { if (!success) { console.log('播放失败'); } // 播放结束后自动跳转下一个 setId(prev => prev + 1); }); }); soundRef.current = newSound; isPlayingRef.current = true; // 组件卸载或id变化前销毁实例,避免内存泄漏 return () => { if (soundRef.current) { soundRef.current.stop(); soundRef.current.release(); } }; }, [id]); const playA = () => { // 避免重复触发播放 if (isPlayingRef.current) return; // 从第一个音频开始播放 setId(1); }; return ( <View style={{flex: 1, backgroundColor: '#FFEDCB', justifyContent: 'center'}}> <View style={{alignSelf: 'center'}} > <Image source={globo} style={{width: 340, height: 484}} /> <View style={{ position: 'absolute', top: 403 }}> <View style={{flexDirection: 'row',position: 'absolute', right: -120 }}> <TouchableOpacity onPress={playA} style={styles.iconHeart}> <Icon name={'play-circle-outline'} size={60} color='#F8C56A' /> </TouchableOpacity> </View> </View> </View> </View> ); };
核心逻辑说明
- 用
useRef存储音频实例和播放状态,避免组件重新渲染导致实例丢失、重复触发播放 - 通过
useEffect监听播放id的变化,每次id更新时先销毁旧音频实例,再加载新的音频文件自动播放 - 音频播放完成的回调中更新id,自动触发下一个音频的加载播放流程
- 增加了边界判断,音频全部播放完成后自动停止,不会无限自增id
注意事项
- 把代码中的
TOTAL_AUDIO_COUNT替换为你实际的音频总数 - 如果你的音频路径不是固定数字命名规则,可以把id换成音频路径数组的下标,遍历数组播放即可
- 可根据需求自行扩展暂停、停止的控制逻辑,直接调用
soundRef.current对应的暂停、停止方法即可
内容的提问来源于stack exchange,提问作者Xenia
相关产品推荐
相关产品推荐

