我正在尝试使用AVFoundation
添加旋转相机功能,以允许用户在前置摄像头和后置摄像头之间切换。
如下面的代码所示,我添加了一些println()
语句,并且所有值看似合法,但在测试CanAddInput()
时,代码总是会丢失到失败的else子句。
我已经尝试将sessionPreset(在另一个预先初始化会话的函数中)设置为包括AVCaptureSessionPresetHigh
和AVCaptureSessionPresetLow
在内的各种值,但这没有帮助。
@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!")
}
}
}
}
答案 0 :(得分:6)
问题似乎是迭代中找到的设备的派生输入实际上与captureSession变量中的输入不匹配。这似乎是一个新事物,因为我所看到的所有代码都会通过遍历设备列表找到并删除当前相机的输入,就像我在我的代码中所做的那样。
这似乎不再起作用 - 好吧,至少在我发布的代码中没有,这是基于我能够挖掘的所有资源(所有这些都恰好在Objective中C)。 canAddInput()失败的原因是removeInput()永远不会成功;事实上,它没有发出关于无法拥有多个输入设备的常见错误,这一点很奇怪(因为它可以帮助调试)。
无论如何,修复方法是不从已找到的设备(过去的工作)中删除派生输入的输入。相反,通过进入captureSession.inputs变量并对其执行removeInput()来删除实际存在的输入设备。
要把所有那些唠叨的代码揉成代码,这就是我所做的:
for ii in captureSession!.inputs {
captureSession!.removeInput(ii as! AVCaptureInput)
}
这就是诀窍! :)