You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:12:03