我正在开发一款相机应用程序,允许用户拍摄照片和视频(带声音)。在测试时,我意识到如果用户正在进行 FaceTime 通话并尝试使用摄像头,它就会停止工作。视频源被冻结并抛出如下运行时错误:
AVError(_nsError:错误域= AVFoundationErrorDomain代码= -11800“操作无法完成”UserInfo = {NSLocalizedFailureReason =发生未知错误(561017449),NSLocalizedDescription =操作无法完成,NSUnderlyingError = 0x300723240 {错误域= NSOSStatusErrorDomain Code=561017449“(null)”UserInfo={AVErrorFourCharCode='!pri'}}})
经过挖掘,我发现罪魁祸首正试图像这样激活我的
AVCaptureSession
上的麦克风:
if let audioDevice = AVCaptureDevice.default(for: .audio),
let audioDeviceInput = try? AVCaptureDeviceInput(device: audioDevice),
session.canAddInput(audioDeviceInput) {
session.addInput(audioDeviceInput)
}
更改似乎很简单:从
AVCaptureSession
设置逻辑中删除那段代码,然后将其移至用户尝试录制视频之前的右侧。问题是,如果我这样做,相机按预期工作,但用户点击按钮和视频开始录制之间存在显着的延迟,相机甚至会出现一秒钟的空白。如果麦克风设置代码在我设置 AVCaptureSession
时完成,则当用户点击录制按钮时不会有任何延迟。
我尝试在我用来处理所有相机逻辑的
DispatchQueue
内部(和外部)运行该代码,但没有任何改变。我还尝试将其添加到 session.beginConfiguration()
和 session.commitConfiguration()
之间,但它也没有改变任何事情。
我最终使用两个
AVCaptureSession
解决了这个问题。我的视频源始终运行,只有当用户点击录制按钮时,我才会启动音频源。
这样,录音是即时的,并且不录音时的麦克风问题就消失了,因为会话未运行,因此麦克风未处于活动状态。
作为奖励,现在我还可以在控件上运行触觉反馈,因为处理麦克风的
AVCaptureSession
没有运行!