简体   繁体   English

录制视频时更改相机捕获设备

[英]Change camera capture device while recording a video

I am developing an iPhone App.我正在开发一个 iPhone 应用程序。 In that, there is a requirement for Pausing and resuming the camera.其中,有暂停和恢复相机的要求。 So i used AVFoundation for that instead of using UIImagePickerController .所以我使用AVFoundation而不是使用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 am facing the problem when i change the camera to Front.在这里,当我将相机更改为 Front 时,我遇到了问题。 when i calling the above method by changing the camera to front, the preview layer is getting stuck and no preview is coming.当我通过将相机更改为前置来调用上述方法时,预览层卡住了,并且没有预览。 My doubt is "Can we change the capture device in the middle of capture session ?".我的疑问是“我们可以在捕获会话的中间更换捕获设备吗?”。 Please guide me where i am going wrong (or) Suggest me with a solution on how to navigate between front and back camera while recording.请指导我哪里出错(或)向我建议有关如何在录制时在前后摄像头之间导航的解决方案。

Thanks in Advance.提前致谢。

Yes, you can.是的你可以。 There are just a few of things you need to cater to.您只需要满足几件事。

  1. Need to be using AVCaptureVideoDataOutput and its delegate for recording.需要使用 AVCaptureVideoDataOutput 及其委托进行录制。
  2. Make sure you remove the previous deviceInput before adding the new deviceInput.在添加新的 deviceInput 之前,请确保删除以前的 deviceInput。
  3. You must remove and recreate the AVCaptureVideoDataOutput as well.您还必须删除并重新创建 AVCaptureVideoDataOutput。

I am using these two functions for it right now and it works while the session is running.我现在正在使用这两个函数,它在会话运行时工作。

- (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];
}

You can't change the captureDevice mid-session.您不能在会话期间更改 captureDevice。 And you can only have one capture session running at a time.并且您一次只能运行一个捕获会话。 You could end the current session and create a new one.您可以结束当前会话并创建一个新会话。 There will be a slight lag (maybe a second or two depending on your cpu load).会有一点延迟(可能一两秒取决于你的 CPU 负载)。

I wish Apple would allow multiple sessions or at least multiple devices per session... but they do not... yet.我希望 Apple 允许多个会话或每个会话至少允许多个设备......但他们还没有......

您是否考虑过进行多个会话,然后再处理视频文件以将它们合并为一个?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM