I am having a crash when trying to take a photo (front facing camera), that only fails when the user is using picture in picture mode for a separate apps video. Everything works fine if the user doesn't have a video in picture in picture. The crash occurs on this line:
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
with the error
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:] - inconsistent state.'
I tried checking if the phone just couldn't take a photo in general while using picture in picture mode, but the default iOS camera app is able to take a picture fine (although maybe it uses a different method of taking the photo). stillImageOutput
and videoConnection
seem to be set up fine and are not nil.
Here is the code leading up to this crash in case it helps.
avCaptureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice* cameraDevice = [GS60_FriendFeed_ScreenshotSelfie_Preview_View frontFacingCameraIfAvailable];
avCaptureSession.sessionPreset = avCaptureSessionPresetString;
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&error];
if (!input) {
NSLog(@"ERROR: trying to open camera: %@", error);
}
[avCaptureSession addInput:input];
AVCaptureStillImageOutput* stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[avCaptureSession addOutput:stillImageOutput];
[avCaptureSession startRunning];
and later
AVCaptureConnection* videoConnection = nil;
AVCaptureStillImageOutput* stillImageOutput = [[avCaptureSession outputs] objectAtIndex:0];
for (AVCaptureConnection* connection in stillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
AVCaptureVideoOrientation avcaptureOrientation = AVCaptureVideoOrientationPortrait;
if(orientation == UIInterfaceOrientationUnknown) {
avcaptureOrientation = AVCaptureVideoOrientationPortrait;
} else if(orientation == UIInterfaceOrientationPortrait) {
avcaptureOrientation = AVCaptureVideoOrientationPortrait;
} else if(orientation == UIInterfaceOrientationPortraitUpsideDown) {
avcaptureOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
} else if(orientation == UIInterfaceOrientationLandscapeLeft) {
avcaptureOrientation = AVCaptureVideoOrientationLandscapeLeft;
} else if(orientation == UIInterfaceOrientationLandscapeRight) {
avcaptureOrientation = AVCaptureVideoOrientationLandscapeRight;
}
[videoConnection setVideoOrientation:avcaptureOrientation];
//this line flips the image so it uses exactly what the preview shows
[videoConnection setVideoMirrored:YES];
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
...
I would prefer to be able to take the photo but if that is not possible while picture in picture is open, knowing how to detect that we won't be able to take it would be still be helpful.
Thanks for any help.
Take a selfie in Portrait mode. With an iPhone X and later, you can take selfies in Portrait mode. Here's how: Open the Camera app. Swipe to Portrait mode and tap the front-facing camera button . Hold your iPhone in front of your face. Snap your selfie with one of the volume buttons.
Change Lighting on iPhone 1 Open the Photos app, then select the Portrait mode photo that you want to change. 2 Tap Edit. Lighting effects appear in the bottom part of the photo. 3 Swipe the lighting effects to choose the one you want. 4 Tap Done. See More....
Take photos in Portrait mode. To capture the perfect shot: Open the Camera app and swipe to Portrait mode. Follow the tips on your screen, such as moving further away. When Portrait mode is ready, the lighting effect, like Natural Light, turns yellow. Tap the shutter button .
The rear-facing iPhone XR camera supports only Natural Light, Studio Light, and Contour Light. With an iPhone X and later, you can take selfies in Portrait mode. Here's how: Open the Camera app.
Make sure the connection is there and enabled
if (!videoConnection || !videoConnection.enabled || !videoConnection.active) {
// Raise error here / warn user...
return;
}
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
AVCaptureVideoOrientation avcaptureOrientation = AVCaptureVideoOrientationPortrait;
This can happen when the capture session is interrupted and unable to start, which can be triggered by a phone call, alarm, the app being in split screen on the iPad, or another app using picture-in-picture mode.
It's a good idea to add an observer for the AVCaptureSessionWasInterrupted
notification so your app can respond and alert the user according to the reason.
You can check for the reason in the notification callback:
notification.userInfo[AVCaptureSessionInterruptionReasonKey];
Furthermore, you should add an observer for AVCaptureSessionInterruptionEnded
to restart the session when the interruption has ended.
Apple has a great example on how this works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With