joe*_*oey 7 core-image avfoundation ios swift
我已经看了很多这样的问题,并尝试了很多解决方案,但这种情况有点不同.我正在使用AVCaptureVideoDataOutputSampleBufferDelegate,以便我可以将CIFilters应用于实时视频源.我正在使用以下方法来更改相机:
func changeCameras() {
captureSession.stopRunning()
var desiredPosition: AVCaptureDevicePosition?
if front {
desiredPosition = AVCaptureDevicePosition.Back
} else {
desiredPosition = AVCaptureDevicePosition.Front
}
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as? [AVCaptureDevice]
for device in devices! {
if device.position == desiredPosition {
self.captureSession.beginConfiguration()
do {
let input = try AVCaptureDeviceInput(device: device)
for oldInput in self.captureSession.inputs {
print(oldInput)
self.captureSession.removeInput(oldInput as! AVCaptureInput)
}
print(input)
self.captureSession.addInput(input)
self.captureSession.commitConfiguration()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.captureSession.startRunning()
})
} catch { print("evic failed")}
}
}
front = !front
}
Run Code Online (Sandbox Code Playgroud)
我用来设置摄像头(在viewDidLoad中调用)并从委托接收sampleBuffer的方法在这里:https://gist.github.com/JoeyBodnar/17e22e3c04093caa54cf240ed8b1b601 .
一个问题是当按下按钮来更换相机时,在更换之前需要4-5秒的固定屏幕冻结.我已经尝试了上面的方法,以及创建一个单独的队列来运行整个函数,它仍然需要很长时间.我只是在使用常规AVVideoPreviewLayer切换相机时从未遇到过这个问题,所以我认为这可能部分是因为我使用的是样本缓冲区委托,但不能完全拼凑出如何/为什么.任何帮助表示赞赏.谢谢!
使用DispatchQueue.global().async以便 capturesession 设置在后台完成并且 ui 不会冻结
DispatchQueue.global().async {
self.captureSession.beginConfiguration()
// captureSession configurations here
// end with
self.captureSession.commitConfiguration()
DispatchQueue.main.async {
self.captureSession.startRunning()
}
}
Run Code Online (Sandbox Code Playgroud)
这对我有用
对于您的代码,它将像这样。
func changeCameras() {
captureSession.stopRunning()
var desiredPosition: AVCaptureDevicePosition?
if front {
desiredPosition = AVCaptureDevicePosition.Back
} else {
desiredPosition = AVCaptureDevicePosition.Front
}
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as? [AVCaptureDevice]
for device in devices! {
if device.position == desiredPosition {
DispatchQueue.global().async {
self.captureSession.beginConfiguration()
do {
let input = try AVCaptureDeviceInput(device: device)
for oldInput in self.captureSession.inputs {
print(oldInput)
self.captureSession.removeInput(oldInput as! AVCaptureInput)
}
print(input)
self.captureSession.addInput(input)
self.captureSession.commitConfiguration()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.captureSession.startRunning()
})
} catch { print("evic failed")}
}
}
}
front = !front
}
Run Code Online (Sandbox Code Playgroud)