AVFoundation切换摄像头速度慢(已连接到样本缓冲区)

时间:2018-09-19 01:15:26

标签: ios swift avfoundation

override func viewDidLoad() {
    super.viewDidLoad()
    ...
    setupDevice()
    setupInputOutput()
}

查看是否加载启动了安装链

 func setupDevice() {
    let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified)
    let devices = deviceDiscoverySession.devices

    for device in devices {
        if device.position == AVCaptureDevice.Position.back {
            backCamera = device
            setupCorrectFramerate(currentCamera: backCamera!)
        }
        else if device.position == AVCaptureDevice.Position.front {
            frontCamera = device
            setupCorrectFramerate(currentCamera: frontCamera!)
        }
    }
    currentCamera = cameraModeIsBack ? backCamera : frontCamera
}

var deviceInput: AVCaptureDeviceInput?
let videoOutput = AVCaptureVideoDataOutput()

func setupInputOutput() {
    do {
        let captureDeviceInput = try AVCaptureDeviceInput(device: currentCamera!)
        deviceInput = captureDeviceInput
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1280x720

        if captureSession.canAddInput(deviceInput!) {
            captureSession.addInput(deviceInput!)
        }
        videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "sample buffer delegate", attributes: []))
        if captureSession.canAddOutput(videoOutput) {
            captureSession.addOutput(videoOutput)
        }
        captureSession.startRunning()
        if(firstTime){
            setupMetal()
        }
        firstTime = false
        toggleCamerButton.isEnabled = true
    } catch {
        print(error)
    }
}

总的来说,我找到了设备输入,设置了它们的帧速率并设置了捕获会话(缓冲区输出已处理到MTKView)。

问题是当我更换相机时。它要么反应敏捷,要么充满生气,要么变得非常缓慢,在响应之前冻结了4-5秒。

我用来更换相机的逻辑:

func updateCameras(){
    DispatchQueue.global().async {
        self.captureSession.stopRunning()
        self.captureSession.removeInput(self.deviceInput!)
        self.currentCamera = self.cameraModeIsBack ? self.backCamera : self.frontCamera
        self.changeCameras()
    }
}


func changeCameras(){
    do {
        let captureDeviceInput = try AVCaptureDeviceInput(device: self.currentCamera!)
        self.deviceInput = captureDeviceInput
        if self.captureSession.canAddInput(self.deviceInput!) {
            self.captureSession.addInput(self.deviceInput!)
        }
        self.captureSession.startRunning()
       DispatchQueue.main.async {
            self.toggleCamerButton.isEnabled = true
       }
    } catch {
        print(error)
    }

}

我已尽力对其进行了修订。切换相机本质上是

  1. 停止摄像头会话
  2. 删除输入
  3. 添加输入
  4. 开始会议

我不知道为什么在地球上它是如此变化(大多数时间在我的iPhone X上都能正常工作,而在iPhone 6上却总是很慢)。

1 个答案:

答案 0 :(得分:0)

我怀疑操纵cameraSession的调用应该在主线程上完成。尝试将updateCameras()改为使用DispatchQueue.main.async()而不是DispatchQueue.global().async

赞:

func updateCameras(){
    DispatchQueue.main.async {
        self.captureSession.stopRunning()
        self.captureSession.removeInput(self.deviceInput!)
        self.currentCamera = self.cameraModeIsBack ? self.backCamera : self.frontCamera
        self.changeCameras()
    }
}

通过这种更改,就不再需要在DispatchQueue.main.async()函数中调用changeCameras()