AvCam-ios从后置摄像头切换到前置摄像头非常慢,我该如何解决这个问题?

时间:2017-10-27 11:23:09

标签: ios avfoundation ios-camera

在切换之前

///,我确定isRunning == true

   func toggleCamera(){
        let first:TimeInterval = Date().timeIntervalSince1970
        let currentVideoDevice = self.videoInput.device
        ///////////////begin to switch
        self.captureSession.beginConfiguration()
        self.captureSession.removeInput(self.videoInput)
        if self.cameraDeviceType == .back {
            self.cameraDeviceType = .front
            self.inputCamera = self.frontDevice
        }else{
            self.cameraDeviceType = .back
            self.inputCamera = self.backDevice
        }
        do {
            self.videoInput = try AVCaptureDeviceInput(device:self.inputCamera)
        } catch {
            print(error)
        }
        if self.captureSession.canAddInput(self.videoInput) {
            NotificationCenter.default.removeObserver(self, name: .AVCaptureDeviceSubjectAreaDidChange, object: currentVideoDevice)
            NotificationCenter.default.addObserver(self, selector: #selector(self.subjectAreaDidChange), name: .AVCaptureDeviceSubjectAreaDidChange, object: self.videoInput.device)

            self.captureSession.addInput(self.videoInput)
        } else {
            self.captureSession.addInput(self.videoInput)
        }
        self.captureSession.commitConfiguration()
        if let connection = self.videoOutput?.connection(withMediaType: "video") {
            if connection.isVideoStabilizationSupported {
                connection.preferredVideoStabilizationMode = .auto
            }
            connection.isEnabled = false
            connection.isEnabled = true
        }
        let second:TimeInterval = Date().timeIntervalSince1970
        print("turnAroundInnerCost:",second-first)
    }

//// log:turnAroundInnerCost:0.431715965270996 ///运行时间很快,但界面开关很慢,约为5s

2 个答案:

答案 0 :(得分:1)

因此,每次切换都会重新创建相机,重新配置设备,启用/禁用连接等。尝试将相机配置逻辑移动到其他功能并调用一次,例如在viewDidLoad()中。

在相机之间切换可以是:

     func switchToFrontCamera() throws {
            guard let inputs = captureSession.inputs as? [AVCaptureInput], let rearCameraInput = self.rearCameraInput, inputs.contains(rearCameraInput),
                let frontCamera = self.frontCamera else { throw CameraError.invalidOperation }

            self.frontCameraInput = try AVCaptureDeviceInput(device: frontCamera)

            captureSession.removeInput(rearCameraInput)

            if captureSession.canAddInput(self.frontCameraInput) {
                captureSession.addInput(self.frontCameraInput)

                self.currentCameraPosition = .front
            }

            else {
                throw CameraError.invalidOperation
            }
        }

     func switchToRearCamera() throws {
            guard let inputs = captureSession.inputs as? [AVCaptureInput], let frontCameraInput = self.frontCameraInput, inputs.contains(frontCameraInput),
                let rearCamera = self.rearCamera else { throw CameraError.invalidOperation }

            self.rearCameraInput = try AVCaptureDeviceInput(device: rearCamera)

            captureSession.removeInput(frontCameraInput)

            if captureSession.canAddInput(self.rearCameraInput) {
                captureSession.addInput(self.rearCameraInput)

                self.currentCameraPosition = .rear
            }

            else { throw CameraError.invalidOperation }
        }

然后你可以打电话

  switch currentCameraPosition {
    case .front:
        try switchToRearCamera()

    case .rear:
        try switchToFrontCamera()
  }

答案 1 :(得分:0)

//在viewDid()中创建一次captureSession,但当我将相机从后向前更改时,此func仍然运行缓慢

let frontDevice = AVCaptureDevice.devices(withMediaType:AVMediaTypeVideo).map { $0 as! AVCaptureDevice }.filter { $0.position == .front}.first!

let backDevice = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).map { $0 as! AVCaptureDevice }.filter { $0.position == .back}
    .first!

public func turnAroundCamera() {
    sessionQueue.async {
        let first:TimeInterval = Date().timeIntervalSince1970
        let oldVedioInput = self.videoInput

        //self.captureSession.beginConfiguration()

        self.captureSession.removeInput(self.videoInput)
        if self.cameraDeviceType == .back {
            self.cameraDeviceType = .front
            self.inputCamera = self.frontDevice
        }else{
            self.cameraDeviceType = .back
            self.inputCamera = self.backDevice
        }
        do {
            self.videoInput = try AVCaptureDeviceInput(device:self.inputCamera)
        } catch {
            print(error)
        }

        if self.captureSession.canAddInput(self.videoInput) {
            self.captureSession.addInput(self.videoInput)
        }else{
            self.captureSession.addInput(oldVedioInput)
        }
        //self.captureSession.commitConfiguration()

        let second:TimeInterval = Date().timeIntervalSince1970
        print("turnAroundInnerCost:",second-first)
    }
}

更多信息,记录turnAroundInnerCost:0.245857000350952

实际上,当我调用它时,函数turnAroundCamera()运行得很快,但是captureOutput()在函数turnAroundCamera()结束后运行缓慢(大约5s)。这个时间很贵,特别是当我试图转过来时从后到前的相机。所以我尝试做的事情(启用/禁用)是刷新会话,希望刷新captureOutput .....