Changing the camera capture device during video recording

I am developing an application for the iPhone. In this case, pause and resume the camera. So I used AVFoundation to do this instead of using UIImagePickerController .

My code is:

  - (void) startup :(BOOL)isFrontCamera { if (_session == nil) { NSLog(@"Starting up server"); self.isCapturing = NO; self.isPaused = NO; _currentFile = 0; _discont = NO; // create capture device with video input _session = [[AVCaptureSession alloc] init]; AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if(isFrontCamera) { NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; AVCaptureDevice *captureDevice = nil; for (AVCaptureDevice *device in videoDevices) { if (device.position == AVCaptureDevicePositionFront) { captureDevice = device; break; } } cameraDevice = captureDevice; } cameraDevice=[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:nil]; [_session addInput:input]; // audio input from default mic AVCaptureDevice* mic = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; AVCaptureDeviceInput* micinput = [AVCaptureDeviceInput deviceInputWithDevice:mic error:nil]; [_session addInput:micinput]; // create an output for YUV output with self as delegate _captureQueue = dispatch_queue_create("uk.co.gdcl.cameraengine.capture", DISPATCH_QUEUE_SERIAL); AVCaptureVideoDataOutput* videoout = [[AVCaptureVideoDataOutput alloc] init]; [videoout setSampleBufferDelegate:self queue:_captureQueue]; NSDictionary* setcapSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange], kCVPixelBufferPixelFormatTypeKey, nil]; videoout.videoSettings = setcapSettings; [_session addOutput:videoout]; _videoConnection = [videoout connectionWithMediaType:AVMediaTypeVideo]; [_videoConnection setVideoOrientation:AVCaptureVideoOrientationPortrait]; NSDictionary* actual = videoout.videoSettings; _cy = [[actual objectForKey:@"Width"] integerValue]; _cx = [[actual objectForKey:@"Height"] integerValue]; AVCaptureAudioDataOutput* audioout = [[AVCaptureAudioDataOutput alloc] init]; [audioout setSampleBufferDelegate:self queue:_captureQueue]; [_session addOutput:audioout]; _audioConnection = [audioout connectionWithMediaType:AVMediaTypeAudio]; [_session startRunning]; _preview = [AVCaptureVideoPreviewLayer layerWithSession:_session]; _preview.videoGravity = AVLayerVideoGravityResizeAspectFill; } } 

Here I encountered a problem when I change the camera to Front. when I call the above method, changing the camera to the foreground, the preview layer is stuck and the preview does not appear. I doubt: "Can we change the capture in the middle of the capture session?". Let me know where I am wrong (or). Suggest me a solution on how to move between the front and rear cameras during recording.

Thanks at Advance.

+4
source share
3 answers

Yes, you can. There are just a few things you need to satisfy.

  • You must use AVCaptureVideoDataOutput and its delegate for recording.
  • Before adding a new deviceInput, make sure you delete the previous DeviceInput.
  • You must also delete and recreate AVCaptureVideoDataOutput.

I am using these two functions for him right now, and it works during the session.

 - (void)configureVideoWithDevice:(AVCaptureDevice *)camera { [_session beginConfiguration]; [_session removeInput:_videoInputDevice]; _videoInputDevice = nil; _videoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:camera error:nil]; if ([_session canAddInput:_videoInputDevice]) { [_session addInput:_videoInputDevice]; } [_session removeOutput:_videoDataOutput]; _videoDataOutput = nil; _videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; [_videoDataOutput setSampleBufferDelegate:self queue:_outputQueueVideo]; NSDictionary* setcapSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange], kCVPixelBufferPixelFormatTypeKey, nil]; _videoDataOutput.videoSettings = setcapSettings; [_session addOutput:_videoDataOutput]; _videoConnection = [_videoDataOutput connectionWithMediaType:AVMediaTypeVideo]; if([_videoConnection isVideoOrientationSupported]) { [_videoConnection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight]; } [_session commitConfiguration]; } - (void)configureAudioWithDevice:(AVCaptureDevice *)microphone { [_session beginConfiguration]; _audioInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:microphone error:nil]; if ([_session canAddInput:_audioInputDevice]) { [_session addInput:_audioInputDevice]; } [_session removeOutput:_audioDataOutput]; _audioDataOutput = nil; _audioDataOutput = [[AVCaptureAudioDataOutput alloc] init]; [_audioDataOutput setSampleBufferDelegate:self queue:_outputQueueAudio]; [_session addOutput:_audioDataOutput]; _audioConnection = [_audioDataOutput connectionWithMediaType:AVMediaTypeAudio]; [_session commitConfiguration]; } 
+4
source

You cannot change the captureDevice session. And you can only perform one capture session at a time. You can end the current session and create a new one. There will be a slight lag (perhaps a second or two, depending on the load of your processor).

I would like Apple to allow multiple sessions, or at least multiple devices per session ... but they haven't ....

+1
source

Do you think you have several sessions and then process the video files to combine them into one?

0
source

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


All Articles