Begin new captureSession without removing previewLayer

时间:2015-11-12 11:11:55

标签: ios swift avcapturesession

I'm creating a customView for the CameraView, which works fine however i'm now working on changing from the back camera to the front camera. i've at the moment done it by doing below. However this seem to create a bad user experience where it removes the previewLayer (the screen becomes white) and then show the front camera correctly. is there a way to create a better user experience by not making everything white in 1 sec before showing the new session?

switchCamera

func switchCamera() {
    if usingbackCamera == true {
        endSession()
        beginSession(frontCamera!)
        usingbackCamera = false
        self.cameraView.bringSubviewToFront(actionView)

    } else {
        endSession()
        beginSession(backCamera!)
        usingbackCamera = true
        self.cameraView.bringSubviewToFront(actionView)
    }
}

beginSession

func beginSession(device: AVCaptureDevice) {

    do {
        captureSession.addInput(try AVCaptureDeviceInput(device: device))
        self.previewLayer?.removeFromSuperlayer()
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

        self.cameraView.layer.addSublayer(previewLayer!)

        previewLayer?.frame = self.cameraView.bounds
        captureSession.startRunning()

        stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
        if captureSession.canAddOutput(stillImageOutput) {
            captureSession.addOutput(stillImageOutput)
        }
        if captureSession.canAddOutput(videoOutput) {
            captureSession.addOutput(videoOutput)
        }



    } catch let err as NSError {
        print(err)
    }

}

endSession

func endSession() {
    self.previewLayer?.removeFromSuperlayer()
    captureSession.stopRunning()
    captureSession = AVCaptureSession()

}

Take Picture

func takePicture() {


    if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo){
        videoConnection.videoOrientation = AVCaptureVideoOrientation.Portrait
        stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: {
            (sampleBuffer, error) in


                let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
                let dataProvider  = CGDataProviderCreateWithCFData(imageData)
                let cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider, nil, true, CGColorRenderingIntent.RenderingIntentDefault)

                let image = UIImage(CGImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.Right)

                self.previewImageView.image = image
                self.previewImageView.hidden = false
                self.cameraView.bringSubviewToFront(self.previewImageView)





        })
    }


}

2 个答案:

答案 0 :(得分:1)

我认为您在更改输入设备时不必删除预览图层。 该层与会话绑定,您只需停止会话,删除原始输入并添加新输入,然后再次启动会话。

我通过自定义渲染创建捕获视图,但我认为该过程将是相同的。

捕获代码段:

    for output in session.outputs {
        if let capture = output as? AVCaptureStillImageOutput{
            for connection in (capture.connections as! [AVCaptureConnection]){
                for port in (connection.inputPorts as! [AVCaptureInputPort]){
                    if port.mediaType == AVMediaTypeVideo{
                        capture.captureStillImageAsynchronouslyFromConnection(connection, completionHandler: {(buffer, err) -> Void in
                            if err != nil{
                                print(err)
                            }
                            let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer)
                            guard let image = CIImage(data: imageData) else{
                                completion(nil)
                                return
                            }
                            let rotatedImage = image.imageByApplyingTransform(CGAffineTransformMakeRotation(-CGFloat(M_PI_2)))
                        })
                    }
                }
            }
        }
    }

答案 1 :(得分:0)

当从后置摄像头切换到前置摄像头时,您不需要停止captureSession并再次启动它,反之亦然。

您需要做的就是删除旧的捕获会话输入,添加新的捕获会话输入以及开始/提交会话配置块之间的所有内容。

这是一个粗略的例子:

  func switchCamera() {
    //begin configuration changes
    captureSession.beginConfiguration()

    //remove the previous inputs
    let inputs = captureSession.inputs as! [AVCaptureInput]
    for oldInput:AVCaptureInput in inputs {
        captureSession.removeInput(oldInput)
    }

    //add the new input
    if usingbackCamera == true {
        addInput(frontCamera!)
        usingbackCamera = false
        self.cameraView.bringSubviewToFront(actionView)

    }
    else {
        addInput(backCamera!)
        usingbackCamera = true
        self.cameraView.bringSubviewToFront(actionView)
    }

    //end the configuration
    captureSession.commitConfiguration()
}


func addInput(device: AVCaptureDevice) {

    do {
        captureSession.addInput(try AVCaptureDeviceInput(device: device))

    } catch let err as NSError {
        print(err)
    }

}