ios – 电话无法正常工作后恢复AVAudioPlayer

ios – 电话无法正常工作后恢复AVAudioPlayer,第1张

概述SO上已经有一些看似相似的问题,但经过几个小时的搜索和我的代码试验,我一直无法找到明确的答案.我能找到的最接近的东西是 this answer,它暗示了4年前的“已知错误”,但没有详细说明如何解决它. 我有一个audioPlayer类,它正在播放AVAudioPlayer的音频文件,并监听AVAudioSessionDelegate方法beginInterruption和endInterrupti SO上已经有一些看似相似的问题,但经过几个小时的搜索和我的代码试验,我一直无法找到明确的答案.我能找到的最接近的东西是 this answer,它暗示了4年前的“已知错误”,但没有详细说明如何解决它.

我有一个audioPlayer类,它正在播放AVAudioPlayer的音频文件,并监听AVAudioSessionDelegate方法beginInterruption和endInterruption.我知道endInterruption不能保证,所以我在beginInterruption中存储了一个布尔值,并处理了在applicationDIDBecomeActive中重新启动音频播放.

如果手机接到电话并且用户拒绝或让它转到语音邮件,这一切都可以正常运行.一旦我的应用程序返回活动状态,音频播放就会恢复.

在这里,我得到了奇怪的行为:如果用户接听电话,一旦他们挂机,一切似乎按预期工作,但通过耳机或扬声器没有声音.

我可以通过每秒打印音量和当前时间来验证音频是否在技术上播放,但声音没有出来.

如果我等待20-40秒,音频突然切入并变得可听见,好像它已经在后台默默播放.

经过更多调试后,我注意到AVAudioSession.sharedInstance().secondaryAudioShouldBeSilencedHint在这20-40秒的静音中保持为真,然后突然变为false并让音频播放.

我订阅了AVAudioSessionSilenceSecondaryAudioHintNotification以查看我是否可以检测到此更改,但它永远不会被调用,即使.secondaryAudioShouldBeSilencedHint从true更改为false.

我甚至尝试在恢复播放音频的方法中明确设置AVAudioSession.sharedInstance().setActive(true),但行为没有改变.

最后,我尝试设置一个计时器,在applicationDIDBecomeActive之后将恢复延迟10秒,但行为没有改变.

那么,为什么电话似乎没有放弃对我的应用程序的音频会话的控制?

谢谢参观!

码:

在init()中设置AVAudioSession:

NSNotificationCenter.defaultCenter().addobserver(self,selector: #selector(self.handleAudioHintChange),name: AVAudioSessionSilenceSecondaryAudioHintNotification,object: nil)NSNotificationCenter.defaultCenter().addobserver(self,selector: #selector(self.handleAudioInterruption),name: AVAudioSessionInterruptionNotification,object: nil)do {  try AVAudioSession.sharedInstance().setcategory(AVAudioSessioncategoryPlayback,withOptions: AVAudioSessioncategoryOptions.MixWithOthers)  print("AVAudioSession category Playback OK")  do {    try AVAudioSession.sharedInstance().setActive(true,withOptions: .NotifyOthersOnDeactivation)    print("AVAudioSession is Active")  } catch let error as NSError {    print(error.localizedDescription)  }} catch let error as NSError {  print(error.localizedDescription)}

通知处理程序:

///////////////////////////////////// This never gets called :( //////func handleAudioHintChange(notification: NSNotification) {  print("audio hint changed")}///////////////////////////////////func handleAudioInterruption(notification: NSNotification) {  if notification.name != AVAudioSessionInterruptionNotification || notification.userInfo == nil{    return  }  if let typeKey = notification.userInfo [AVAudioSessionInterruptionTypeKey] as? UInt,let type = AVAudioSessionInterruptionType(rawValue: typeKey) {    switch type {      case .Began:        print("Audio Interruption Began")        NSUserDefaults.standardUserDefaults().setBool(true,forKey:"wasInterrupted")      case .Ended:        print("Audio Interuption Ended")    }  }}

应用代表:

func applicationDIDBecomeActive(application: UIApplication) {  if(NSUserDefaults.standardUserDefaults().boolForKey("wasInterrupted")) {    audioPlayer.resumeAudioFromInterruption()  }}

重启功能:

// This works great if the phone call is declinedfunc resumeAudioFromInterruption() {  NSUserDefaults.standardUserDefaults().removeObjectForKey("wasInterrupted")  do {    try AVAudioSession.sharedInstance().setActive(true)    print("AVAudioSession is Active")  } catch let error as NSError {    print(error.localizedDescription)  }  thisFunctionPlaysMyAudio()

}

解决方法@H_502_62@ 虽然我没有在setActive方法中使用任何选项,但我试图这样做.

iOS 9.3.1中似乎存在一个错误,该错误在电话呼叫结束后无法恢复AVAudioPlayer的播放.

以下是为我解决的问题片段:(抱歉,Objective-C)

- (voID)handleInterruption:(NSNotification *) notification{    if (notification.name != AVAudioSessionInterruptionNotification || notification.userInfo == nil) {        return;    }    NSDictionary *info = notification.userInfo;    if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {        if ([[info valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {            NSLog(@"InterruptionTypeBegan");        } else {            NSLog(@"InterruptionTypeEnded");            //*The* Workaround - Add a small delay to the avplayer's play call; Without the delay,the playback will *not* be resumed            //            //(I dIDn't play much with the times,but 0.01 works with my iPhone 6S 9.3.1)            dispatch_after(dispatch_time(disPATCH_TIME_Now,0.01 * NSEC_PER_SEC),dispatch_get_main_queue(),^{                NSLog(@"playing");                [_player play];            });        }    }}

我在播放器的播放通话中添加了一个小延迟,并且它有效.

你可以在这里找到我完整的Demo项目:
https://github.com/liorazi/AVAudioSessionWorkaround

我向Apple提交了一个雷达,希望它能在下一个版本中得到修复.

总结

以上是内存溢出为你收集整理的ios – 电话无法正常工作后恢复AVAudioPlayer全部内容,希望文章能够帮你解决ios – 电话无法正常工作后恢复AVAudioPlayer所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1070705.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存