AVFoundation - 相机切换一次,而且只有一次

Posted

技术标签:

【中文标题】AVFoundation - 相机切换一次,而且只有一次【英文标题】:AVFoundation- Camera Switches Once, And Only Once 【发布时间】:2015-05-09 15:44:43 【问题描述】:

我在 *** 上找到了 this great thread here,并用它在 Swift 中编写了我的 switchCamera 函数。

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

额外说明:当我翻译上面线程中提到的代码时,我无法在我的cameraWithPosition() 中返回nil。不确定这是否是导致我的问题的原因。

我的代码:

@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()

【问题讨论】:

【参考方案1】:

在我发布问题 5 分钟后,我想通了,哈哈。

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

所以为了解决这个问题,我只是在switchCamera()结尾处做了这个...

captureDevice! = newCamera!

【讨论】:

感谢您的回答!它节省了我的时间【参考方案2】:

您实现切换摄像头的方式还可以,并且仅在您只有一个视频 AVCaptureDevice 输入时才有效。想想有多个 AVCaptureDevice 输入(音频和视频)的情况。在这种情况下,您无法保证以下行 -:

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

在这种情况下,当您单击 toggleCamera 按钮时,它会崩溃并出现以下错误

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)

为了克服这个问题,我以不同的方式实现了它。所以我在 CameraController.swift 中的切换相机代码看起来像这样 -:

// 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
        ()

在我的视图控制器中:

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

希望对您有所帮助。 谢谢

【讨论】:

该代码也可以工作 Vivek!非常感谢你。我找到了我的解决方案,但我知道你的解决方案最适合未来需要帮助的任何人。 @justColbs 你能分享一下适合你的代码吗? @AnkitJain 我使用的代码在我原来的问题中,加上函数末尾的这行代码captureDevice! = newCamera! @justColbs 谢谢你的回答,它节省了我的时间

以上是关于AVFoundation - 相机切换一次,而且只有一次的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中使用 AVFoundation 切换相机后视频录制不起作用

切换到前置摄像头时 AVFoundation 摄像头崩溃(刷新摄像头)

用AVFoundation自定义相机拍照

AVFoundation的自定义相机

AVFoundation -> 用动画覆盖记录相机视频

IOS8:AVFoundation 相机冻结