Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camera feed slow to load with AVCaptureSession on iOS - How can I speed it up?

Right now I'm trying to allow users to take pictures in my app without using UIImagePickerController. I'm using AVCaptureSession and all the related classes to load a camera feed as a sublayer on a full-screen view I have on one of my view controllers. The code works but unfortunately the camera is very slow to load. Usually takes 2-3 seconds. Here is my code:

session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;

if ([session canSetSessionPreset:AVCaptureSessionPresetHigh])
    //Check size based configs are supported before setting them
    [session setSessionPreset:AVCaptureSessionPresetHigh];

[session setSessionPreset:AVCaptureSessionPreset1280x720];

CALayer *viewLayer = self.liveCameraFeed.layer;
//NSLog(@"viewLayer = %@", viewLayer);

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];

captureVideoPreviewLayer.frame = viewLayer.bounds;
[viewLayer addSublayer:captureVideoPreviewLayer];

AVCaptureDevice *device;

if(isFront)
{
    device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
else
{
    device = [self frontCamera];
}

AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput * audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
[session addInput:audioInput];

NSError *error = nil;
input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
    // Handle the error appropriately.
    //NSLog(@"ERROR: trying to open camera: %@", error);
}

[session addInput:input];
[session startRunning];

stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];

Is there any way to speed it up? I've already tried loading it on another thread using Grand Central Dispatch and NSThread and though that stopped the app from freezing it made the loading of the camera take even longer. Any help is appreciated.

like image 310
Tony Friz Avatar asked Feb 22 '14 03:02

Tony Friz


2 Answers

Waiting for AVCaptureSession's startRunning function was my solution too. You can run startRunning in global async and then in main thread you can add your AVCaptureVideoPreviewLayer.

Swift 4 sample

DispatchQueue.global().async {
    self.captureSession.startRunning()
    DispatchQueue.main.async {
        let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
    }
}
like image 181
abdullahselek Avatar answered Oct 29 '22 08:10

abdullahselek


In my case, I need to wait for session to start running

dispatch_async(queue) {
  self.session.startRunning()

  dispatch_async(dispatch_get_main_queue()) {
    self.delegate?.cameraManDidStart(self)

    let layer = AVCaptureVideoPreviewLayer(session: self.session)
  }
}
like image 32
onmyway133 Avatar answered Oct 29 '22 10:10

onmyway133