如何让AVCaptureSession和AVPlayer尊重AVAudioSessionCategoryAmbient?

And*_*lor 3 avfoundation ios avaudiosession avplayer swift

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

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

声音播放非主要应用的类别 - 也就是说,您的应用可以在声音关闭时成功使用.

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

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

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

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

And*_*lor 7

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

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

AVCaptureSession.automaticallyConfiguresApplicationAudioSession = false
Run Code Online (Sandbox Code Playgroud)

但是,这样做只会冻结应用程序.因为不幸的是,AVAudioSessionCategoryAmbient只是不起作用AVCaptureSession.

解决方案是将应用程序设置AVAudioSessionAVAudioSessionCategoryPlayAndRecord 选项:

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: [.MixWithOthers, .AllowBluetooth, .DefaultToSpeaker])
    try AVAudioSession.sharedInstance().setActive(true)

} catch let error as NSError {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

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

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

在录制过程中,您将设置AVAudioSessionAVAudioSessionCategoryPlayAndRecord,但这不符合静音开关.

因为AVAudioSessionCategoryAmbient当麦克风输入时你无法设置.诀窍是从中删除麦克风AVCaptureSession,然后设置AVAudioSessionAVAudioSessionCategoryAmbient:

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) }
Run Code Online (Sandbox Code Playgroud)

完成播放并需要返回录制后,需要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!)
Run Code Online (Sandbox Code Playgroud)

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

  • 当我使用此代码时,它会冻结 AVCaptureSession 大约 1-2 秒。有什么解决方法吗? (2认同)