【发布时间】:2017-11-18 12:39:56
【问题描述】:
我想知道是否可以通过单个相机设备输入将多个AVCaptureVideoDataOutput 添加到AVCaptureSession?
我的实验表明添加第二个VideoDataOutput 将导致canAddOutput 返回NO。但是我在 Apple 的文档中找不到任何地方说不允许多数据输出。
【问题讨论】:
标签: ios iphone ios-camera
我想知道是否可以通过单个相机设备输入将多个AVCaptureVideoDataOutput 添加到AVCaptureSession?
我的实验表明添加第二个VideoDataOutput 将导致canAddOutput 返回NO。但是我在 Apple 的文档中找不到任何地方说不允许多数据输出。
【问题讨论】:
标签: ios iphone ios-camera
我们不能将单个AVCaptureSession 用于多个AVCaptureVideoDataOutput 对象。
你可以做的是你可以用多个AVCaptureSession对象创建多个AVCaptureVideoDataOutput。
您可以创建AVCaptureVideoDataOutput和AVCaptureSession的两种不同设置,然后您可以在应用程序中依次使用它们,您将能够实现目标。
在我的例子中,我必须使用相机一次捕捉正面和背面图像。
我确实为AVCaptureVideoDataOutput 和AVCaptureSession 创建了两个不同的对象,如下所示。
/* 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;
}
}
这样您就可以使用两组不同的AVCaptureSession 和AVCaptureStillImageOutput 对象,从而实现您的目标。
如果您有任何困惑,请告诉我。
【讨论】: