Search code examples
iosobjective-cxcodeipadavcapturesession

AVCaptureSession canAddInput for front-camera always returns false on iPad


The following code is working perfectly on the iPhone. Switching back and forth between back- and front-camera. However, when run it on an iPad the canAddInput-method always returns NO when selecting the front-camera (back camera works fine). Any ideas why?

- (void)addVideoInput:(BOOL)isFront{

    AVCaptureDevice *videoDevice;

    //NSLog(@"Adding Video input - front: %i", isFront);

    [self.captureSession removeInput:self.currentInput];

    if(isFront == YES){
        self.isFrontCam = YES;
        videoDevice = [self frontFacingCameraIfAvailable];
    }else{
        self.isFrontCam = NO;
        videoDevice = [self backCamera];
    }



    if (videoDevice) {

        NSError *error;
        AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
        if (!error) {

          // Everything's fine up to here.
          // the next line always resolves to NO and thus the
          // Video input isn't added.



            if ([[self captureSession] canAddInput:videoIn]){
                [[self captureSession] addInput:videoIn];
                self.currentInput = videoIn;

                // Set the preset for the video input

                if([self.captureSession canSetSessionPreset:AVCaptureSessionPreset1920x1080]){
                    [self.captureSession setSessionPreset:AVCaptureSessionPreset1920x1080];
                }
            }
            else {
                NSLog(@"Couldn't add video input");
                NSLog(@"error: %@", error.localizedDescription);
            }
        }
        else{
            NSLog(@"Couldn't create video input");
            NSLog(@"error: %@", error.localizedDescription);
        }
    }else
        NSLog(@"Couldn't create video capture device");

}

Solution

  • Most probably, it fails because you set the sessionPreset to 1080p and the iPad's front camera is not 1080p.

    I had the same issue and just set it to .high, which by Apple's definition Specifies capture settings suitable for high-quality video and audio output. It should just choose the highest supported resolution for any camera.

    If you don't trust this description, you could also create an array of your preferred presets and check if they're available for the camera you wish to use before switching cameras.

    I took the following code from an answer to basically the same question:

    let videoPresets: [AVCaptureSession.Preset] = [.hd4K3840x2160, .hd1920x1080, .hd1280x720] //etc. Put them in order to "preferred" to "last preferred"
    let preset = videoPresets.first(where: { device.supportsSessionPreset($0) }) ?? .hd1280x720
    captureSession.sessionPreset = preset
    

    https://stackoverflow.com/a/53214766/3338129