Flutter中如何使用assets_audio_player播放列表内的全部音频?
问题根因
你当前的写法错误点是在循环内每次调用_assetsAudioPlayer.open(),每次传入的都是仅包含当前单条音频的Playlist,这会导致每次调用open都会直接覆盖播放器当前的播放队列,循环执行完后播放器队列里仅会保留最后一次open传入的音频,自然无法按顺序播放所有音频。
修正方案
第一步:先完整构建播放列表,再一次性传给播放器
不要在循环里调用open,先把所有Audio对象攒到一个列表里,再统一传给Playlist,一次性open:
List<String> surahAudioList = []; Future getAudioData() async { String url = 'http://api.quran.com/api/v3/chapters/${widget.surahIndex}/verses?recitation=1&page=1&limit=16&text_type=words'; var response = await http.get(Uri.parse(url)); Map<String, dynamic> map = json.decode(response.body); List<dynamic> data = map['verses']; if (surahAudioList.isNotEmpty) surahAudioList.clear(); // 先声明一个存储所有Audio对象的列表 List<Audio> audioList = []; for (var i = 0; i < data.length; i++) { String audioUrl = 'https://audio.qurancdn.com/${data[i]['audio']["url"]}'; surahAudioList.add(audioUrl); // 把所有音频都加入audioList audioList.add(Audio.network(audioUrl, metas: Metas(title: '第${i+1}节', artist: 'Reciter'))); } // 循环结束后一次性open整个播放列表 await _assetsAudioPlayer.open( Playlist(audios: audioList), showNotification: true, autoStart: false, // 配置播放完当前自动切下一首,不需要自动切可以删掉 loopMode: LoopMode.none ); print(surahAudioList); }
第二步:补充可选的切歌逻辑
如果需要支持手动切换上一首/下一首,可以补充这两个方法:
// 切换到下一首 playNext() async { await _assetsAudioPlayer.next(); } // 切换到上一首 playPrevious() async { await _assetsAudioPlayer.previous(); }
第三步:绑定播放状态同步UI
你当前使用的isPlaying变量需要和播放器的真实状态绑定,否则点击按钮后UI状态不会同步更新,建议在页面初始化时添加状态监听:
@override void initState() { super.initState(); // 监听播放器播放状态,同步更新isPlaying _assetsAudioPlayer.isPlaying.listen((playing) { setState(() { isPlaying = playing; }); }); // 可选:监听当前播放的索引变化,更新当前播放章节的UI展示 _assetsAudioPlayer.current.listen((current) { if (current != null) { print('当前播放第${current.index+1}个音频'); } }); }
内容的提问来源于stack exchange,提问作者Usama Hafeez Official
相关产品推荐
相关产品推荐

