Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot capture dual photo from dual camera on iPhone X

Tags:

ios

swift

ios11

I am trying to simultaneously capture from both the telephoto and wide angle cameras on a iPhoneX. This is how I initialized the device:

let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)

and I requested dual photo delivery for AVPhotoOutput:

let photoSettings = AVCapturePhotoSettings()

photoSettings.isDualCameraDualPhotoDeliveryEnabled = true

capturePhotoOutput.capturePhoto(with: photoSettings, delegate: self)

However, I am running into this error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCapturePhotoOutput setDualCameraDualPhotoDeliveryEnabled:] Dual Camera dual photo delivery is not supported in this configuration'

Are there additional settings I need to enable or disable?

like image 281
user1155386 Avatar asked Nov 08 '22 14:11

user1155386


1 Answers

You have to make sure that your capture device, capture session and capture output are properly configured:

  1. Get capture device, using the following settings (which are already correct in your code): AVCaptureDeviceTypeBuiltInDualCamera, AVMediaTypeVideo, AVCaptureDevicePositionBack

  2. Create AVCaptureDeviceInput using the device you just retrieved in 1.

  3. Create AVCaptureSession and set its sessionPreset to AVCaptureSessionPresetPhoto
  4. Create AVCapturePhotoOutput
  5. Add the created AVCaptureDeviceInput and AVCapturePhotoOutput to the AVCaptureSession
  6. Set dualCameraDualPhotoDeliveryEnabled of your AVCapturePhotoOutput to YES
  7. Start capturing session

Corresponding code (Objective-C):

// Create capture device discovery session to retrieve devices matching our
// needs
// -------------------------------------------------------------------------------
AVCaptureDeviceDiscoverySession*    captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInDualCamera]
                                                                                                                           mediaType:AVMediaTypeVideo
                                                                                                                            position:AVCaptureDevicePositionBack];

// Loop through the retrieved devices and select correct one
// -------------------------------------------------------------------------------
for(AVCaptureDevice* device in [captureDeviceDiscoverySession devices])
{
    if(device.position == AVCaptureDevicePositionBack)
    {
        self.captureDevice = device;
        break;
    }
}

// Get camera input
// -------------------------------------------------------------------------------
NSError*                error               = nil;
AVCaptureDeviceInput*   videoDeviceInput    = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:&error];

if(!videoDeviceInput)
{
    NSLog(@"Could not retrieve camera input, error: %@", error);
    return;
}

// Initialize capture session
// -------------------------------------------------------------------------------   
self.captureSession                 = [[AVCaptureSession alloc] init];
self.captureSession.sessionPreset   = AVCaptureSessionPresetPhoto;

// Add video device input and photo data output to our capture session
// -------------------------------------------------------------------------------
self.captureOutput  = [AVCapturePhotoOutput new];
[self.captureSession beginConfiguration];
if(![self.captureSession canAddOutput:self.captureOutput])
{
    NSLog(@"Cannot add photo output!");
    return;
}

[self.captureSession addInput:videoDeviceInput];
[self.captureSession addOutput:self.captureOutput];
[self.captureSession commitConfiguration];

// Configure output settings AFTER input & output have been added to the session
// -------------------------------------------------------------------------------
if(self.captureOutput.isDualCameraDualPhotoDeliverySupported)
    self.captureOutput.dualCameraDualPhotoDeliveryEnabled = YES;

// Create video preview layer for this session, and add it to our preview UIView
// -------------------------------------------------------------------------------
AVCaptureVideoPreviewLayer* videoPreviewLayer   = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
videoPreviewLayer.videoGravity                  = AVLayerVideoGravityResizeAspect;
videoPreviewLayer.frame                         = self.view.bounds;
[self.view.layer addSublayer:videoPreviewLayer];

// Start capturing session
// -------------------------------------------------------------------------------
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    [self.captureSession startRunning];
});
  1. Later, for each photo that you will request from the AVCapturePhotoOutput, use AVCapturePhotoSettings with dualCameraDualPhotoDeliveryEnabled set to YES

Code (Objective-C):

AVCapturePhotoSettings* settings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey: AVVideoCodecTypeJPEG}];
settings.dualCameraDualPhotoDeliveryEnabled = YES;
[self.captureOutput capturePhotoWithSettings:settings delegate:self];
like image 120
RodKik Avatar answered Nov 15 '22 11:11

RodKik