Video hangs on camera switch with AVFoundation

I made an application with the function of capturing and saving videos. I used AVFoundation for this, and Apple AVCam was my guide.

Hope I can clarify:
Everything works fine until I let go of the video projector that processes AVCamCaptureManager for the first time (in AVCam, which will be AVCamViewController). After that, when I create it again, the video freezes immediately after switching the camera. Even a restart does not help, does not clear, or the device is reset. (Sometimes one of the things helps, but thatโ€™s not the rule).

I release videoViewController when you do not need to save memory.

The code for switching the camera is basically the same as in AVCam:

NSError *error; AVCaptureDeviceInput *newVideoInput; AVCaptureDevicePosition position = currentVideoInput.device.position; if (position == AVCaptureDevicePositionBack) newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:frontFacingCamera error:&error]; else if (position == AVCaptureDevicePositionFront) newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:backFacingCamera error:&error]; if (newVideoInput != nil) { [session beginConfiguration]; [session removeInput:currentVideoInput]; if ([session canAddInput:newVideoInput]) { [session addInput:newVideoInput]; [self setVideoInput:newVideoInput]; } else { [session addInput:currentVideoInput]; } [session commitConfiguration]; [newVideoInput release]; } else if (error) { NSLog(@"%@",[error localizedDescription]); } 

Code with which I reject videoView

 [self.videoViewController.view removeFromSuperview]; self.videoViewController = nil; 

My current โ€œworkaroundโ€ is to simply leave it, even if I don't need it.

Can someone explain why this is happening and how to solve it.

EDIT: Solved
As W Dyson pointed out in his answer, I had to end the session before releasing my video projector, for example:

 [[[self.videoViewController captureManager] session] stopRunning]; [self.videoViewController.view removeFromSuperview]; self.videoViewController = nil; 

Thanks W Dyson.

+6
source share
2 answers

Do you get error logs? If not, you need to fix the code above and see what they say. What version of AVCam are you using? They recently upgraded the project to version 1.2, which is much more efficient and uses blocks.

In my experience, you should not create and recreate a session, you can just leave it. You may need to structure your application a little differently. What exactly is your application about? Maybe we can help you. If your application is centered around the camera, then itโ€™s easier to leave the session turned on, if your video is only a video, then perhaps using AVCam will be redundant.

Your real problem, for me, sounds like AVCaptureDeviceInput. Download the original AVCam package and see if any retention or security indicators have changed if the statements. If there is another code, send a message.

UPDATE: can you change

 } else if (error) { NSLog(@"%@",[error localizedDescription]); } 

to

 } if (error) { NSLog(@"%@",[error localizedDescription]); } 

and tell me if there is an error?

Also, before releasing the view controller that owns the session, make sure you stop the session and set the capture manager to zero.

UPDATE 2: Try this switch code. This is what I used. AVCamMirringMode is the following structure:

 enum { AVCamMirroringOff = 1, AVCamMirroringOn = 2, AVCamMirroringAuto = 3 }; typedef NSInteger AVCamMirroringMode; - (BOOL) toggleCamera { BOOL success = NO; if ([self cameraCount] > 1) { NSError *error; AVCaptureDeviceInput *newVideoInput; AVCaptureDevicePosition position = [[videoInput device] position]; BOOL mirror; if (position == AVCaptureDevicePositionBack){ newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontFacingCamera] error:&error]; switch ([self mirroringMode]) { case AVCamMirroringOff: mirror = NO; break; case AVCamMirroringOn: mirror = YES; break; case AVCamMirroringAuto: default: mirror = YES; break; } } else if (position == AVCaptureDevicePositionFront){ newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backFacingCamera] error:&error]; switch ([self mirroringMode]) { case AVCamMirroringOff: mirror = NO; break; case AVCamMirroringOn: mirror = YES; break; case AVCamMirroringAuto: default: mirror = NO; break; } } else goto bail; if (newVideoInput != nil) { [[self session] beginConfiguration]; [[self session] removeInput:[self videoInput]]; if ([[self session] canAddInput:newVideoInput]) { [[self session] addInput:newVideoInput]; AVCaptureConnection *connection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]]; if ([connection isVideoMirroringSupported]) { [connection setVideoMirrored:mirror]; } [self setVideoInput:newVideoInput]; } else { [[self session] addInput:[self videoInput]]; } [[self session] commitConfiguration]; success = YES; [newVideoInput release]; } else if (error) { if ([[self delegate] respondsToSelector:@selector(captureManager:didFailWithError:)]) { [[self delegate] captureManager:self didFailWithError:error]; } } } bail: return success; } 
+3
source

Try this - he worked as a champion for me:

 BOOL isUsingFrontFacingCamera; - (BOOL) swapCameras { if ([self cameraCount] > 1) { AVCaptureDevicePosition desiredPosition; if (isUsingFrontFacingCamera) { desiredPosition = AVCaptureDevicePositionBack; } else { desiredPosition = AVCaptureDevicePositionFront; } for (AVCaptureDevice *d in [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo]) { if ([d position] == desiredPosition) { [[self session] beginConfiguration]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:d error:nil]; for (AVCaptureInput *oldInput in [[self session] inputs]) { [[self session] removeInput:oldInput]; } [[self session] addInput:input]; [[self session] commitConfiguration]; break; } } isUsingFrontFacingCamera = !isUsingFrontFacingCamera; return YES; } return NO; } 

You can leave this code to replace the original swapCameras in VideoRecorderCaptureManager.m

Origin: Apple SquareCam sample code.

+9
source

Source: https://habr.com/ru/post/886150/


All Articles