Swift AVCaptureSession Close Open Button Error : Multiple audio/video AVCaptureInputs are not currently supported
Swift AVCaptureSession Close Open Button Error : Multiple audio/video AVCaptureInputs are not currently supported
我有一个可用的条形码扫描器代码。当我单击 openCamera
按钮时,第一次一切都很好。当我单击 closeCamera
按钮时,很好,但是如果我再次单击 openCamera
按钮会出现致命错误。代码和错误如下。事实上,是否可以一键切换相机视图?
// Barcode Camera Properties
let captureSession = AVCaptureSession()
var captureDevice:AVCaptureDevice?
var captureLayer:AVCaptureVideoPreviewLayer?
override func viewDidLoad() {
super.viewDidLoad()
self.cameraView.alpha = 0
}
@IBAction func closeCamera(sender: AnyObject) {
self.captureLayer!.hidden = true
self.captureSession.stopRunning()
}
@IBAction func openCamera(sender: AnyObject) {
self.cameraView.alpha = 1
self.cameraView.animate()
setupCaptureSession()
}
//MARK: Session Startup
private func setupCaptureSession(){
self.captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
do {
let deviceInput = try AVCaptureDeviceInput(device: captureDevice) as AVCaptureDeviceInput
//Add the input feed to the session and start it
self.captureSession.addInput(deviceInput)
self.setupPreviewLayer({
self.captureSession.startRunning()
self.addMetaDataCaptureOutToSession()
})
} catch let setupError as NSError {
self.showError(setupError.localizedDescription)
}
}
private func setupPreviewLayer(completion:() -> ()){
self.captureLayer = AVCaptureVideoPreviewLayer(session: captureSession) as AVCaptureVideoPreviewLayer
if let capLayer = self.captureLayer {
capLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
capLayer.frame = self.cameraView.frame
self.view.layer.addSublayer(capLayer)
completion()
} else {
self.showError("An error occured beginning video capture.")
}
}
//MARK: Metadata capture
func addMetaDataCaptureOutToSession() {
let metadata = AVCaptureMetadataOutput()
self.captureSession.addOutput(metadata)
metadata.metadataObjectTypes = metadata.availableMetadataObjectTypes
metadata.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
}
//MARK: Delegate Methods
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
for metaData in metadataObjects {
let decodedData:AVMetadataMachineReadableCodeObject = metaData as! AVMetadataMachineReadableCodeObject
self.pCodeTextField.text = decodedData.stringValue
//decodedData.type
}
}
//MARK: Utility Functions
func showError(error:String) {
let alertController = UIAlertController(title: "Error", message: error, preferredStyle: .Alert)
let dismiss:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler:{(alert:UIAlertAction) in
alertController.dismissViewControllerAnimated(true, completion: nil)
})
alertController.addAction(dismiss)
self.presentViewController(alertController, animated: true, completion: nil)
}
错误:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* Multiple audio/video AVCaptureInputs are not currently supported.'
*** First throw call stack:
(0x23f3410b 0x236dae17 0x2946bf73 0x2946b8bf 0x6d0d8 0x6ce28 0x6cebc 0x280a86cd 0x280a8659 0x2809064f 0x280a7fb5 0x28062275 0x280a0e21 0x280a05d3 0x280712f9 0x2806f98b 0x23ef768f 0x23ef727d 0x23ef55eb 0x23e48bf9 0x23e489e5 0x25094ac9 0x280d8ba1 0xa794c 0x23af7873)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
您的 setupCaptureSession()
方法 每次调用时都会添加 一个新输入(使用 self.captureSession.addInput(deviceInput)
)。
但错误消息明确指出"Multiple audio/video AVCaptureInputs are not currently supported"。
所以您一次只能使用一个输入:不要像您一样将它们堆叠在 self.captureSession 中。
例如,您可以在添加新的之前删除之前的(使用 removeInput
)。
要确保在添加新输入之前删除所有输入,您可以这样做:
if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
for input in inputs {
captureSession.removeInput(input)
}
}
就在 self.captureSession.addInput(deviceInput)
.
之前
如果它仍然不起作用...尝试不同的方法:不要删除输入,而是更改代码以便添加设备输入只需一次,而不是每次该方法称为:
if captureSession.inputs.isEmpty {
self.captureSession.addInput(deviceInput)
}
而不仅仅是 self.captureSession.addInput(deviceInput)
.
我刚刚在 Playground 上试过了,它成功了。既然你已经理解了 idea,你有责任通过调整我的解决方案使其在你自己的应用程序中工作,我不能为你做,即使我想.. .;)
我有一个可用的条形码扫描器代码。当我单击 openCamera
按钮时,第一次一切都很好。当我单击 closeCamera
按钮时,很好,但是如果我再次单击 openCamera
按钮会出现致命错误。代码和错误如下。事实上,是否可以一键切换相机视图?
// Barcode Camera Properties
let captureSession = AVCaptureSession()
var captureDevice:AVCaptureDevice?
var captureLayer:AVCaptureVideoPreviewLayer?
override func viewDidLoad() {
super.viewDidLoad()
self.cameraView.alpha = 0
}
@IBAction func closeCamera(sender: AnyObject) {
self.captureLayer!.hidden = true
self.captureSession.stopRunning()
}
@IBAction func openCamera(sender: AnyObject) {
self.cameraView.alpha = 1
self.cameraView.animate()
setupCaptureSession()
}
//MARK: Session Startup
private func setupCaptureSession(){
self.captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
do {
let deviceInput = try AVCaptureDeviceInput(device: captureDevice) as AVCaptureDeviceInput
//Add the input feed to the session and start it
self.captureSession.addInput(deviceInput)
self.setupPreviewLayer({
self.captureSession.startRunning()
self.addMetaDataCaptureOutToSession()
})
} catch let setupError as NSError {
self.showError(setupError.localizedDescription)
}
}
private func setupPreviewLayer(completion:() -> ()){
self.captureLayer = AVCaptureVideoPreviewLayer(session: captureSession) as AVCaptureVideoPreviewLayer
if let capLayer = self.captureLayer {
capLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
capLayer.frame = self.cameraView.frame
self.view.layer.addSublayer(capLayer)
completion()
} else {
self.showError("An error occured beginning video capture.")
}
}
//MARK: Metadata capture
func addMetaDataCaptureOutToSession() {
let metadata = AVCaptureMetadataOutput()
self.captureSession.addOutput(metadata)
metadata.metadataObjectTypes = metadata.availableMetadataObjectTypes
metadata.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
}
//MARK: Delegate Methods
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
for metaData in metadataObjects {
let decodedData:AVMetadataMachineReadableCodeObject = metaData as! AVMetadataMachineReadableCodeObject
self.pCodeTextField.text = decodedData.stringValue
//decodedData.type
}
}
//MARK: Utility Functions
func showError(error:String) {
let alertController = UIAlertController(title: "Error", message: error, preferredStyle: .Alert)
let dismiss:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler:{(alert:UIAlertAction) in
alertController.dismissViewControllerAnimated(true, completion: nil)
})
alertController.addAction(dismiss)
self.presentViewController(alertController, animated: true, completion: nil)
}
错误:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* Multiple audio/video AVCaptureInputs are not currently supported.'
*** First throw call stack: (0x23f3410b 0x236dae17 0x2946bf73 0x2946b8bf 0x6d0d8 0x6ce28 0x6cebc 0x280a86cd 0x280a8659 0x2809064f 0x280a7fb5 0x28062275 0x280a0e21 0x280a05d3 0x280712f9 0x2806f98b 0x23ef768f 0x23ef727d 0x23ef55eb 0x23e48bf9 0x23e489e5 0x25094ac9 0x280d8ba1 0xa794c 0x23af7873)
libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
您的 setupCaptureSession()
方法 每次调用时都会添加 一个新输入(使用 self.captureSession.addInput(deviceInput)
)。
但错误消息明确指出"Multiple audio/video AVCaptureInputs are not currently supported"。
所以您一次只能使用一个输入:不要像您一样将它们堆叠在 self.captureSession 中。
例如,您可以在添加新的之前删除之前的(使用 removeInput
)。
要确保在添加新输入之前删除所有输入,您可以这样做:
if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
for input in inputs {
captureSession.removeInput(input)
}
}
就在 self.captureSession.addInput(deviceInput)
.
如果它仍然不起作用...尝试不同的方法:不要删除输入,而是更改代码以便添加设备输入只需一次,而不是每次该方法称为:
if captureSession.inputs.isEmpty {
self.captureSession.addInput(deviceInput)
}
而不仅仅是 self.captureSession.addInput(deviceInput)
.
我刚刚在 Playground 上试过了,它成功了。既然你已经理解了 idea,你有责任通过调整我的解决方案使其在你自己的应用程序中工作,我不能为你做,即使我想.. .;)