Flutter使用audio_service与just_audio在iOS端播放异常问题咨询
[NowPlaying] [MRNowPlaying] Ignoring setPlaybackState because application does not contain entitlement com.apple.mediaremote.set-playback-state for platform
这个iOS平台抛出的报错本质是媒体播放状态同步时序冲突,并不是真的缺少com.apple.mediaremote.set-playback-state权限。苹果MediaRemote框架会在应用音频会话未完成激活、播放队列还未同步到系统现在播放中心时,拒绝应用的播放状态更新请求,就会触发这个报错。
你的现有代码连续执行队列添加、跳转到指定项、播放三个异步操作,但内部队列状态同步到系统的操作没有等待完成,iOS端状态同步速度慢于Android,就会出现Android正常iOS报错的情况。
步骤1:确认基础权限配置
首先检查Xcode项目配置,确保已经开启后台音频能力:
- 打开iOS项目的Runner.xcworkspace
- 进入Signing & Capabilities标签页
- 添加Background Modes能力,勾选
Audio, AirPlay, and Picture in Picture选项
步骤2:修正异步方法实现
你的skipToQueueItem方法没有等待seek异步操作完成就返回,会导致状态不同步,修改为:
@override Future<void> skipToQueueItem(int index) async { if (index < 0 || index >= queue.value.length) return; if (_player.shuffleModeEnabled) { index = _player.shuffleIndices![index]; } // 新增await等待seek操作执行完成 await _player.seek(Duration.zero, index: index); }
步骤3:调整调用时序适配iOS特性
iOS系统同步播放队列到现在播放中心有延迟,在多个操作之间增加短延迟等待同步完成,修改loadFirstPlayList方法:
Future<void> loadFirstPlayList(List<MediaItem> playlist, int index) async { await emptyPlaylist(); if (playlist.isNotEmpty) { await _audioHandler.addQueueItems(playlist); // iOS端等待队列同步完成 if (defaultTargetPlatform == TargetPlatform.iOS) { await Future.delayed(const Duration(milliseconds: 150)); } await _audioHandler.skipToQueueItem(index); // iOS端等待跳转操作完成 if (defaultTargetPlatform == TargetPlatform.iOS) { await Future.delayed(const Duration(milliseconds: 50)); } await _audioHandler.play(); } }
注:
defaultTargetPlatform需要导入package:flutter/foundation.dart使用,也可以通过BuildContext获取当前平台。
如果修改后仍偶现报错,可以在addQueueItems方法中监听queue流的更新回调,确认系统收到队列更新后再返回方法,避免提前执行后续操作。
内容的提问来源于stack exchange,提问作者Alex Aung

