首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVCaptureSession崩溃了

AVCaptureSession崩溃了
EN

Stack Overflow用户
提问于 2015-12-01 16:17:16
回答 1查看 2.6K关注 0票数 1

我用这个代码来拍照片,我不能尽快拍到照片。快速拍摄多张照片,应用程序就会崩溃。

我用的是Swift 1.1。

错误:

由于异常“NSInvalidArgumentException”终止应用程序,原因:‘+AVCaptureStillImageOutput:- NULL示例缓冲区。’

代码语言:javascript
复制
 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()
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-01 19:01:15

@alper在linked answer中解释的是,有时imageSampleBuffer可以是零,这就是崩溃的根源。

我相信在Swift 2中imageSampleBuffer是一个可选的,所以为了避免这种崩溃,您可以检查为零。示例:

代码语言:javascript
复制
if imageSampleBuffer != nil {
    let imageDataJpeg = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageSampleBuffer)
    // ...
} else {
    // handle or ignore the error
}

但是您使用的是Swift 1,这是一个问题,因为在Swift 1中,imageSampleBuffer被声明为一个隐式未包装的可选选项,这意味着它不能是零,并且不能像前面的示例那样检查。

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

代码语言:javascript
复制
CMSampleBufferIsValid(imageSampleBuffer)

作为检查缓冲区是否有效的方法。

如果前面的解决方案不起作用,您可以尝试这样做。

当我查看函数签名时:

代码语言:javascript
复制
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, _) -> Void in

我看到缓冲区旁边有另一个参数,但是您忽略了它:

(imageSampleBuffer:CMSampleBuffer!,_)

我没有查找Swift 1文档,但是如果_实际上是一个错误参数,我不会感到惊讶。尝试用error替换它,如下所示:

代码语言:javascript
复制
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error) -> Void in

或者也许

代码语言:javascript
复制
self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(self.captureConnection, completionHandler:{ (imageSampleBuffer:CMSampleBuffer!, error:NSError) -> Void in

然后在继续使用error之前检查imageSampleBuffer的内容。

注意:正如我最后说过的,使用error__的解决方案是猜测,我没有测试:您必须尝试,调整,看看我的想法是否正确。如果您能够找到Swift 1的文档,并明确地告诉我们有关它的情况,那将是非常理想的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34024942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档