在解雇后无法重新启动捕获会话

时间:2016-01-13 15:02:39

标签: ios swift avcapturesession

我有一个启动AVCaptureSession来扫描条形码的按钮。除非您取消会话或扫描条形码并决定扫描另一个条形码,否则一切正常。为了再次启动它,视图控制器必须被解除然后再次呈现。

尝试再次启动会话时的错误在setUpCaptureSession()

let captureSession = AVCaptureSession()
var captureDevice: AVCaptureDevice?
var captureLayer: AVCaptureVideoPreviewLayer?

以下是相关方法。

@IBAction func scanBarcode(sender: AnyObject) {
        self.setupCaptureSession()
    }

func cancel() {
        NSNotificationCenter.defaultCenter().postNotificationName("backPressed", object: nil, userInfo: nil)
        self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
    }

func cancelBarcodeScan() {
        self.captureSession.stopRunning()
        self.captureLayer?.removeFromSuperlayer()
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "done")
        self.navigationItem.leftBarButtonItem?.action = "cancel"
    }

private func setupPreviewLayer(completion:() -> ()) {
        self.captureLayer = AVCaptureVideoPreviewLayer(session: captureSession)

        if let capLayer = self.captureLayer {
            capLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
            capLayer.frame = self.view.frame
            self.view.layer.addSublayer(capLayer)
            self.navigationItem.rightBarButtonItem = nil
            self.navigationItem.leftBarButtonItem?.action = "cancelBarcodeScan"
            completion()
        } else {
            self.showError("An error occured beginning video capture.")
        }
    }

    private func addMetaDataCaptureOutToSession() {
        let metaData = AVCaptureMetadataOutput()
        self.captureSession.addOutput(metaData)
        // metaData.metadataObjectTypes = metaData.availableMetadataObjectTypes
        metaData.metadataObjectTypes = [AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypePDF417Code,
            AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode]
        metaData.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
    }

    private func setupCaptureSession() {
        self.captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        let deviceInput: AVCaptureDeviceInput
        do {
            deviceInput = try AVCaptureDeviceInput(device: captureDevice)
        } catch {
            return
        }

        if (captureSession.canAddInput(deviceInput)) {
            // Show live feed
            captureSession.addInput(deviceInput)
            self.setupPreviewLayer({
                self.captureSession.startRunning()
                self.addMetaDataCaptureOutToSession()
            })
        } else {
            self.showError("Error while setting up input captureSession.")
        }
    }

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        for metaData in metadataObjects {
            let decodedData: AVMetadataMachineReadableCodeObject = metaData as! AVMetadataMachineReadableCodeObject
            upcTextField.text = decodedData.stringValue
            itemNameTextField.text = decodedData.type
            getProductData(decodedData.stringValue)
            self.captureSession.stopRunning()
            self.captureLayer?.removeFromSuperlayer()
            self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "done")
            self.navigationItem.leftBarButtonItem?.action = "cancel"
        }
    }

    private func showError(error:String)
    {
        let alertController = UIAlertController(title: "Error", message: error, preferredStyle: .Alert)
        let dismiss:UIAlertAction = UIAlertAction(title: "Ok", style: .Default, handler:{(alert:UIAlertAction!) in
            alertController.dismissViewControllerAnimated(true, completion: nil)
        })
        alertController.addAction(dismiss)
        self.presentViewController(alertController, animated: true, completion: nil)
    }

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,这就是我解决它的方法,我只是添加了一个 captureSession.stopRunning() captueSession.StartRunning()

 if metadataObj.stringValue != nil {
//                messageLabel.text = metadataObj.stringValue
                let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

                if supportedCodeTypes.contains(metadataObj.type) {
                    // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
                    let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj)
                    qrCodeFrameView?.frame = barCodeObject!.bounds

                    guard let url = URL(string: metadataObj.stringValue!) else {
                            return
                            }
                        if #available(iOS 10.0, *) {
                            performSegue(withIdentifier: "segue", sender: nil)
                            captureSession.stopRunning()
                            captureSession.startRunning()