Flutter中使用just_audio获取播放列表当前播放歌曲详情
Flutter 基于just_audio获取当前播放歌曲全量详情方案
基于just_audio实现该需求不需要额外引入其他依赖,利用播放器自带的播放序列状态接口就能实现,状态100%和播放器内部同步,不会出现切歌后信息不匹配的问题。
前置准备
构造播放列表时,把每首歌的全量详情挂载到对应AudioSource的tag字段,这是官方预留的自定义元数据存储位,支持任意类型对象,直接传你项目内定义的歌曲实体类即可。
示例代码:
// 播放器实例 final player = AudioPlayer(); // 加载播放列表示例 await player.setAudioSource( ConcatenatingAudioSource( children: [ AudioSource.uri( Uri.parse("歌曲音频资源地址"), // 直接把歌曲全量详情存在tag字段 tag: SongDetail( id: 1, title: "晴天", artist: "周杰伦", album: "叶惠美", cover: "歌曲封面资源地址", duration: Duration(minutes: 4, seconds: 29), lyric: "歌词资源地址" ), ), // 其余歌曲按相同格式构造即可 ], ), );
两种获取方式
一次性获取当前值
在需要读取详情的时机直接调用播放器属性即可,适合触发式场景(比如点击分享按钮时拿当前歌曲信息):
SongDetail? getCurrentPlayingSong() { // 无有效播放序列时直接返回空 if (player.sequenceState == null || player.currentIndex == null) { return null; } // 读取当前播放源挂载的tag信息 return player.sequenceState!.currentSource?.tag as SongDetail?; }
实时监听变化(自动刷新UI)
做播放器常驻UI、播放页时,直接监听播放序列状态流,切歌时会自动回调最新的歌曲信息,不需要手动同步下标:
late final StreamSubscription<SequenceState?> _songListener; SongDetail? nowPlaying; @override void initState() { super.initState(); _songListener = player.sequenceStateStream.listen((state) { final currentSong = state?.currentSource?.tag as SongDetail?; if (currentSong == null) return; // 更新状态刷新UI setState(() { nowPlaying = currentSong; }); }); } @override void dispose() { // 页面销毁时取消监听避免内存泄漏 _songListener.cancel(); super.dispose(); }
注意事项
- 不要自行维护当前播放下标变量:手动切歌、自动顺播、随机/循环模式切歌、用户拖动播放列表跳转都会改变当前播放项,自己维护下标极易出现状态不同步,直接使用播放器内置的状态是最可靠的方案。
sequenceStateStream仅在当前播放项变更时触发回调,不会随播放进度频繁触发,不需要额外做防抖处理。- 应用从后台切回前台时,可主动读取一次静态属性做兜底,避免后台期间流回调被系统暂停导致UI信息滞后。
- 如果搭配audio_service做后台播放,该逻辑完全兼容,tag中存储的歌曲信息可以直接和audio_service的MediaItem做映射。
内容的提问来源于stack exchange,提问作者niaz muhammad
相关产品推荐
相关产品推荐

