Search code examples
iosiphoneavcapturesession

AVCapturesession handling after returning from background


I am implementing a VideoRecorder using the AVCaptureSession. I am starting AVCaptureSession at viewWillAppear and tearing it down at viewWillDisappear on recommendation of this question AVCaptureSession fails when returning from background . Now when the Video is Recording and the app goes to background I want to stop recording and pause the capture session. But each time the app comes to foreground at this point I get one of the following

  1. Capture Session is not paused but recording and the Preview Layer keeps updating
  2. Capture Session provides Preview Layer with black-screen at this point app may or may not crash.

Any suggestions on handling the AVCaptureSession at this point. I would like to just show the last frame recorded on the previewLayer, once recording stops.


Solution

  • I have encountered a similar situation and in my experience I have found that viewWillDisappear: doesn't get called. I'm really not sure why, but I solved it by subscribing for notifications when the app goes inactive. Here's an example:

    In viewWillAppear:

    // Detect this for ending recording
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appInactive:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
    

    And the appropriate callback method:

    - (void)appInactive:(NSNotification *)notification {
    NSLog(@"App going inactive, stopping recording...");
    taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
        [[UIApplication sharedApplication] endBackgroundTask:taskId];
        taskId = UIBackgroundTaskInvalid;
    }];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        question.prepTimeRemaining = [prepEndTime timeIntervalSinceNow];
    
        // Stop camera stuff
        if (recording)
            [self stopRecording]; // Method to handle shutting down the session, any other cleanup, etc.
    
        // End task
        [[UIApplication sharedApplication] endBackgroundTask:taskId];
        taskId = UIBackgroundTaskInvalid;
    });
    }
    

    In viewWillDisappear:

    [[NSNotificationCenter defaultCenter] removeObserver:self];
    

    I immediately move to the next view when I detect this, so I'm not sure what it leaves behind on the preview layer, but I suspect it would do what you want. Hope this helps!