如何让AVCaptureSession和AVPlayer尊重AVAudioSessionCategoryAmbient?

我正在创建一个记录( AVCaptureSession )和播放( AVPlayerLayer )video的应用程序。 我希望能够在不暂停其他应用程序的背景音频的情况下执行此操作,并且我希望播放能够尊重静音开关。

在AppDelegate中我设置了AVAudioSessionCategoryAmbient ,根据文档应该:

应用程序的类别,其中声音播放是非主要的 – 也就是说,您的应用程序可以在声音关闭时成功使用。

此类别也适用于“播放”风格的应用程序,例如用户在播放音乐应用程序时播放的虚拟钢琴。 使用此类别时,来自其他应用程序的音频会与您的音频混合。 屏幕锁定和静音开关(在iPhone上称为Ring / Silent开关)可以使您的音频静音。

这完美地描述了我正在寻找的行为。 但它不起作用。

我知道它已设置,因为如果我在任何视图控制器中尝试print(AVAudioSession.sharedInstance().category) ,它将返回AVAudioSessionCategoryAmbient

有任何想法吗? 我正在使用Swift,但即使是一个模糊的方向,也会受到赞赏。

如何将背景音频与AVCapture会话混合:

如果您有麦克风输入,默认情况下AVCapture会话会将您的应用AVAudioSession设置为AVAudioSessionCategoryPlayAndRecord 。 你必须告诉它不要:

 AVCaptureSession.automaticallyConfiguresApplicationAudioSession = false 

但是,这样做只会冻结应用程序。 因为不幸的是, AVAudioSessionCategoryAmbient只适用于AVCaptureSession

解决方案是使用选项将您的应用AVAudioSession设置为AVAudioSessionCategoryPlayAndRecord

 do { try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: [.MixWithOthers, .AllowBluetooth, .DefaultToSpeaker]) try AVAudioSession.sharedInstance().setActive(true) } catch let error as NSError { print(error) } 

.MixWithOthers是最重要的一种。 这让其他应用的音频播放。 但是它把它转换成了超级奇怪的耳机(我以为它最初被躲了起来)。 所以.DefaultToSpeaker将它移动到底部扬声器和.AllowBluetooth让你可以保持耳机的蓝牙音频,但也可以启用蓝牙麦克风。 不确定这是否可以改进,但它们似乎是所有相关选项。

如何在播放中尊重静音开关:

在录制过程中,您将AVAudioSession设置为AVAudioSessionCategoryPlayAndRecord ,但这不符合静音开关。

因为在有麦克风输入时无法设置AVAudioSessionCategoryAmbient 。 诀窍是从AVCaptureSession删除麦克风,然后将AVAudioSession设置为AVAudioSessionCategoryAmbient

 do { captureSession.removeInput(micInput) try AVAudioSession.sharedInstance().setActive(false) try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient) try AVAudioSession.sharedInstance().setActive(true) } catch let error as NSError { print(error) } 

完成播放并需要返回录制后,需要再次设置AVAudioSessionCategoryPlayAndRecord (再次使用选项,以便后台音频继续):

 do { try AVAudioSession.sharedInstance().setActive(false) try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: [.MixWithOthers, .AllowBluetooth, .DefaultToSpeaker]) try AVAudioSession.sharedInstance().setActive(true) } catch let error as NSError { print(error) } captureSession.automaticallyConfiguresApplicationAudioSession = false captureSession.addInput(micInput!) 

do block中的第一行是让我长时间陷入困境的事情。 我不需要将音频会话设置为非活动状态以切换到AVAudioSessionCategoryAmbient但在返回到AVAudioSessionCategoryPlayAndRecord时它会暂停背景音频。