在 endInterruption 调用了 AVAudioSessionDelegate,但未调用 beginInterruption

Posted

技术标签:

【中文标题】在 endInterruption 调用了 AVAudioSessionDelegate,但未调用 beginInterruption【英文标题】:AVAudioSessionDelegate called at endInterruption, but beginInterruption not called 【发布时间】:2012-07-26 19:42:06 【问题描述】:

我在应用启动时设置了一个 AVAudiosession 并将委托设置为 appDelegate。一切似乎都在工作(播放等),除了当电话接到电话时没有调用代表上的 beginInterruption 。当通话结束时 endInterruption 正在被调用。

我唯一的想法是我使用的音频播放器代码曾经基于 AVAudioPlayer,但现在使用的是 AVPlayer。用于处理中断的 AVAudioPlayer 委托的回调仍在其中,但它们会以任何方式发生冲突似乎很奇怪。

【问题讨论】:

我遇到了同样的情况,安德鲁,你能解决吗? 您在 iOS 5.x 中看到问题了吗? 我只在 iOS 6 中看到了同样的情况。刚刚升级了,还是不行。如果你解决了,请告诉我。 如我的回答中所述,这似乎已在 iOS 6.1 中修复。但是不是 6.0.1.. 我在 6.1.2 中仍然看到这个问题。当中断实际开始时,不会发布任何通知。当中断实际结束时, Began 和 Ended 通知都会发布。 【参考方案1】:

查看标题,在 iOS6 中,看起来 AVAudioSessionDelegate 现在已被弃用。

在 iOS6 中使用 AVAudioSessionInterruptionNotification

更新:那没有用。我认为框架中存在错误。

是的,根据我的经验,beginInterruption 和新记录的 AVAudioSessionInterruptionNotification 也不能正常工作。我必须做的是使用本地标志跟踪播放器的状态,然后处理endInterruption:withFlags: 方法以跟踪中断的恢复。

在 iOS 6 中,从中断中恢复至少会使您的 AudioPlayer 保持在正确的位置,因此我无需存储 AVAudioPlayer 的最后已知播放时间,我只需点击播放即可。

这是我想出的解决方案。如果 AVPlayer 驻留时间过长,iOS 6 似乎会通过 Media Reset 杀死您的音频。最终发生的是 AVPlayer 播放,但没有声音出来。 AVPlayer 上的速率为 1,但绝对没有声音。更糟糕的是,AVAudioSession setActive 和 AVPlayer 本身都没有错误表明存在问题。

加上你不能依赖 appWillResignActive 的事实,因为如果你完全依赖远程控制手势,你的应用可能已经在后台。

我实现的最终解决方案是在 AVPlayer 上添加一个周期性观察者,并记录最后一次已知时间。当我收到我已获得控制权的事件时,我创建一个新的 AVPlayer,使用 AVPlayerItem 加载它,然后 seekToTime 到适当的时间。

这是一个相当烦人的解决方法,但至少它有效,并且避免了正在发生的周期性崩溃。

【讨论】:

同意。 AVAudioSessionInterruptionNotification 和 AVAudioSessionRouteChangeNotification 似乎都不起作用!我已经向 Apple 提交了一个错误,并建议其他人也这样做,希望在 6.1 中修复此 API。 bugreport.apple.com/cgi-bin/WebObjects/RadarWeb.woa/wa/signIn【参考方案2】:

我可以确认使用C api,中断开始时也没有调用中断方法;只有当它结束时

(AudioSessionInitialize (nil, nil, interruptionListenerCallback, (__bridge void *)(self));

我还针对该问题向苹果提交了错误报告。

编辑:这已在 iOS 6.1(但不是 iOS 6.0.1)中修复

【讨论】:

不确定您的代码设置是否有问题,但我看到音频会话中断回调在 iOS 6 设备上开始中断时被调用。 有趣 - 我有 uploaded the example 发送给苹果 - 你可以试一试,看看 NSLog 是否被打印以通知中断的开始?想知道您是否以不同的方式设置音频会话? 我上面提到的项目在ios 6.1 beta上可以正常运行 当使用远程 io 使用 extAudioFile 直接录制到 AAC 时,我在 ios 6.0.1 和 6.1 beta 4 上都看到了这种行为。它似乎没有在 6.x 代码上得到修复全部【参考方案3】:

只要打电话:

[[AVAudioSession sharedInstance] setDelegate: self];

【讨论】:

那会触发beginInterruption?【参考方案4】:

我刚刚检查了我的 iPhone 5(运行 iOS 6.0),方法是在 AudioSessionInitialize() 中声明的 AudioSessionInterruptionListener 回调函数中设置断点,实际上,当应用程序有活动音频时,会调用此中断回调会话和音频单元,并被来电中断(Xcode 显示应用程序在中断开始时的断点处停止,然后我继续)。

我让应用程序停止其音频单元并停用其音频会话。然后,在结束中断回调时,应用程序重新激活音频会话并重新启动音频单元而没有问题(应用程序随后正常录制音频)。

【讨论】:

只有当我们直接编码为 mpeg4aac 时,我才会发现这个问题。任何其他编解码器和东西都可以正常工作。您使用的文件格式是什么?【参考方案5】:

我在 iOS 6.0.x 上构建了一个全新的音频流 (AVPlayer) 应用程序,发现了同样的问题。

现在已弃用代表,我们必须使用通知,这很好,但这是我的发现:

    在来电期间,我的处理程序中只得到AVAudioSessionInterruptionTypeEnded,以及AVAudioSessionInterruptionOptionShouldResume。音频会话自动暂停(音频淡出),我只需要继续播放 AVPlayer。 但是,当我尝试启动游戏(例如 CSR Racing)时,我奇怪地收到了可怕的 AVAudioSessionInterruptionTypeBegan,但没有任何迹象表明我的应用程序可以恢复播放,甚至没有终止游戏。

现在,这可能取决于其他因素,例如我的音频类别(在我的情况下为 AVAudioSessionCategoryPlayback)和两个应用程序的混合设置(kAudioSessionProperty_OverrideCategoryMixWithOthers),我不确定,但肯定我看到了一些东西地点。

希望其他人报告说,在 6.1beta 上,此问题已修复,但我还需要升级,所以我们拭目以待。

【讨论】:

以上是关于在 endInterruption 调用了 AVAudioSessionDelegate,但未调用 beginInterruption的主要内容,如果未能解决你的问题,请参考以下文章

关于j使用ava匿名类的好处总结

ava堆栈

ava集合---HashSet的源码分析

[ 原创 ]AVA反射机制主要提供了以下哪些功能?

如果已经在 J​​ava 中打开,如何关闭程序

已经在 J​​ava 类中管理 ID 为 0 的 GoogleApiClient