iOS端Audio Players播放音频报AVPlayerItem.Status.failed如何解决
Flutter audioplayers插件iOS端播放本地音频报AVPlayerItem.Status.failed解决方法
问题表现
使用audioplayers插件播放本地已录制音频时,Android端功能正常,iOS端触发播放时输出以下错误日志,播放流程中断:
"iOS => call setVolume, playerId 57c0b5cc-3c75-4f8f-bf99-ad8ddbcb7709" "iOS => call setUrl, playerId 57c0b5cc-3c75-4f8f-bf99-ad8ddbcb7709" "" 2022-06-23 18:27:00.168194-0300 Runner[16264:695114] flutter: AVPlayerItem.Status.failed
对应功能实现代码:
await audioPlayer2.setVolume(1.0); await audioPlayer2.setUrl(filepath, isLocal: true); await audioPlayer2.play(filepath, isLocal: true); audioPlayer2.onPlayerStateChanged.listen((event) { setState(() { _isPlaying = false; }); });
排查解决步骤
- 校验本地文件路径有效性
iOS端对本地文件路径的识别规则和Android存在差异,若传入的是Android专属的沙盒路径、路径缺失file://协议头、路径指向的文件不存在(比如录制完成后文件未正确写入沙盒),都会直接导致AVPlayer加载资源失败。优先通过path_provider获取APP沙盒目录拼接文件路径,不要硬编码路径,可在setUrl前打印文件路径,通过File(filepath).existsSync()方法先校验文件是否真实存在。 - 补全iOS端必要权限配置
打开iOS项目下的ios/Runner/Info.plist文件,添加音频访问权限描述,否则系统会拦截AVPlayer的资源读取请求:
若音频文件存放在iCloud或APP沙盒外的目录,还需要补充添加文档读取权限。<key>NSAppleMusicUsageDescription</key> <string>用于播放已录制的音频内容</string> - 修正API调用逻辑
现有代码存在冗余调用问题:setUrl方法已经完成音频源的绑定,后续调用play时重复传入filepath和isLocal参数,会触发iOS端重复加载资源的逻辑,引发状态异常。调整调用逻辑如下:await audioPlayer2.setVolume(1.0); await audioPlayer2.setSourceDeviceFile(filepath); await audioPlayer2.resume(); audioPlayer2.onPlayerStateChanged.listen((event) { // 仅在播放完成、停止状态下更新播放标识,避免加载中状态误改 if (event == PlayerState.completed || event == PlayerState.stopped) { setState(() { _isPlaying = false; }); } }); - 校验音频编码兼容性
iOS端AVPlayer不支持部分Android端默认的音频编码格式(比如低版本AMR编码),如果录制音频时使用了非双端兼容的编码,会出现加载成功但解码失败的问题。录制音频时统一选择AAC编码,可保证双端正常解码播放。 - 清理构建缓存重新编译
所有配置和代码调整完成后,执行以下命令清理历史构建缓存,避免旧缓存导致配置不生效:flutter clean cd ios && pod deintegrate && pod install --repo-update flutter run
内容的提问来源于stack exchange,提问作者Wagner Tiburcio
相关产品推荐
相关产品推荐

