Ios 在前后摄像头之间切换

Ios 在前后摄像头之间切换,ios,swift,avcapturesession,Ios,Swift,Avcapturesession,我正在试着做一个定制的摄影师,到目前为止效果不错。然而,我遇到了一个在前后摄像头之间切换的问题。我试图通过自定义枚举来处理它。但是,当调用switchCamera方法时。只是好像把相机冻住了?怎么会这样 摄像机变量 var camera = CameraType.Back viewDidLoad switchButton = UIButton(frame: CGRectMake(rightButtonXPoint, 35, 30, 30)) switchButton.setIm

我正在试着做一个定制的摄影师,到目前为止效果不错。然而,我遇到了一个在前后摄像头之间切换的问题。我试图通过自定义枚举来处理它。但是,当调用
switchCamera
方法时。只是好像把相机冻住了?怎么会这样

摄像机变量

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)
视图将出现

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

    reloadCamera()


}
切换摄像头

func switchCamera() {

    if camera == CameraType.Back {
        camera = CameraType.Front
    } else {
        camera = CameraType.Back
    }
    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


        }
    }







}
重新加载摄像头

func switchCamera() {

    if camera == CameraType.Back {
        camera = CameraType.Front
    } else {
        camera = CameraType.Back
    }
    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


        }
    }







}

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

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

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()
    }
}
这是一个相当简单但功能强大的示例。每次我都会传递捕获设备(需要时可以通过前/后摄像头),它在我的代码中工作得很好。非常典型的实现,但希望这能为您提供缺少的步骤:

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

  • 无需删除预览层,因为它已连接到当前会话。

    我看不出您在哪里调用过
    switchCamera
    ,那么问题实际出现在哪里?你是不是在抓捕过程中就称之为SMAK?如果是这样,那就是你的问题;这是一个不连贯的操作。我在视图中添加了一个按钮,该按钮调用
    开关相机
    。我现在已经添加了代码,好吧,但正如我之前所说的,您不能随意删除正在运行的捕获会话,然后像那样替换它。您没有停止会话。您没有替换界面中的预览层。这是不连贯的好吧那我该怎么办?我什么时候能打电话给你?你需要停下来想想。如果已经有一个正在运行的会话,您需要停止它并按良好的顺序将其关闭,并且需要从接口中删除它的层。