Ios Swift AVCAPTURE会话关闭打开按钮错误:当前不支持多个音频/视频AVCAPTURE输入

Ios Swift AVCAPTURE会话关闭打开按钮错误:当前不支持多个音频/视频AVCAPTURE输入,ios,swift,avfoundation,avcapturesession,Ios,Swift,Avfoundation,Avcapturesession,我有一个工作条形码扫描仪代码。当我单击openCamera按钮时,第一次一切正常。当我点击closeCamera按钮时,很好,但如果我再次点击openCamera按钮,则会出现致命错误。代码和错误如下。事实上,是否可以用一个按钮切换摄影机视图 // Barcode Camera Properties let captureSession = AVCaptureSession() var captureDevice:AVCaptureDevice? var captureLayer:AVCaptu

我有一个工作条形码扫描仪代码。当我单击
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)
}
错误:

*由于未捕获异常“NSInvalidArgumentException”而终止应用程序,原因:“*当前不支持多个音频/视频AVCaptureInputs。”

***第一次抛出调用堆栈: (0x23f3410b 0x236dae17 0x2946bf73 0x2946b8bf 0x6d0d8 0x6ce28 0x6cebc 0x280a8659 0x2809064f 0x280a7fb5 0x28062275 0x280a0e21 0x280a05d3 0x280712f9 0x2806f98b 0x23ef768f 0x23ef55eb 0x23e48bf9 0x23E489E489E5 0x25094ac9 0x280d8ba1 0xa794c 0x23af7873)

libc++abi.dylib:以NSException类型的未捕获异常终止 (lldb)


您的
setupCaptureSession()
方法每次调用时都会添加一个新输入(使用
self.captureSession.addInput(deviceInput)

但错误消息明确表示“当前不支持多个音频/视频AVCaptureInputs”

因此,您一次只能使用一个输入:不要像您那样将它们堆叠在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)


我只是在操场上试过,效果不错。既然您已经理解了这个想法,您有责任通过调整我的解决方案使其在您自己的应用程序中工作,我不能为您这样做,即使我想……;)

是的,我想是的,但我需要代码哪些代码需要?你已经知道如何添加输入,它在你的代码中:
self.captureSession.addInput(deviceInput)
。现在,您需要在添加新输入之前删除以前的输入,例如:
self.captureSession.removeInput(deviceInput)
。这就是它的全部,真的。:)现在,尝试一下自己,适应,努力理解正在发生的事情和我的建议。如果你卡住了,我会帮你的,别担心。我在self.captureSession.addInput(deviceInput)之前添加了self.captureSession.removeInput(deviceInput),并给出了相同的错误