如何通过just_audio获取播放列表当前歌曲的URL及名称?
解决方法
方法一:给AudioSource附加Sound元数据(推荐)
直接在创建AudioSource时,将对应的Sound对象作为tag参数传入,后续可直接从当前播放源中取出Sound信息,无需额外匹配:
修改添加播放列表的代码:
final tracks = Sound.sounds.toList(); tracks.forEach((element) { playlist.add( AudioSource.uri( Uri.parse(element.url), tag: element, // 将Sound对象绑定到AudioSource的tag上 ), ); });
监听播放状态获取当前歌曲名称:
通过监听播放器的sequenceStateStream或currentIndexStream,取出当前播放源的tag即可拿到Sound对象:
@override void initState() { super.initState(); // 监听播放序列状态变化 player.sequenceStateStream.listen((state) { if (state?.currentSource is UriAudioSource) { final currentSource = state!.currentSource as UriAudioSource; final Sound currentSound = currentSource.tag as Sound; setState(() { // 更新界面显示的歌曲名称 currentSongName = currentSound.name; }); } }); }
方法二:通过索引匹配Sound列表
如果不想使用tag,可以利用播放列表的索引与Sound.sounds的索引对应关系(注意随机播放时需要转换索引):
@override void initState() { super.initState(); player.currentIndexStream.listen((index) { if (index != null) { // 处理随机播放的索引转换:如果开启随机,用shuffleIndices映射原始索引 final actualIndex = player.shuffleIndices?[index] ?? index; if (actualIndex >= 0 && actualIndex < Sound.sounds.length) { setState(() { currentSongName = Sound.sounds[actualIndex].name; }); } } }); }
方法三:从AudioSource中提取URL再匹配(不推荐)
如果一定要通过URL匹配,可从ProgressiveAudioSource(属于UriAudioSource子类)中取出URI并转为字符串,再遍历Sound.sounds匹配:
player.sequenceStateStream.listen((state) { if (state?.currentSource is UriAudioSource) { final uri = (state!.currentSource as UriAudioSource).uri; final currentUrl = uri.toString(); // 遍历Sound列表匹配URL final currentSound = Sound.sounds.firstWhere( (sound) => sound.url == currentUrl, orElse: () => Sound(name: '未知', url: '', category: ''), ); setState(() { currentSongName = currentSound.name; }); } });
注意:这种方法每次都要遍历列表,性能不如前两种,且如果存在相同URL的歌曲会出现匹配错误。
内容的提问来源于stack exchange,提问作者Trick Shot
相关产品推荐
相关产品推荐

