【问题标题】:Smooth transition while switching cameras in custom camera swift + xcode在自定义相机swift + xcode中切换相机时平滑过渡
【发布时间】:2017-04-28 12:45:53
【问题描述】:

我正在使用 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()
}

【问题讨论】:

    标签: ios swift xcode swift3 avfoundation


    【解决方案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()
    }
    

    【讨论】:

      【解决方案2】:

      viewDidAppear 中调用loadCamera() 函数而不是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
          }
      }
      

      【讨论】:

      • 您也可以使用后台线程来执行一些 uicomponents 更新。
      • 有什么建议或链接可以分享给我看看吗?
      • 您不能在viewWillAppear 内完成繁重的任务,请在进一步编码之前查看difference
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      • 2018-04-10
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多