在自定义相机swift + xcode中切换相机时平滑过渡

时间:2016-12-13 12:40:49

标签: ios swift xcode swift3 avfoundation

我正在使用swift 3和xcode创建自定义相机视图。

我有工作,但我面临一个小问题。要从前/后切换摄像机设备,我将停止会话,从视图中删除视频预览图层,然后创建新会话并从前置摄像头添加新的视频预览图层。这使得新相机出现了混蛋。我希望相机设备之间平滑过渡。我怎么能这样做?

这是我加载相机的代码:

func loadCamera()
{

    session?.stopRunning()
    videoPreviewLayer?.removeFromSuperlayer()

    session = AVCaptureSession()
    session!.sessionPreset = AVCaptureSessionPresetPhoto


    var backCamera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .front)

    if cameraPos == "back"
    {
        backCamera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .back)
    }

    var error: NSError?
    var input: AVCaptureDeviceInput!
    do {
        input = try AVCaptureDeviceInput(device: backCamera)
    } catch let error1 as NSError {
        error = error1
        input = nil
        print(error!.localizedDescription)
    }

    if error == nil && session!.canAddInput(input) {
        session!.addInput(input)

        stillImageOutput = AVCapturePhotoOutput()


        if session!.canAddOutput(stillImageOutput) {
            session!.addOutput(stillImageOutput)


            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)

            videoPreviewLayer?.frame = cameraView.bounds
            videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
            videoPreviewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait


            cameraView.layer.addSublayer(videoPreviewLayer!)
            session!.startRunning()

        }   
    }
}

我从viewWillAppear

调用它
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    loadCamera()
}

我在用户点击更换相机时调用了负载相机

@IBAction func changeCamera(_ sender: UIButton) {

    if cameraPos == "back"
    {cameraPos = "front"}

    else
    {cameraPos = "back"}


    loadCamera()
}

2 个答案:

答案 0 :(得分:1)

在loadCamera()中,您需要从前捕获设备创建AVCaptureInput。在一些相机单件上保持后输入和前输入是一个好习惯。前后之间的平滑过渡可以通过删除所有输入然后分配另一个输入来完成。

func show(back: Bool) {
  session.beginConfiguration()
  if let inputs = session.inputs as? [AVCaptureDeviceInput] {
    for input in inputs {
      session.removeInput(input)
    }
  }
  if back {
    if session.canAddInput(backInput) {
      session.addInput(backInput)
    }
  } else {
    if session.canAddInput(frontInput) {
      session.addInput(frontInput)
    }
  }
  session.commitConfiguration()
}

答案 1 :(得分:-1)

调用loadCamera()内的viewDidAppear功能,而不是viewWillAppear

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(true)
    loadCamera()
}

后台主题:

DispatchQueue.global(qos: .background).async {

    // perform ui updation and web related code
    // background thread

    DispatchQueue.main.async {
        // main thread
    }
}