我正在尝试制作一个自定义的 cameraView,到目前为止它可以正常工作。但是我遇到了在前后摄像头之间切换的问题。我试图通过自定义枚举来处理它。但是当 switchCamera
方法被调用时。它似乎只是卡住了相机?怎么会这样?
相机变量
var camera = CameraType.Back
viewDidLoad
switchButton = UIButton(frame: CGRectMake(rightButtonXPoint, 35, 30, 30))
switchButton.setImage(UIImage(named: "Switch"), forState: UIControlState.Normal)
switchButton.addTarget(self, action: "switchCamera", forControlEvents: UIControlEvents.TouchUpInside)
actionView.addSubview(switchButton)
ViewWillAppear
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
reloadCamera()
}
切换相机
func switchCamera() {
if camera == CameraType.Back {
camera = CameraType.Front
} else {
camera = CameraType.Back
}
reloadCamera()
}
重新加载相机
func reloadCamera() {
captureSession = AVCaptureSession()
// let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
var captureDevice:AVCaptureDevice! = nil
if (camera == CameraType.Front) {
let videoDevices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
for device in videoDevices{
let device = device as! AVCaptureDevice
if device.position == AVCaptureDevicePosition.Front {
captureDevice = device
break
}
}
} else {
captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
}
do {
let input = try? AVCaptureDeviceInput(device: captureDevice)
if (captureSession?.canAddInput(input) != nil){
captureSession?.addInput(input)
stillImageOutput = AVCaptureStillImageOutput()
stillImageOutput?.outputSettings = [AVVideoCodecKey : AVVideoCodecJPEG]
if (captureSession?.canAddOutput(stillImageOutput) != nil){
captureSession?.addOutput(stillImageOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
cameraView.layer.addSublayer(previewLayer!)
captureSession?.startRunning()
}
cameraView.bringSubviewToFront(actionView)
previewImageView.bringSubviewToFront(actionView)
self.previewImageView.hidden = true
}
}
}
最佳答案
在不知 Prop 体细节的情况下,很难猜测,但看看你的代码,我认为你遇到的问题是你试图向 session 添加多个摄像头(每次切换时,您实际上是在尝试添加新设备)。
测试捕获 session 是否正在运行,如果是,则在添加新设备之前移除现有设备(后置/前置摄像头)。确保将其包装为这样的交易:
func beginSession(captureDevice : AVCaptureDevice?) {
if captureSession.running {
captureSession.beginConfiguration()
let currentInput : AVCaptureInput = captureSession.inputs[0] as! AVCaptureInput
captureSession.removeInput(currentInput)
do {
try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
} catch {
print("Error adding video input device")
}
captureSession.commitConfiguration()
} else {
// Setup the camera and layer for the first time.
do {
try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice))
} catch {
print("Error adding video input device")
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
self.view.layer.insertSublayer(previewLayer!, atIndex: 0)
previewLayer?.frame = self.view.layer.frame
captureSession.startRunning()
}
}
这是一个相当简单但实用的示例。我只是每次都传递捕获设备(根据需要使用前置/后置摄像头),它在我的代码中运行良好。非常原型(prototype)实现,但希望这能为您提供缺少的步骤:
- .beginConfiguration() 在更改正在运行的 session 之前。
- 删除现有设备,然后添加新设备。
- .commitConfiguration() 使一切正常。
无需删除预览层,因为它已经连接到您的 currentSession。
关于ios - 在前后摄像头之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33637566/