在前后摄像头之间切换

我正在尝试制作一个自定义的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() } 

SwitchCamera

 func switchCamera() { if camera == CameraType.Back { camera = CameraType.Front } else { camera = CameraType.Back } reloadCamera() } 

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 } } } 

在不知道具体细节的情况下,很难猜测,但是看看你的代码,我认为你遇到的问题是你试图在会话中添加多个摄像头(每次切换时,你都是实际上试图添加一个新设备)。

测试捕获会话是否正在运行,如果是,则在添加新设备之前移除现有设备(后置/前置摄像头)。 确保将其包装为如此的事务:

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

这是一个相当简单但function性的例子。 我只是每次都通过捕获设备(根据需要使用前/后摄像头),它在我的代码中运行良好。 非常原型实现,但希望这可以为您提供缺少的步骤:

  1. .beginConfiguration()在更改正在运行的会话之前。
  2. 删除现有设备,然后添加新设备。
  3. .commitConfiguration()使一切正常。

无需删除预览图层,因为它已经连接到currentSession。