AVFoundation- 相机切换一次,且仅一次
AVFoundation- Camera Switches Once, And Only Once
我在 Whosebug 上找到了 this great thread here,并用它在 Swift 中编写了我的 switchCamera
函数。
我已经让它工作了,所以当我按下我的按钮时,摄像头会切换到后置摄像头。但是,一旦我再次按下它,它就不会切换回前置摄像头。我在不允许再次切换相机的代码中做错了什么?
一个额外的注意事项:当我翻译上面线程中提到的代码时,我无法在我的 cameraWithPosition()
中 return 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()
}
5 分钟后,我 post 解决了这个问题,哈哈。
我的问题是我没有将我的初始 captureDevice
设置为等于我称为 newCamera
的新创建的 AVCaptureDevice。
所以为了解决这个问题,我只是在 switchCamera()
结束时做了这个...
captureDevice! = newCamera!
您实现切换相机的方式很好,并且只有在您只有一个视频 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()
}
希望对您有所帮助。
谢谢
我在 Whosebug 上找到了 this great thread here,并用它在 Swift 中编写了我的 switchCamera
函数。
我已经让它工作了,所以当我按下我的按钮时,摄像头会切换到后置摄像头。但是,一旦我再次按下它,它就不会切换回前置摄像头。我在不允许再次切换相机的代码中做错了什么?
一个额外的注意事项:当我翻译上面线程中提到的代码时,我无法在我的 cameraWithPosition()
中 return 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()
}
5 分钟后,我 post 解决了这个问题,哈哈。
我的问题是我没有将我的初始 captureDevice
设置为等于我称为 newCamera
的新创建的 AVCaptureDevice。
所以为了解决这个问题,我只是在 switchCamera()
结束时做了这个...
captureDevice! = newCamera!
您实现切换相机的方式很好,并且只有在您只有一个视频 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()
}
希望对您有所帮助。 谢谢