Question

I'm building an app that shows a video preview layer using AVCaptureVideoPreviewLayer. The setup of that is pretty straight-forward, and it seems to work well:

newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:[[self captureManager] session]];
CGRect tmpRect = CGRectInset(recordingView.bounds, 3, 3);
[newCaptureVideoPreviewLayer setFrame:CGRectInset(tmpRect, 3, 3)];
CALayer *viewLayer = [recordingView layer];
[newCaptureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[viewLayer insertSublayer:newCaptureVideoPreviewLayer below:[[viewLayer sublayers] objectAtIndex:0]];
[self setCaptureVideoPreviewLayer:newCaptureVideoPreviewLayer];
[newCaptureVideoPreviewLayer release];

Later, I have a situation where a user can exchange the view containing the preview layer with one that shows a view that contains a recorded video, using MPMoviePlayerController. I set it up like so (the previous code block comes from the UIViewController's viewDidLoad: method, and this is in the same controller, as part of its own method for changing the view:

MPMoviePlayerController * player = [[MPMoviePlayerController alloc] initWithContentURL:url];
[player.view setFrame:[detailView playerView].bounds];  // player's frame must match parent's

player.view.backgroundColor = [UIColor clearColor];
player.shouldAutoplay = NO;
player.fullscreen = NO;
player.scalingMode = MPMovieScalingModeAspectFit;

[[detailView playerView] addSubview:player.view];

The trouble is that when the MPMoviePlayerController is added to the view, the preview "freezes" -- it shows the last frame of whatever was in front of the camera prior to entering this code block. I get no error messages, and I can't find any source for the problem.

I do note that I'm not releasing the player variable. Any attempts to do so break the player, including autoreleasing it, or trying to release it in a notification callback. However, I don't think that issue (while potentially a problem in its own right) is the source of killing my preview layer.

I would appreciate any insight you might have into this issue!

Update: @boredastronaut asked below how I set up the views here. I have one controller running all the views. In my app, I have the preview layer, and in the same spot, the view that contains the player. All views are loaded in -loadView:, and I use the hidden property to show/hide these layers as appropriate.

Was it helpful?

Solution 2

After no small amount of struggling, I settled on a different solution. I had been keeping the preview layer in memory and running while switching the view to the detailView. Now, I'm taking down the previewLayer and closing the recording session altogether when it's taken off screen, and then building it back up again when the user returns. It causes about a one second delay in re-initializing the previewLayer, but it's working, and I think that's fine.

OTHER TIPS

Thanks for this post! I finally got my app to work after 3 hours of debugging. I used the second approach suggested here and it worked beautifully.

if([self.capMan.session isInterrupted]) { [self.capMan.session startRunning]; }

You could just check if session of the preview layer is running, and if not, call startRunning method of session.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top