We are developing a ios camera app which has features like : picture/video capture, media file management, media sharing etc. Our landing screen is the camera preview screen. This has many buttons to navigate to other screens.
If we are at the viewfinder screen and then lock and unlock the phone, the preview remains OK. But if I navigate from viewfinder to another screen and come back to viewfinder and then do a lock and unlock, the camera preview becomes stuck, ie the screen will show last frame. But the buttons etc are navigable. This is the error we are getting:
Capture session runtime error: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSUnderlyingError=0x1490838e0 {Error Domain=NSOSStatusErrorDomain Code=-12780 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12780), NSLocalizedDescription=The operation could not be completed
What is the most stable and efficient way to see the preview?
Some relevant snippets of code:
-(void) setGUIBasedOnMode{
if (![self isStreamStarted]) {
if (shutterActionMode == SapCamSelectionModeLiveStream)
{
_flashButton.hidden = true;
_cameraButton.hidden = true;
_liveSteamSession = [[VCSimpleSession alloc] initWithVideoSize:[[UIScreen mainScreen]bounds].size frameRate:30 bitrate:1000000 useInterfaceOrientation:YES];
[_liveSteamSession.previewView removeFromSuperview];
AVCaptureVideoPreviewLayer *ptr;
[_liveSteamSession getCameraPreviewLayer:(&ptr)];
_liveSteamSession.previewView.frame = self.view.bounds;
_liveSteamSession.delegate = self;
}
else{
[_liveSteamSession.previewView removeFromSuperview];
_liveSteamSession.delegate = nil;
// [self removeObservers];
_cameraButton.hidden = false;
if(flashFlag == 0){
_flashButton.hidden = false;
}
else if(flashFlag == 1){
_flashButton.hidden = true;
}
self.session = [[AVCaptureSession alloc] init];
self.previewView.hidden = false;
self.previewView.session = self.session;
[self configureCameraSettings];
dispatch_async( self.sessionQueue, ^{
switch ( self.setupResult )
{
case AVCamSetupResultSuccess:
{
[self addObservers];
[self.session startRunning];
self.sessionRunning = self.session.isRunning;
if(loadingCameraFlag == false){
[self hidingView];
}
break;
}
case AVCamSetupResultCameraNotAuthorized:
{
dispatch_async( dispatch_get_main_queue(), ^{
NSString *message = NSLocalizedString( @"App doesn't have permission to use the camera, please change privacy settings", @"Alert message when the user has denied access to the camera");
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"AVCam" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"OK", @"Alert OK button" ) style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancelAction];
UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"Settings", @"Alert button to open Settings" ) style:UIAlertActionStyleDefault handler:^( UIAlertAction *action ) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}];
[alertController addAction:settingsAction];
[self presentViewController:alertController animated:YES completion:nil];
} );
break;
}
case AVCamSetupResultSessionConfigurationFailed:
{
dispatch_async( dispatch_get_main_queue(), ^{
NSString *message = NSLocalizedString( @"Unable to capture media", @"Alert message when something goes wrong during capture session configuration" );
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"OK", @"Alert OK button" ) style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
} );
break;
}
}
});
}
}
}
More:
[self.session beginConfiguration];
if ( [self.session canAddInput:videoDeviceInput] ) {
[self.session addInput:videoDeviceInput];
self.videoDeviceInput = videoDeviceInput;
dispatch_async( dispatch_get_main_queue(), ^{
UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation;
AVCaptureVideoOrientation initialVideoOrientation = AVCaptureVideoOrientationPortrait;
if ( statusBarOrientation != UIInterfaceOrientationUnknown ) {
initialVideoOrientation = (AVCaptureVideoOrientation)statusBarOrientation;
}
AVCaptureVideoPreviewLayer *previewLayer = (AVCaptureVideoPreviewLayer *)self.previewView.layer;
previewLayer.connection.videoOrientation = initialVideoOrientation;
} );
}
else {
self.setupResult = AVCamSetupResultSessionConfigurationFailed;
}