Ios AVCaptureSession将崩溃

Ios AVCaptureSession将崩溃,ios,swift,Ios,Swift,我正在使用该代码拍照,我能够尽快拍照。 快速拍摄多张照片应用程序将崩溃 我用的是Swift 1.1 错误: 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'+[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] -空样本缓冲区。' class ViewController: UIViewController { let captureSession = AVCapt

我正在使用该代码拍照,我能够尽快拍照。 快速拍摄多张照片应用程序将崩溃

我用的是Swift 1.1

错误:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'+[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] -空样本缓冲区。'

 class ViewController: UIViewController {
    let captureSession = AVCaptureSession()
    var previewLayer : AVCaptureVideoPreviewLayer?
    var captureDevice : AVCaptureDevice?
    var captureConnection: AVCaptureConnection?
    var stillImageOutput = AVCaptureStillImageOutput()
    let targetRegion = CALayer()
    var currentImage: UIImage?

    @IBOutlet weak var cameraView: UIImageView!
    @IBOutlet weak var imageDisplayed: UIImageView!


    override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.setNavigationBarHidden(true, animated: true)

        captureSession.sessionPreset = AVCaptureSessionPreset1920x1080
        let devices = AVCaptureDevice.devices()
        for device in devices {
            if device.hasMediaType(AVMediaTypeVideo) {
                if device.position == AVCaptureDevicePosition.Back {
                    captureDevice = device as? AVCaptureDevice
                }
            }
        }
        if captureDevice != nil {
            println("Device trovato")
            beginSession()
        }


    }


    func beginSession() {

        var err: NSError? = nil
        captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &err))

        if err != nil {
            println("err \(err?.localizedDescription)")
            return
        }

        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.view.layer.addSublayer(previewLayer)

        previewLayer?.frame = CGRect(x: cameraView.frame.origin.x, y: cameraView.frame.origin.y, width: cameraView.frame.size.width, height: cameraView.frame.size.height)

        captureSetup()
        captureSession.startRunning()
    }

    func captureSetup() {

        let outputSetting = NSDictionary(dictionary: [AVVideoCodecKey: AVVideoCodecJPEG])
        self.stillImageOutput.outputSettings = outputSetting
        self.captureSession.addOutput(stillImageOutput)
        for connection:AVCaptureConnection in self.stillImageOutput.connections as [AVCaptureConnection] {

            for port:AVCaptureInputPort in connection.inputPorts! as [AVCaptureInputPort] {
                if port.mediaType == AVMediaTypeVideo {
                    captureConnection = connection as AVCaptureConnection
                    break
                }
            }
            if captureConnection != nil {
                break
            }
        }
    }


    var i = 0;

    func captureScene() {


        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
            if self.captureConnection != nil {
                self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in

                    let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
                    var pickedImage: UIImage = UIImage(data:imageDataJpeg)!



                    if let data = UIImagePNGRepresentation(pickedImage) {


                        let filename = self.getDocumentsDirectory().stringByAppendingPathComponent("\(self.i).png")
                        data.writeToFile(filename, atomically: true)

                        self.i++
                    }


                })
            }
        })

    }



    func getDocumentsDirectory() -> NSString {
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        let documentsDirectory: AnyObject = paths[0]


        return documentsDirectory as NSString
    }




    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        captureScene()
    }

}

@alper在中解释的是,有时
imageSampleBuffer
可能为零,这就是崩溃的根源


我相信在Swift 2
imageSampleBuffer
中,缓冲区是可选的,所以为了避免这种崩溃,您可以检查nil。例如:

if imageSampleBuffer != nil {
    let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
    // ...
} else {
    // handle or ignore the error
}
但是您使用的是Swift 1,这是一个问题,因为在Swift 1
imageSampleBuffer
中,它被声明为隐式展开的可选项,这意味着它不能为零,也不能像前面的示例中那样进行检查

@alper给出的解决方案是使用

CMSampleBufferIsValid(imageSampleBuffer)
作为检查缓冲区是否有效的一种方法


如果前面的解决方案不起作用,您可以试试这个

当我看到函数签名时:

self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in
我看到缓冲区旁边有另一个参数,但您忽略了它:

(imageSampleBuffer:CMSampleBuffer!,389;)

我没有查找Swift 1文档,但如果
\uuuu
实际上是一个错误参数,我也不会感到惊讶。尝试将其替换为
错误
,如下所示:

self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error) -> Void in
或许

self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error:NSError) -> Void in
然后在继续执行
imageSampleBuffer
之前,检查
错误的内容

注意:正如我在最后一部分所说的,带有
错误的解决方案是一个猜测,我没有测试:你必须尝试、调整,看看我的想法是否正确。如果您能找到有关Swift 1的文档并明确地告诉我们,这将是非常理想的



可能重复的问题您能解释关于同一个问题的答案吗?非常简单:检查
imageSampleBuffer
是否为零,因为如果您快速拍摄几张照片,有时会为零我发现您的
captureStillImageAsynchronouslyFromConnection
签名有一个非可选的
imageSampleBuffer
。我相信这是Swift 1的问题,在Swift 2中它是可选的,您可以检查它是否为零。对于Swift 1,您应该查找此函数是否有可用的错误参数,并使用它。请重新编写作为答案,以便我可以提供完美的工作解决方案。回到过去,但为什么制作相机应用程序的方法如此缓慢?谢谢。不知道,我也有点惊讶,这个问题没有得到更明确的处理。检查这个解决方案,我不知道如何在swift中使用它@埃里克,我已经看过了,别担心不幸的是,我对另一个问题没有答案。