Flutter使用audio_service与just_audio时如何更新队列MediaItem的Rating属性
解决方案
问题原因
直接修改queue.value列表的内部元素存在两个问题:
- 没有触发
ValueNotifier的状态更新通知,audio_service不会向客户端广播新的队列状态 - 没有同步修改just_audio持有的播放列表源,两者状态不匹配导致修改不生效
正确实现步骤
你需要同时同步just_audio的播放源和audio_service的队列状态,示例代码如下:
// 假设你已定义just_audio播放器实例,以及作为播放列表的ConcatenatingAudioSource final AudioPlayer _player = AudioPlayer(); final ConcatenatingAudioSource _playlist = ConcatenatingAudioSource(children: []); @override Future<void> updateMediaItem(MediaItem mediaItem) async { // 1. 找到对应索引 int index = queue.value.indexWhere((item) => item.id == mediaItem.id); if (index == -1) return; // 2. 同步更新just_audio播放列表对应AudioSource的tag属性 if (index < _playlist.length) { final oldSource = _playlist.children[index]; // 用新的MediaItem作为tag创建新的AudioSource,这里根据你实际用的AudioSource类型调整(比如UriAudioSource、ClippingAudioSource等) final newSource = AudioSource.uri( Uri.parse(mediaItem.id), tag: mediaItem, ); // 替换播放列表中的对应项,播放地址不变的情况下不会中断当前播放 await _playlist.replaceRange(index, index + 1, [newSource]); } // 3. 更新audio_service的队列,必须生成新的列表赋值,才能触发ValueNotifier通知 final newQueue = List<MediaItem>.from(queue.value); newQueue[index] = mediaItem; queue.value = newQueue; // 4. 如果修改的是当前正在播放的项,主动调用父类方法通知客户端当前播放项更新 if (index == _player.currentIndex) { await super.updateMediaItem(mediaItem); } }
注意事项
- 替换
AudioSource的时候要和你初始化播放列表时用的AudioSource类型、参数保持一致,仅替换tag为新的MediaItem即可,不要修改播放地址等核心播放参数,避免播放中断 - 如果点赞操作是从Flutter UI层发起的,直接调用
AudioService.updateMediaItem(updatedMediaItem)即可触发该回调,不需要额外处理跨进程通信逻辑
内容的提问来源于stack exchange,提问作者Alex Aung
相关产品推荐
相关产品推荐

