在 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的主要内容,如果未能解决你的问题,请参考以下文章