【问题标题】:Multiple AVCaptureVideoDataOutput in same AVCaptureSession同一个 AVCaptureSession 中的多个 AVCaptureVideoDataOutput
【发布时间】:2017-11-18 12:39:56
【问题描述】:

我想知道是否可以通过单个相机设备输入将多个AVCaptureVideoDataOutput 添加到AVCaptureSession

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

【问题讨论】:

    标签: ios iphone ios-camera


    【解决方案1】:

    我们不能将单个AVCaptureSession 用于多个AVCaptureVideoDataOutput 对象。

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

    您可以创建AVCaptureVideoDataOutputAVCaptureSession的两种不同设置,然后您可以在应用程序中依次使用它们,您将能够实现目标。

    在我的例子中,我必须使用相机一次捕捉正面和背面图像。

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

    /* 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;
    

    现在视图确实加载了最初我确实设置了后置摄像头并设置了会话开始录制的标志,或者没有为两个会话设置标志。

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

    现在,每当用户开始拍摄照片时,我们都会使用以下代码拍摄正面照片。

    - (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 方法捕获正面图像,如下所示.

    - (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 对象,从而实现您的目标。

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

    【讨论】:

    • 感谢杰伊什提供的信息。您知道这种方法是否适用于单个输入设备吗?我的目标是使用相同的后置摄像头,并以不同的分辨率获取两个输出。
    • 不,您不能一次使用单个输入设备。在您的情况下,您可能可以从原始输出制作另一个分辨率的文件。这可能是您的一种选择。或者您可以使用两个不同的会话并一个接一个地使用。但这需要一两秒钟的时间。
    • 谢谢!这也符合我的实验。我现在接受你的解决方案作为答案。但是你知道苹果有没有说这是不允许的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2012-06-19
    相关资源
    最近更新 更多