2015-11-10 1 views
2

Я пытаюсь создать пользовательский 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 


     } 
    } 







} 
+0

Я не вижу, где вы когда-либо называли 'switchCamera', так где же проблема на самом деле возникает? Вы просто называете это smack в середине, пока идет захват уже? Если это так, это ваша проблема; это некогерентная вещь. – matt

+0

Я добавил кнопку в представление, которое вызывает 'switchCamera'. Я добавил код сейчас –

+0

Хорошо, но, как я уже говорил, вы не можете просто выкинуть сеанс захвата и заменить его таким образом. Вы не прекращаете сеанс. Вы не заменяете слой предварительного просмотра в интерфейсе. Это некогерентно. – matt

ответ

5

Не зная точных особенностей, это трудно догадаться, но, глядя на свой код, я думаю, что проблема, которую вы бежите в том, что вас» Повторяя попытку добавить к сеансу несколько камер (каждый раз, когда вы переключаетесь, вы на самом деле пытаетесь добавить новое устройство).

Тест, чтобы проверить, работает ли сеанс захвата, а затем, если он есть, затем удалите существующее устройство (переднюю/переднюю камеру) перед добавлением нового устройства. Убедитесь, что вы завернули транзакцию следующим образом:

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

Это довольно простой, но функциональный пример. Я просто передаю устройство захвата каждый раз (передняя/задняя камера по мере необходимости), и он работает достаточно хорошо в моем коде. Очень опытная реализация, но, надеюсь, это дает вам недостающие шаги:

  1. .beginConfiguration() ПЕРЕД заменой текущей сессии.
  2. Удалите существующее устройство и добавьте новый.
  3. .commitConfiguration(), чтобы все работало.

Не нужно удалять слой предварительного просмотра, поскольку он уже подключен к вашей текущей сессии в любом случае.