本文介绍了同一AVCaptureSession中有多个AVCaptureVideoDataOutput的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否可以通过单个摄像头设备输入将多个AVCaptureVideoDataOutput添加到AVCaptureSession?

I was wondering if it's possible to add multiple AVCaptureVideoDataOutput to AVCaptureSession with a single camera device input?

我的实验表明,添加第二个VideoDataOutput将导致canAddOutput返回NO.但是我在Apple文档中找不到任何地方说不允许多个数据输出.

My experiments indicate that adding a second VideoDataOutput will cause canAddOutput return NO. But I couldn't find anywhere on Apple's documentation says multiple data output is disallow.

推荐答案

我们不能对多个AVCaptureVideoDataOutput对象使用单个AVCaptureSession.

We can not use single AVCaptureSession for multiple AVCaptureVideoDataOutput objects.

您可以做的是用多个AVCaptureSession对象创建多个AVCaptureVideoDataOutput.

What can you do is you can make multiple AVCaptureVideoDataOutput with multiple AVCaptureSession objects.

您可以创建AVCaptureVideoDataOutputAVCaptureSession的两个不同的设置,然后可以在应用程序中一个接一个地使用它们,就可以实现目标.

You can create two different setups of the AVCaptureVideoDataOutput and AVCaptureSession then you can use them one after another in the app and you will be able to achieve the goal.

就我而言,我必须一次使用相机捕获正面和背面的图像.

In my case, I had to capture front and back image using the camera at a time.

我确实为AVCaptureVideoDataOutputAVCaptureSession创建了两个不同的对象,如下所示.

I did create two different objects for AVCaptureVideoDataOutput and AVCaptureSession as given below.

/* Front camera settings */
@property bool isFrontRecording;
@property (strong, nonatomic) AVCaptureDeviceInput *videoInputBack;
@property (strong, nonatomic) AVCaptureStillImageOutput *imageOutputBack;
@property (strong, nonatomic) AVCaptureSession *sessionBack;

/* Back camera settings */
@property bool isBackRecording;
@property (strong, nonatomic) AVCaptureDeviceInput *videoInputFront;
@property (strong, nonatomic) AVCaptureStillImageOutput *imageOutputFront;
@property (strong, nonatomic) AVCaptureSession *sessionFront;

现在,鉴于视图最初已加载,所以我设置了后置摄像头并设置了会话开始记录的标志,或者不设置两个会话的标志,如下所述.

Now in view did load initially I did setup back camera and set up flags for session started recording or not for both sessions as followed.

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupBackAVCapture];

    self.isFrontRecording = NO;
    self.isBackRecording = NO;
}

- (void)setupBackAVCapture
{
    NSError *error = nil;

    self.sessionBack = [[AVCaptureSession alloc] init];
    self.sessionBack.sessionPreset = AVCaptureSessionPresetPhoto;

    AVCaptureDevice *camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    self.videoInputBack = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:&error];
    [self.sessionBack addInput:self.videoInputBack];

    self.imageOutputBack = [[AVCaptureStillImageOutput alloc] init];
    [self.sessionBack addOutput:self.imageOutputBack];

}

现在,无论何时用户开始拍摄照片,我们都会使用以下代码拍摄正面照片.

Now, whenever the user starts capturing photo we will capture the front photo using below code.

- (IBAction)buttonCapture:(id)sender {
    [self takeBackPhoto];
}

- (void)takeBackPhoto
{
    [self.sessionBack startRunning];
    if (!self.isFrontRecording) {

        self.isFrontRecording = YES;

        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
        AVCaptureConnection *videoConnection = [self.imageOutputBack connectionWithMediaType:AVMediaTypeVideo];

        if (videoConnection == nil) {
            return;
        }


        [self.imageOutputBack
         captureStillImageAsynchronouslyFromConnection:videoConnection
         completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

             if (imageDataSampleBuffer == NULL) {
                 return;
             }

             NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

             UIImage *image = [[UIImage alloc] initWithData:imageData];

             UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);

             [self.imageView setImage:image];

             [self.sessionBack stopRunning];

             // Set up front camera setting and capture photo.
             [self setupFrontAVCapture];
             [self takeFrontPhoto];

         }];

        self.isFrontRecording = NO;

    }

}

一旦捕获到背面图像,我们将设置会话以使用 setupFrontAVCapture 方法捕获正面图像,然后我们将使用 takeFrontPhoto 方法捕获正面图像,如下所示

As soon as the back image will be captured we will setup session to capture front image using setupFrontAVCapture method and then we will capture front image using takeFrontPhoto method as given below.

- (void)setupFrontAVCapture
{
    NSError *error = nil;

    self.sessionFront = [[AVCaptureSession alloc] init];
    self.sessionFront.sessionPreset = AVCaptureSessionPresetPhoto;

    AVCaptureDevice *camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    camera = [self cameraWithPosition:AVCaptureDevicePositionFront];

    self.videoInputFront = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:&error];
    [self.sessionFront addInput:self.videoInputFront];

    self.imageOutputFront = [[AVCaptureStillImageOutput alloc] init];
    [self.sessionFront addOutput:self.imageOutputFront];
}

- (void)takeFrontPhoto
{
    [self.sessionFront startRunning];
    if (!self.isBackRecording) {

        self.isBackRecording = YES;

        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
        AVCaptureConnection *videoConnection = [self.imageOutputFront connectionWithMediaType:AVMediaTypeVideo];

        if (videoConnection == nil) {
            return;
        }


        [self.imageOutputFront
         captureStillImageAsynchronouslyFromConnection:videoConnection
         completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

             if (imageDataSampleBuffer == NULL) {
                 return;
             }

             NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

             UIImage *image = [[UIImage alloc] initWithData:imageData];

             UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);
             [self.imageViewBack setImage:image];

             [self.sessionFront stopRunning];


         }];

        self.isBackRecording = NO;

    }

}

这样,您可以使用两组不同的AVCaptureSessionAVCaptureStillImageOutput对象,就可以实现目标.

This way you can use two different set of AVCaptureSession and AVCaptureStillImageOutput objects and you can achieve your goal.

如果您有任何困惑,请告诉我.

Please let me know if you have any confusion.

这篇关于同一AVCaptureSession中有多个AVCaptureVideoDataOutput的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-09 16:58