iOS 相机:`AVCaptureAudioDataOutput` 即时激活音频会话,避免背景音乐卡顿 [英] iOS Camera: `AVCaptureAudioDataOutput` activate audio session on the fly, avoid background music stutter
问题描述
我使用 AVFoundation 创建了一个相机,它能够使用 AVCaptureVideoDataOutput
和 AVCaptureAudioDataOutput
录制视频和音频.我创建我的捕获会话,连接所有输入以及视频和音频数据输出,然后相机处于空闲状态.用户现在可以开始视频录制了.
I have created a Camera using AVFoundation which is able to record video and audio using AVCaptureVideoDataOutput
and AVCaptureAudioDataOutput
. I create my capture session, attach all inputs and the video- and audio-data outputs, and the Camera then sits idle. The user is now able to start a video recording.
问题在于,在我开始捕获会话 (captureSession.startRunning()
) 后,背景音乐立即断断续续.我认为这是因为一旦捕获会话开始运行,AVCaptureAudioDataOutput
在内部激活 AVAudioSession (AVAudioSession.setActive(...)
),我不希望它这样做.我希望它处于空闲状态(并且不提供任何音频输出缓冲区),直到我明确激活音频会话(一旦用户开始录制).
The problem with this is that immediately after I start the capture session (captureSession.startRunning()
), the background music stutters. I assume this is because once the capture session starts running, the AVCaptureAudioDataOutput
internally activates the AVAudioSession (AVAudioSession.setActive(...)
), which I don't want it doing. I want it sitting idle (and not providing any audio output buffers) until I explicitly activate the Audio Session (once the user starts recording).
这真的很烦人,因为相机是我们应用程序的开始屏幕,每次用户打开或关闭应用程序时,他的音乐都会断断续续.
This is really annoying, since the Camera is the start-screen in our app and everytime the user opens or closes the app his music stutters.
我知道这在某种程度上是可能的,因为 Snapchat 就是这样工作的——你打开应用程序,背景音频继续流畅地播放.开始录制后,背景音乐会出现轻微的卡顿,但相机会顺利运行并在短暂的卡顿结束后开始录制.
I know that this is somehow possible because Snapchat works that way - you open the App and background audio smoothly continues to play. Once you start recording, there is a small stutter on the background music, but the Camera smoothly operates and starts recording once the short stutter is over.
我的代码:
func configureSession() {
captureSession.beginConfiguration()
// Video, Photo and Audio Inputs
...
// Video Output
...
// Audio Output
audioOutput = AVCaptureAudioDataOutput()
guard captureSession.canAddOutput(audioOutput!) else {
throw CameraError.parameter(.unsupportedOutput(outputDescriptor: "audio-output"))
}
audioOutput!.setSampleBufferDelegate(self, queue: audioQueue)
captureSession.addOutput(audioOutput!)
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord,
options: [.mixWithOthers,
.allowBluetoothA2DP,
.defaultToSpeaker,
.allowAirPlay])
captureSession.commitConfiguration()
}
我尝试了什么
延迟配置AVAudioSession.sharedInstance()
我尝试首先使用类别AVAudioSession.Category.playback
配置AVAudioSession.sharedInstance
,并在需要时切换到.playAndRecord
开始录制音频.
What I tried
Delay configuring the AVAudioSession.sharedInstance()
I tried to first configure the AVAudioSession.sharedInstance
with the category AVAudioSession.Category.playback
, and switch to .playAndRecord
once I want to start recording audio.
这不起作用,AVCaptureSessionRuntimeError
事件在启动相机后立即被调用,错误代码为 -10851
,这意味着 kAudioUnitErr_InvalidPropertyValue
.我认为这意味着 AVCaptureAudioDataOutput
不允许从音频会话中录制,但我现在不想这样做 - 它应该只是空闲.
This didn't work and the AVCaptureSessionRuntimeError
event gets invoked immediately after starting the Camera with the Error code -10851
, which means kAudioUnitErr_InvalidPropertyValue
. I think this means that the AVCaptureAudioDataOutput
is not allowed to record from the Audio Session, but I don't event want to do that right now - it should just be idle.
我尝试在开始时不添加音频输出 (AVCaptureAudioDataOutput
),而仅按需"添加它一旦用户开始录制,虽然这对背景音乐效果很好(开始时没有口吃,用户开始录制后只有短暂的口吃,正是我想要的),它使预览冻结了很短的时间(因为捕获会话正在通过 beginConfiguration
+ 添加音频输出 + commitConfiguration
)
I tried to not add the audio output (AVCaptureAudioDataOutput
) in the beginning, and only add it "on-demand" once the user starts recording, and while that worked fine for the background music (no stutter when starting, only short stutter once the user starts recording, exactly how I want it), it made the Preview freeze for a short amount of time (because the Capture Session is being reconfigured via beginConfiguration
+ audio output adding + commitConfiguration
)
有谁知道如何实现我在这里想要做的事情 - 或者 Snapchat 是如何做到的?感谢任何帮助,谢谢!
Does anyone know how it's possible to achieve what I'm trying to do here - or how Snapchat does it? Any help appreciated, thanks!
推荐答案
终于想通了.我只是创建了一个单独的 AVCaptureSession
,专门用于与主捕获会话的 masterClock
同步的音频输入/输出.然后我可以即时启动/停止辅助捕获会话(在开始录制前不久)
Finally figured it out. I simply created a separate AVCaptureSession
specifically for the audio input/output which I synchronize with the main capture session's masterClock
. I can then start/stop the secondary capture session on the fly (shortly before start recording)
这篇关于iOS 相机:`AVCaptureAudioDataOutput` 即时激活音频会话,避免背景音乐卡顿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!