ios - AVAudioSession 类别变为 nil 并且 mediaServicesWereReset,avplayer 播放一直失败
问题描述
我们的团队有一个应用程序可以使用 avplayer 在线播放 m4a 资源。最近,有一些用户抱怨播放一直失败,我们不知道这背后的原因。
我们检查了用户日志和avplayer 错误日志如下(对于多个失败的实例):
- avPlayer.currentItem.error = 错误域=AVFoundationErrorDomain Code=-11800 "操作无法完成" UserInfo={NSLocalizedFailureReason=发生未知错误 (-16155),NSLocalizedDescription=操作无法完成,NSUnderlyingError=0x280e6ef10 {错误域=NSOSStatusErrorDomain 代码=-16155 "(null)"}}
- avPlayer.currentItem.error = 错误域=AVFoundationErrorDomain Code=-11800 "操作无法完成" UserInfo={NSLocalizedFailureReason=发生未知错误 (606068440), NSLocalizedDescription=操作无法完成, NSUnderlyingError=0x280e9f8d0 {错误域=NSOSStatusErrorDomain 代码=606068440 "(null)"}}
- avPlayer.currentItem.error = 错误域=AVFoundationErrorDomain Code=-11800 "操作无法完成" UserInfo={NSLocalizedFailureReason=发生未知错误 (1705376704),NSLocalizedDescription=操作无法完成,NSUnderlyingError=0x281ec60d0 {错误域=NSOSStatusErrorDomain 代码=1705376704 "(null)"}}
我们开始玩的正常流程:(按大多数用户的预期工作)
- [[AVAudioSession sharedInstance] setActive:YES error:&activationError];
- 调用 [avplayer 播放]
- 音频开始成功播放
失败场景:(对于某些用户,这种场景不断发生)
- 激活错误返回Error Domain=NSOSStatusErrorDomain Code=2003329396 "(null)"
- 我们记录了 [AVAudioSession sharedInstance].category 变为空
- 收到 mediaServicesWereReset 通知
- avplayer 无法播放,并观察到上述 avplayer 项目错误之一
当用户失败一次时,他无法在我们的应用程序中播放任何音频资源,并且场景不断重复。
我们想知道:
- 为什么这会发生在某些用户设备上?
- 如何防止问题发生?
- 有没有办法从丢失的 mediaService 中恢复?这样即使错误发生一次,用户仍然可以在我们的应用程序中播放其他资源。
即使我们尝试了开发者菜单中的重置媒体服务,我们也无法自己产生失败场景,行为并不完全相同。期待社区的任何帮助,谢谢。
解决方案
我不能肯定地回答你的前两个问题,但苹果对你最后一个问题的回答如下:
收到
AVAudioSessionMediaServicesWereResetNotification
通知后,申请应:
- 处置孤立的音频对象并创建新的音频对象
- 重置任何被跟踪的内部音频状态,包括 AVAudioSession 的所有属性
- 适当时,
AVAudioSession
使用该setActive:error:
方法重新激活
有关这方面的更多信息,请参阅https://developer.apple.com/library/archive/qa/qa1749/_index.html。
至于我对你前两个问题的猜测:
- 该问题可能不是特定于某些用户设备,而是可能有点随机。我在 Apple 中看到了一个类似的、非常罕见的问题,它提供了来自客户设备的崩溃日志,直到今天我才能重现。现在我终于能够通过简单地在自动测试中重复应用程序的正常操作数千次来重现该问题。在极少数情况下,iOS 会重置音频会话媒体服务,并导致会话激活或停用失败。在这种情况下,延迟一段时间后重新启动音频会话似乎可以解决问题。(不过我仍在测试,因为每次测试都需要几个小时才能重现问题)。
- 考虑到我在上面链接的 Apple 技术说明并没有提供任何可以避免重置音频会话媒体服务的迹象,我猜可能没有办法可靠地防止它发生。您激活/停用音频会话的频率越低(或次数越少),发生此问题的可能性就越小,但最终对于某些任意用户仍可能发生。这就是为什么正确的做法是假设这
AVAudioSessionMediaServicesWereResetNotification
有时是不可避免的,因此按照上面概述的方式处理它。
推荐阅读
- matlab - 将 64 个图形分解为一组子图
- ruby-on-rails - My nested cocoon form only accepts the last line of my dynamic table
- python - 如何使用字典使用询问的输入输出字典键
- java - BinaryTree 期望 Comparable,另一个实现 Comparable 的子类不起作用
- html - 如何在 HTML 中的 Node 中显示数组中的每个元素?
- typescript - 是否有一种类型级别的方法可以从类中提取具有默认值的属性?
- asp.net-core - 添加 ResponseCache 属性时记录缓存控制警告
- php - 如何绕过网站重定向屏幕?
- express - 在快速应用程序中使用压缩中间件不起作用
- r - 在 ggplot 中绘制具有聚集标准误差的回归的置信区间