AVFoundation:在 CanAddInput 处切换相机失败

AVFoundation: toggle camera fails at CanAddInput

我正在尝试使用 AVFoundation 添加旋转摄像头功能,以允许用户在前置摄像头和后置摄像头之间切换。

如下面的代码所示,我已经放入了一些 println() 语句,所有值看起来都是合法的,但是在测试 CanAddInput() 时代码总是掉落到失败的 else 子句。

我已经尝试将 sessionPreset(在另一个预先初始化会话的函数中)设置为各种值,包括 AVCaptureSessionPresetHighAVCaptureSessionPresetLow,但这没有帮助。

@IBAction func rotateCameraPressed(sender: AnyObject) {

    // Loop through all the capture devices to find right ones
    var backCameraDevice : AVCaptureDevice?
    var frontCameraDevice : AVCaptureDevice?
    let devices = AVCaptureDevice.devices()
    for device in devices {
        // Make sure this particular device supports video
        if (device.hasMediaType(AVMediaTypeVideo)) {
            // Define devices
            if (device.position == AVCaptureDevicePosition.Back) {
                backCameraDevice = device as? AVCaptureDevice
            } else if (device.position == AVCaptureDevicePosition.Front) {
                frontCameraDevice = device as? AVCaptureDevice
            }
        }
    }

    // Assign found devices to corresponding input
    var backInput : AVCaptureDeviceInput?
    var frontInput : AVCaptureDeviceInput?
    var error: NSError?
    if let backDevice = backCameraDevice {
        println("Back device is \(backDevice)")
        backInput = AVCaptureDeviceInput(device : backDevice, error: &error)
    }
    if let frontDevice = frontCameraDevice {
        println("Front device is \(frontDevice)")
        frontInput = AVCaptureDeviceInput(device : frontDevice, error: &error)
    }

    // Now rotate the camera
    isBackCamera = !isBackCamera  // toggle camera position
    if isBackCamera {
        // remove front and add back
        captureSession!.removeInput(frontInput)
        if let bi = backInput {
            println("Back input is \(bi)")
            if captureSession!.canAddInput(bi) {
                captureSession!.addInput(bi)
            } else {
                println("Cannot add back input!")
            }
        }
    } else {
        // remove back and add front
        captureSession!.removeInput(backInput)
        if let fi = frontInput {
            println("Front input is \(fi)")
            if captureSession!.canAddInput(fi) {
                captureSession!.addInput(fi)
            } else {
                println("Cannot add front input!")
            }
        }
    }
}

问题似乎是从迭代中找到的设备派生的输入实际上与 captureSession 变量中的输入不匹配。这似乎是一个新事物,因为我看到的所有关于此的代码都会通过遍历设备列表来找到并删除当前相机的输入,就像我在我的代码中所做的那样。

这似乎不再起作用了 - 好吧,至少在我发布的代码中不起作用,它基于我能够挖掘的所有来源(所有这些都恰好在 Objective C). canAddInput() 失败的原因是 removeInput() 永远不会成功;它没有发出关于无法拥有多个输入设备的常见错误这一事实很奇怪(因为它会有助于调试)。

无论如何,解决方法是不从找到的设备(曾经工作)中删除派生输入上的输入。相反,通过进入 captureSession.inputs 变量并对其执行 removeInput() 来删除实际存在的输入设备。

为了将所有这些喋喋不休的代码整理成代码,我是这样做的:

for ii in captureSession!.inputs {
  captureSession!.removeInput(ii as! AVCaptureInput)
}

成功了! :)