AVFoundation-相机切换一次,仅一次

时间:2015-05-09 15:44:44

标签: ios swift avcapturesession

我在StackOverflow上找到http://referencesource.microsoft.com并用它在Swift中编写我的switchCamera函数。

我已经工作了,所以当我按下按钮时,相机会切换到后置摄像头。但是,再次按下它后,它不会切换回前置摄像头。在我的代码中我做错了什么,不允许再次切换相机?

一个额外的注意事项:当我翻译上述主题中提到的代码时,我无法在nil中返回cameraWithPosition()。不确定这是否是导致我的问题的原因。

我的代码:

@IBAction func switchCamera(sender: UIButton) {
    let currentCameraInput: AVCaptureInput = session.inputs[0] as! AVCaptureInput
    session.removeInput(currentCameraInput)

    let newCamera: AVCaptureDevice?
    if(captureDevice!.position == AVCaptureDevicePosition.Back){
        println("Setting new camera with Front")
        newCamera = self.cameraWithPosition(AVCaptureDevicePosition.Front)
    } else {
        println("Setting new camera with Back")
        newCamera = self.cameraWithPosition(AVCaptureDevicePosition.Back)
    }

    let newVideoInput = AVCaptureDeviceInput(device: newCamera!, error: nil)
    if(newVideoInput != nil) {
        session.addInput(newVideoInput)
    } else {
        println("Error creating capture device input")
    }

    session.commitConfiguration()

}

func cameraWithPosition(position: AVCaptureDevicePosition) -> AVCaptureDevice {
    let devices = AVCaptureDevice.devices()
    for device in devices {
            if(device.position == position){
                return device as! AVCaptureDevice
            }
    }
    return AVCaptureDevice()
}

2 个答案:

答案 0 :(得分:2)

我发布问题后5分钟,我弄明白了,哈哈。

我的问题是我没有将我的初始captureDevice设置为新创建的AVCaptureDevice,我称之为newCamera

所以要解决这个问题,我只是在switchCamera() ...

结尾处这样做了
captureDevice! = newCamera!

答案 1 :(得分:2)

The way you implemented the toggle camera is just ok and only works if you have only one video AVCaptureDevice input. Think in the case of having multiple AVCaptureDevice inputs(audio and video). In that case you can't guarantee below line -:

 let currentCameraInput: AVCaptureInput = session.inputs[0] as! AVCaptureInput
 session.removeInput(currentCameraInput) 

In this case When you click on toggleCamera button , it crashes with below error

Couldn't add back facing video input
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** Multiple audio/video AVCaptureInputs are not currently supported.'
*** First throw call stack:
(0x38f2f2a3 0x3725997f 0x39aff977 0x39aff091 0xe943d 0xe7875 0x3a4de0a5 0x3a4de057 0x3a4de035 0x3a4dd8eb 0x3a4ddde1 0x3a4065f1 0x3a3f3801 0x3a3f311b 0x37cad5a3 0x37cad1d3 0x38f04173 0x38f04117 0x38f02f99 0x38e75ebd 0x38e75d49 0x37cac2eb 0x3a4472f9 0xdf1ab 0x36324b20)

To overcome this issue i have implemented it different way. So mine toggle camera code inside CameraController.swift looks like this -:

// toggleCamera basic purpose is to toggle the camera from front to back or vice versa as per user selection

func toggleCamera(){
        println("toggleCamera -----")
        var error:NSError?
        var backCameraDevice:AVCaptureDevice?
        var audio:AVCaptureDevice?
        var frontCameraDevice:AVCaptureDevice?
        var rearCamera: AVCaptureInput?
        var frontCamera: AVCaptureInput?
        for device in availableCameraDevices as! [AVCaptureDevice] {
           if device.position == .Back {
            self.backCameraDevice = device
           }
           else if device.position == .Front {
            self.frontCameraDevice = device
           }
        }

        if let validVideoFrontDevice = self.frontCameraDevice {
                self.frontCamera = AVCaptureDeviceInput.deviceInputWithDevice(validVideoFrontDevice, error: &error) as! AVCaptureDeviceInput
        }

        if let validVideoBackDevice = self.backCameraDevice {
                self.rearCamera = AVCaptureDeviceInput.deviceInputWithDevice(validVideoBackDevice, error: &error) as! AVCaptureDeviceInput
        }

        session.beginConfiguration()
        let inputs = session.inputs as! [AVCaptureInput]
        let newCamera: AVCaptureDevice?
        if(currentCameraDevice!.position == AVCaptureDevicePosition.Back){
            println("Setting new camera with Front")
            newCamera = self.frontCameraDevice
            if self.hasFrontCamera {
                if let validBackDevice = self.rearCamera {
                    if contains(inputs, validBackDevice) {
                        session.removeInput(validBackDevice)
                    }
                }
                if let validFrontDevice = self.frontCamera {
                    if !contains(inputs, validFrontDevice) {
                        session.addInput(validFrontDevice)
                    }
                }
            }
        } else {
            println("Setting new camera with Back")
            newCamera = self.backCameraDevice
            if let validFrontDevice = self.frontCamera {
                if contains(inputs, validFrontDevice) {
                    session.removeInput(validFrontDevice)
                }
            }
            if let validBackDevice = self.rearCamera {
                if !contains(inputs, validBackDevice) {
                    session.addInput(validBackDevice)
                }
            }
        }
        session.commitConfiguration()
        if let validError = error {
            println("Device setup error occured \(validError.localizedDescription)")
        }
        currentCameraDevice! = newCamera!
}

    /// The Bool property to determine if current device has front camera.

public var hasFrontCamera: Bool = {
        let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
        for  device in devices  {
            let captureDevice = device as! AVCaptureDevice
            if (captureDevice.position == .Front) {
                return true
            }
        }
        return false
        }()

In my view controller:

@IBAction func toggleCamera(sender: UIButton) {
    //  toggle the camera side
    println("toggling the camera side")
    self.cameraController.toggleCamera()
}

Hope it helps. Thanks