Switching Cameras slow in AVCaptureSession
Asked Answered
D

1

8

I've looked at many other questions like this, and tried a lot of the solutions, but this case is a bit different. I'm using AVCaptureVideoDataOutputSampleBufferDelegate so that I can apply CIFilters to the live video feed. I'm using the following method to change cameras:

func changeCameras() {
    captureSession.stopRunning()
    var desiredPosition: AVCaptureDevicePosition?
    if front {
        desiredPosition = AVCaptureDevicePosition.Back
    } else {
        desiredPosition = AVCaptureDevicePosition.Front
    }

    let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as? [AVCaptureDevice]
    for device in devices! {
        if device.position == desiredPosition {
            self.captureSession.beginConfiguration()
                do {
                    let input = try AVCaptureDeviceInput(device: device)
                    for oldInput in self.captureSession.inputs {
                        print(oldInput)
                        self.captureSession.removeInput(oldInput as! AVCaptureInput)
                    }
                  print(input)
                    self.captureSession.addInput(input)
                    self.captureSession.commitConfiguration()
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        self.captureSession.startRunning()
                        })

                } catch { print("evic failed")}
        }
    }
    front = !front
}

The methods that I am using to set up the camera (called in viewDidLoad) and receive the sampleBuffer from the delegate are here: https://gist.github.com/JoeyBodnar/17e22e3c04093caa54cf240ed8b1b601.

One problem is that when pressing the button to change cameras, it takes a solid 4-5 seconds of the screen freezing before changing. I've tried the above method, as well as creating a separate queue to run the entire function on, and it still takes a long time. I've never had this problem when switching cameras just using the regular AVVideoPreviewLayer, so I think this may be caused in part by the fact that i'm using the sample buffer delegate, but can't quite piece together how/why. Any help is appreciated. thanks!

Discord answered 9/7, 2016 at 23:23 Comment(2)
Hi @Joey, how you solved this. I am doing same in swift and it stops calling delegate for 4 - 6 sec and my last received buffer image seems to freeze on screen.Crewel
I'm having the exact same problem. Did anyone get to the bottom of this?Capriole
S
0

Use DispatchQueue.global().async so that the capturesession setup is done in the background and the ui doesn't freeze

DispatchQueue.global().async {
    self.captureSession.beginConfiguration()
    // captureSession configurations here
    
    // end with
    self.captureSession.commitConfiguration()
    DispatchQueue.main.async {
        self.captureSession.startRunning()
    }
}

This worked for me

For your Code it will go like this .

func changeCameras() {
    captureSession.stopRunning()
    var desiredPosition: AVCaptureDevicePosition?
    if front {
        desiredPosition = AVCaptureDevicePosition.Back
    } else {
        desiredPosition = AVCaptureDevicePosition.Front
    }

    let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as? [AVCaptureDevice]
    for device in devices! {
        if device.position == desiredPosition {
DispatchQueue.global().async {
            self.captureSession.beginConfiguration()
                do {
                    let input = try AVCaptureDeviceInput(device: device)
                    for oldInput in self.captureSession.inputs {
                        print(oldInput)
                        self.captureSession.removeInput(oldInput as! AVCaptureInput)
                    }
                  print(input)
                    self.captureSession.addInput(input)
                    self.captureSession.commitConfiguration()
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        self.captureSession.startRunning()
                        })

                } catch { print("evic failed")}
}
        }
    }
    front = !front
}
Synsepalous answered 7/8, 2023 at 4:47 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.