如何使AVCaptureSession和AVPlayer尊重AVAudioSessionCategoryAmbient? [英] How do I make AVCaptureSession and AVPlayer respect AVAudioSessionCategoryAmbient?
问题描述
我正在制作一个录制(AVCaptureSession
)和播放(AVPlayerLayer
)视频的应用.我希望能够在不暂停其他应用程序的背景音频的情况下做到这一点,并且希望播放时尊重静音开关.
I'm making an app that records (AVCaptureSession
) and plays (AVPlayerLayer
) video. I'd like to be able to do this without pausing background audio from other apps and I'd like the playback to respect the mute switch.
在AppDelegate中,我已经设置了AVAudioSessionCategoryAmbient
,根据文档,这应该是:
In the AppDelegate I have set AVAudioSessionCategoryAmbient
, according to the docs this should:
其中声音播放不是主要内容的应用程序类别,也就是说,可以在关闭声音的情况下成功使用您的应用程序.
The category for an app in which sound playback is nonprimary—that is, your app can be used successfully with the sound turned off.
此类别也适用于伴奏"风格的应用程序,例如用户在播放音乐"应用程序时演奏的虚拟钢琴.使用此类别时,其他应用程序的音频会与您的音频混合在一起.屏幕锁定和静音开关(在iPhone上称为铃声/静音"开关)使您的音频静音.
This category is also appropriate for "play along" style apps, such as a virtual piano that a user plays while the Music app is playing. When you use this category, audio from other apps mixes with your audio. Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone).
这完美地描述了我正在寻找的行为.但这不起作用.
This perfectly describes the behavior I'm looking for. But it doesn't work.
我知道它已设置,因为如果我在任何视图控制器中尝试print(AVAudioSession.sharedInstance().category)
,它都会返回AVAudioSessionCategoryAmbient
.
I know it's set because if I try print(AVAudioSession.sharedInstance().category)
in any view controller it returns AVAudioSessionCategoryAmbient
.
有什么想法吗?我使用的是Swift,但即使是模糊的指导方向也可以使用.
Any ideas? I'm using Swift but even a vague direction to look in would be appreciated.
推荐答案
如何将背景音频与AVCapture会话混合:
如果您有麦克风输入,则默认情况下,AVCapture会话会将您的应用程序AVAudioSession设置为AVAudioSessionCategoryPlayAndRecord
.您必须告诉它不要:
How to Mix Background Audio With an AVCapture Session:
If you have a microphone input, an AVCapture session—by default—will set your apps AVAudioSession to AVAudioSessionCategoryPlayAndRecord
. You've got to tell it not to:
AVCaptureSession.automaticallyConfiguresApplicationAudioSession = false
但是,这样做只是冻结了应用程序.因为很遗憾,AVAudioSessionCategoryAmbient
不能与AVCaptureSession
一起使用.
Doing this, however, just froze the app. Because unfortunately, AVAudioSessionCategoryAmbient
just doesn't work with AVCaptureSession
.
解决方案是通过选项将您的应用AVAudioSession
设置为AVAudioSessionCategoryPlayAndRecord
:
The solution is to set your apps AVAudioSession
to AVAudioSessionCategoryPlayAndRecord
with options:
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
可以使蓝牙音频从耳机中发出,同时还可以启用蓝牙麦克风.不确定是否可以进一步完善,但它们似乎是所有相关选项.
.MixWithOthers
was kind of the most important one. That let the audio from other apps play. But it switched it to coming out of the earpiece which was super odd (I thought it was getting ducked at first). So .DefaultToSpeaker
moves it to the bottom speaker and .AllowBluetooth
lets you keep bluetooth audio coming out of headphones but also enables a bluetooth mic. Not sure if this can be refined anymore but they seemed like all the relevant options.
在录制过程中,您将AVAudioSession
设置为AVAudioSessionCategoryPlayAndRecord
,但这不考虑静音开关.
During recording, you set your AVAudioSession
to AVAudioSessionCategoryPlayAndRecord
, but that doesn't respect the mute switch.
因为有麦克风输入,您无法设置AVAudioSessionCategoryAmbient
.诀窍是从AVCaptureSession
移除麦克风,然后将AVAudioSession
设置为AVAudioSessionCategoryAmbient
:
Because you can't set AVAudioSessionCategoryAmbient
when there's a microphone input. The trick is to remove the mic from the AVCaptureSession
, then set the AVAudioSession
to 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
(再次设置选项,以便背景音频继续播放):
Once you have finished playback and need to go back to recording, you need to set AVAudioSessionCategoryPlayAndRecord
again (with options again so the background audio continues):
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
块中的第一行是让我困扰很长时间的事情.我不需要将音频会话设置为非活动状态即可切换到AVAudioSessionCategoryAmbient
,但是回到AVAudioSessionCategoryPlayAndRecord
时它正在暂停背景音频.
The first line in the do
block was the thing that had me caught up for a long time. I didn't need to set the audio session to inactive to switch to AVAudioSessionCategoryAmbient
but it was pausing background audio when coming back to AVAudioSessionCategoryPlayAndRecord
.
这篇关于如何使AVCaptureSession和AVPlayer尊重AVAudioSessionCategoryAmbient?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!