如何使AVCaptureSession和AVPlayer尊重AVAudioSessionCategoryAmbient? [英] How do I make AVCaptureSession and AVPlayer respect AVAudioSessionCategoryAmbient?

查看:82
本文介绍了如何使AVCaptureSession和AVPlayer尊重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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆