iosavfoundationavcapturesessionavcapturemoviefileoutput

Why does switching cameras stop my AVCaptureSession to MovieFileOutput?


The iOS documentation says you can add and remove inputs while a session is running, for example to switch between front and back cameras.

However when I try this, my session stops. I'm locking the session with beginConfiguration and commitConfiguration calls as follows:

- (void)switchCamera:(UIButton *)sender {

    dispatch_async([self sessionQueue], ^{

        AVCaptureSession *session = self.captureSession;
        [session beginConfiguration];

        AVCaptureInput *currentInput = self.currentCameraIsBack ? self.videoDeviceInputBack : self.videoDeviceInputFront;
        AVCaptureInput *newInput = self.currentCameraIsBack ? self.videoDeviceInputFront : self.videoDeviceInputBack;

        [session removeInput:currentInput];
        [session addInput:newInput];
        self.currentCameraIsBack = !self.currentCameraIsBack;

        [session setSessionPreset:AVCaptureSessionPresetMedium];
        [self setCameraOutputProperties];

        [session commitConfiguration];
    });
}

I am outputting to an AVCaptureMovieFileOutput. Is there anything I need to do to configure this session so it is switchable?

(Note that the OP in this question is trying to add a new input without removing the old one, which isn't the problem here)


Solution

  • Turns out that to do this you need to use an AVAssetWriter and call appendSampleBuffer: yourself with the resulting CMSampleBuffer like so:

    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    
        if (self.recording && self.videoWriterInput.isReadyForMoreMediaData) {
    
            [self.videoWriterInput appendSampleBuffer:sampleBuffer];
        }
    }