如何让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
时它会暂停背景音频。