在前后摄像头之间切换 [英] Switch between front and back camera

查看:454
本文介绍了在前后摄像头之间切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个自定义的cameraView,到目前为止,它仍然有效.但是我在前置和后置摄像头之间切换时遇到了一个问题.我试图通过一个自定义枚举来处理它.但是,当调用switchCamera方法时.好像冻结了相机?怎么会这样?

I'm trying to make a custom cameraView, which works so far. However i've reached an issue with switching between front and back camera. I've tried to handle it through a custom enum. However when the switchCamera method is called. it just seem to freeze the camera? How come is that?

摄像机变量

var camera = CameraType.Back

viewDidLoad

    switchButton = UIButton(frame: CGRectMake(rightButtonXPoint, 35, 30, 30))
    switchButton.setImage(UIImage(named: "Switch"), forState: UIControlState.Normal)
    switchButton.addTarget(self, action: "switchCamera", forControlEvents: UIControlEvents.TouchUpInside)
    actionView.addSubview(switchButton)

ViewWillAppear

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    reloadCamera()


}

SwitchCamera

func switchCamera() {

    if camera == CameraType.Back {
        camera = CameraType.Front
    } else {
        camera = CameraType.Back
    }
    reloadCamera()
}

ReloadCamera

func reloadCamera() {

    captureSession = AVCaptureSession()


   // let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    var captureDevice:AVCaptureDevice! = nil
    if (camera == CameraType.Front) {
        let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)

        for device in videoDevices{
            let device = device as! AVCaptureDevice
            if device.position == AVCaptureDevicePosition.Front {
                captureDevice = device
                break
            }
        }
    } else {
        captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    }

    do {
        let input = try? AVCaptureDeviceInput(device: captureDevice)

        if (captureSession?.canAddInput(input) != nil){

            captureSession?.addInput(input)

            stillImageOutput = AVCaptureStillImageOutput()
            stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]

            if (captureSession?.canAddOutput(stillImageOutput) != nil){
                captureSession?.addOutput(stillImageOutput)

                previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

                previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
                previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
                cameraView.layer.addSublayer(previewLayer!)
                captureSession?.startRunning()

            }

            cameraView.bringSubviewToFront(actionView)
            previewImageView.bringSubviewToFront(actionView)
            self.previewImageView.hidden = true


        }
    }







}

推荐答案

不知道确切的细节,很难猜测,但是查看您的代码,我认为您遇到的问题是您试图在会话中添加多个摄像头(每次切换时,您实际上是在尝试添加新设备).

Without knowing the exact specifics, it's hard to guess, but looking at your code, I think the problem you're running into is that you're trying to add more than one camera to the session (each time you switch, you're actually trying to add a new device).

测试以查看捕获会话是否正在运行,如果正在运行,则在添加新设备之前先删除现有设备(后置/前置摄像头).确保将其包装为事务,如下所示:

Test to see if the capture session is running, then if it is, then REMOVE the existing device (back / front camera) before adding the new device. Make sure you wrap it as a transaction like so:

func beginSession(captureDevice : AVCaptureDevice?) {        

    if captureSession.running {
        captureSession.beginConfiguration()

        let currentInput : AVCaptureInput = captureSession.inputs[0] as! AVCaptureInput
        captureSession.removeInput(currentInput)

        do {
            try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
        } catch {
            print("Error adding video input device")
        }

        captureSession.commitConfiguration()

    } else {
        // Setup the camera and layer for the first time.
        do {
            try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
        } catch {
            print("Error adding video input device")
        }


        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.view.layer.insertSublayer(previewLayer!, atIndex: 0)
        previewLayer?.frame = self.view.layer.frame
        captureSession.startRunning()
    }
}

这是一个相当简单但实用的示例.我每次都通过捕获设备(根据需要使用前置/后置摄像头),并且在我的代码中它可以很好地工作.非常原型化的实现,但是希望它能为您提供缺少的步骤:

This is a fairly simple, but functional example. I just pass the capture device in each time (Front / Back camera as needed) and it works well enough in my code. Very prototype implementation, but hopefully this gives you the missing steps:

  1. .beginConfiguration()更改正在运行的会话之前.
  2. 删除现有设备,然后添加新设备.
  3. .commitConfiguration()使其全部正常工作.

由于预览层已经连接到currentSession,因此无需删除它.

No need to remove the preview layer as it's already hooked up to your currentSession anyway.

这篇关于在前后摄像头之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆