AVCaptureSession addOutput 第二次需要很长时间运行
AVCaptureSession addOutput takes very long time second time running
在我的应用程序中,我有一个 QR 码扫描仪,它使用 AVFoundation
显示扫描预览并读取代码数据。由于某种原因,视图控制器(管理捕获会话)第二次将用于 QR 读取的 AVCaptureMetadataOutput
添加到 AVCaptureSession
需要 非常 的时间)出现。另一方面,它第一次出现时,视图控制器几乎可以在一秒钟内设置捕获会话、输入和输出。但是下一次,它在 AVCaptureSession
的 addOutput:
上停留了大约 15-20 秒,然后才最终 returns.
管理 QR 扫描会话的视图控制器如下所示:
init() {
session = AVCaptureSession()
}
func viewDidLoad() {
dispatch_async(dispatch_get_global_queue(0, 0), {
// Handle video input...
let videoDevice = /* get AVCaptureDevice */
self.videoDeviceInput = AVCaptureDeviceInput.deviceInputWithDevice(videoDevice, error: nil)
self.session.addInput(videoDeviceInput)
// Handle QR code output...
self.metadataOutput = AVCaptureMetadataOutput()
self.metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
self.session.addOutput(metadataOutput) /* takes 15 to 20 seconds after first time */
self.metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
})
}
func viewWillAppear(animated: Bool) {
dispatch_async(dispatch_get_global_queue(0, 0), {
self.session.startRunning()
})
}
func viewWillDisappear(animated: Bool) {
dispatch_async(dispatch_get_global_queue(0, 0), {
self.session.stopRunning()
})
}
所以容易发生的情况是,当视图控制器第二次出现时,视频预览立即出现,但在扫描相机指向的二维码之前需要 15 秒或更长时间(因为 addOutput:
花了这么长时间)。它发生在一个单独的线程上,因此至少用户界面保持响应,但是有什么方法可以修复 addOutput:
的长时间?第一次扫描后我没有正确清理吗?还有别的吗?
我不确定为什么,但看起来它花了这么长时间的原因是因为我正在使用 dispatch_get_global_queue(0, 0)
。相反,我创建了自己的队列:
let queue = dispatch_queue_create("com.myApp.avfoundation", nil)
并使用它而不是为 AVFoundation 的所有操作获取全局队列:
dispatch_async(queue, {
…
}
在我的应用程序中,我有一个 QR 码扫描仪,它使用 AVFoundation
显示扫描预览并读取代码数据。由于某种原因,视图控制器(管理捕获会话)第二次将用于 QR 读取的 AVCaptureMetadataOutput
添加到 AVCaptureSession
需要 非常 的时间)出现。另一方面,它第一次出现时,视图控制器几乎可以在一秒钟内设置捕获会话、输入和输出。但是下一次,它在 AVCaptureSession
的 addOutput:
上停留了大约 15-20 秒,然后才最终 returns.
管理 QR 扫描会话的视图控制器如下所示:
init() {
session = AVCaptureSession()
}
func viewDidLoad() {
dispatch_async(dispatch_get_global_queue(0, 0), {
// Handle video input...
let videoDevice = /* get AVCaptureDevice */
self.videoDeviceInput = AVCaptureDeviceInput.deviceInputWithDevice(videoDevice, error: nil)
self.session.addInput(videoDeviceInput)
// Handle QR code output...
self.metadataOutput = AVCaptureMetadataOutput()
self.metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
self.session.addOutput(metadataOutput) /* takes 15 to 20 seconds after first time */
self.metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
})
}
func viewWillAppear(animated: Bool) {
dispatch_async(dispatch_get_global_queue(0, 0), {
self.session.startRunning()
})
}
func viewWillDisappear(animated: Bool) {
dispatch_async(dispatch_get_global_queue(0, 0), {
self.session.stopRunning()
})
}
所以容易发生的情况是,当视图控制器第二次出现时,视频预览立即出现,但在扫描相机指向的二维码之前需要 15 秒或更长时间(因为 addOutput:
花了这么长时间)。它发生在一个单独的线程上,因此至少用户界面保持响应,但是有什么方法可以修复 addOutput:
的长时间?第一次扫描后我没有正确清理吗?还有别的吗?
我不确定为什么,但看起来它花了这么长时间的原因是因为我正在使用 dispatch_get_global_queue(0, 0)
。相反,我创建了自己的队列:
let queue = dispatch_queue_create("com.myApp.avfoundation", nil)
并使用它而不是为 AVFoundation 的所有操作获取全局队列:
dispatch_async(queue, {
…
}