BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.23k stars 4.61k forks source link

Crashed because `GPUImageVideoCamera(sessionPreset: cameraPosition:)` return nil #2445

Closed iTofu closed 7 years ago

iTofu commented 7 years ago

ENV:

Code:

var videoCamera: GPUImageVideoCamera!
var filter: GPUImageOutput!
var filterView: GPUImageView!

func setupPreview() {
    DispatchQueue.global(qos: .background).async {

        self.videoCamera = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPreset1280x720, cameraPosition: .front).then({
            $0.horizontallyMirrorFrontFacingCamera = true
            $0.outputImageOrientation = UIApplication.shared.statusBarOrientation
            $0.addAudioInputsAndOutputs()
        })

        self.resetFilter(withType: self.filterType)

        self.filterView = GPUImageView().then({
            $0.fillMode = kGPUImageFillModePreserveAspectRatioAndFill
        })

        self.recordView?.addSubview(self.filterView)
        self.filterView.snp.makeConstraints({ (make) in
            make.edges.equalToSuperview()
        })

        self.videoCamera.addTarget(self.filter as! GPUImageInput!)
        self.filter.addTarget(self.filterView)

        self.videoCamera.startCapture()

        self.recordView?.alpha = 0
        UIView.animate(withDuration: 0.5, animations: { [weak self] in
            self?.recordView?.alpha = 1.0
        })
    }
}

And I got this error message:

fatal error: unexpectedly found nil while unwrapping an Optional value

Crash Info:

d7b11fd7-5e6a-401c-a32f-b1e134c8928b

iTofu commented 7 years ago

I may found the reason, it was my fault. It may because queue's qos was too low: .global(qos: .background), it works well with this qos:

DispatchQueue.global().async {
}

And operation that update UI should be in main queue, so all code should like this:

var videoCamera: GPUImageVideoCamera!
var filter: GPUImageOutput!
var filterView: GPUImageView!

func setupPreview() {
    DispatchQueue.global().async {
        self.videoCamera = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPreset1280x720, cameraPosition: .front)
        self.videoCamera.do({
            $0.horizontallyMirrorFrontFacingCamera = true
            $0.outputImageOrientation = UIApplication.shared.statusBarOrientation
            $0.addAudioInputsAndOutputs()
        })

        self.resetFilter(withType: self.filterType)

        self.filterView = GPUImageView().then({
            $0.fillMode = kGPUImageFillModePreserveAspectRatioAndFill
        })

        DispatchQueue.main.async {
            self.recordView?.addSubview(self.filterView)
            self.filterView.snp.makeConstraints({ (make) in
                make.edges.equalToSuperview()
            })

            self.recordView?.alpha = 0
            UIView.animate(withDuration: 0.5, animations: { [weak self] in
                self?.recordView?.alpha = 1.0
            })
        }

        self.videoCamera.addTarget(self.filter as! GPUImageInput!)
        self.filter.addTarget(self.filterView)

        self.videoCamera.startCapture()
    }
}
iTofu commented 7 years ago

And thanks for GPUImage's author @BradLarson , I like this repo :)