3

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.

Community
  • 1
  • 1
Edwin Abraham
  • 645
  • 7
  • 24

2 Answers2

3

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!

Brandon
  • 182
  • 11
  • I did the same without the explicit background queue implementation. The recording stops and the file is written. Problem is the capture session doesn't maintain the last frozen frame when I come to foreground. Any thoughts on that? – Edwin Abraham May 09 '14 at 06:40
  • 1
    @EdAbe Not too sure about why that happens. You could try adding a `AVCaptureStillImageOutput` and attempting to capture the last frame on notification. Then display that image when the app resumes instead of the preview layer. I've never used it, so that may not work at all, but it's worth a try. Good luck! – Brandon May 09 '14 at 15:28
3

This is late but I was experiencing some of the same. In order to get around the problem you first have to realize ViewWillAppear and ViewWillDisappear are strictly for in app transitions from one View Controller to another. They don't work for foreground to background and back again transitions. I used a similar fix above:

//application became active
[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(applicationEnteredForeground:)
name:UIApplicationWillEnterForegroundNotification
                                           object:nil];

//application went into background
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationBecameActive:)
name:UIApplicationDidBecomeActiveNotification
                                           object:nil];

In the selector methods just stop and start your camera session and as the other stackoverflow post suggest, it would be a good idea to lazily instantiate your avcapturesession so that your app is memory conservative

brian Scroggins
  • 2,701
  • 3
  • 17
  • 17