有没有办法在不中断UI的情况下实现avaudiosession .duckothers。 Swift 2.0

时间:2016-01-04 10:43:05

标签: ios swift avaudiosession

在使用以下代码播放avaudioplayer之前激活闪避。

do {

        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient,  withOptions: .DuckOthers)

    } catch let error as NSError {

        print(error.localizedDescription)

    }

    do {

        try AVAudioSession.sharedInstance().setActive(true)

    } catch let error as NSError {

        print(error.localizedDescription)

    }

我使用audioPlayerDidFinishPlaying来停止使用:

do {

        try AVAudioSession.sharedInstance().setActive(false)

    } catch let error as NSError {

        print(error.localizedDescription)

    }

正确激活和停用了Ducking,但是当激活闪避时,UI暂时停止,这是一个问题。

我一直在尝试使用dispatch_async异步实现ducking(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE,0)但是没有取得任何成功,即使在强制尝试时。尽管尝试使用异步线程,UI仍然会停止。

2 个答案:

答案 0 :(得分:1)

遇到同样的问题。使用Ducking,.setActive(true).setActive(false)的UI中断似乎是~500ms。 到目前为止,我发现的最佳解决方案是使用完成和通知将UI和.setActive()的更改完全分开。

我用这种方式解决了这个问题:

  • 对UI进行所有更改(在听到声音之前所有可能的更改仍然有意义)
  • 然后在完成这些更改后,执行.setActive(true)
  • 然后.play()
  • 然后在完成音频后,执行.setActive(false)
  • 然后恢复用户界面更改

这似乎会降低您的应用程序被“冻结”的感觉,因为您的用户正在“听到指令”,而不是文档似乎暗示的可视化。

  

.DuckOthers

     

如果您希望通过音乐或其他当前播放的音频听到应用中的音频(例如,导航应用中的语音提示),请使用此选项。请注意,激活应用程序的音频会话时会开始闪避,停用会话时会结束。

     

如果您的应用提供偶尔的语音音频,例如在转弯导航应用或练习应用中,您还应该使用AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers选项。

答案 1 :(得分:0)

我遇到了同样的问题。当AVAudioSession设置为非活动状态时,我的UI被阻止。释放会话时,会有一致的500毫秒暂停。

我通过将AVAudioSession设置为在单独的线程上停用来解决问题。 Blog post about the problem here

虽然我的代码是C#(使用Xamarin),但你可以在Obj-C或Swift中做同样的事情:

private void DeactivateAudioSession()
 {
  new System.Threading.Thread(new System.Threading.ThreadStart(() =>
  {
      var session = AVAudioSession.SharedInstance();
      session.SetActive(false);
  })).Start();
}