在iPhone5上,AVCaptureOutput captureStillImageAsynchronouslyFromConnection永远无法完成。

8
在我的应用程序中,我显示了一个AVCaptureVideoPreviewLayer,然后使用AVCaptureOutput中的captureStillImageAsynchronouslyFromConnection函数,在用户点击按钮时捕获静态图像。在iPhone 5上,这一直运行良好,但是它从未完成过。
我的设置代码如下:
...
self.imageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.imageOutput setOutputSettings:outputSettings];

self.captureSession = [[[AVCaptureSession alloc] init] autorelease];
[self.captureSession addInput:self.rearFacingDeviceInput];
[self.captureSession addOutput:self.imageOutput];
[self.captureSession setSessionPreset:AVCaptureSessionPresetPhoto];

self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
self.previewLayer.frame = CGRectMake(0, 0, 320, 427);
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspect;

[self.captureSession startRunning];
[outputSettings release];

我的捕获方法是:

AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in self.imageOutput.connections){
    for (AVCaptureInputPort *port in [connection inputPorts]){
        if ([[port mediaType] isEqual:AVMediaTypeVideo] ){
            videoConnection = connection;
            break;
        }
    }
    if (videoConnection) { break; }
}

//code to abort if not return 'soon'
...

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

    //use image here

}];

使用iPhone5时,captureStillImageAsynchronouslyFromConnection方法无法完成

我进行了以下测试:

  • 不是因为操作系统6的原因。因为该代码在已更新的iPhone 4s和iPod(第四代)上都可以工作

  • captureSession正在运行

  • videoConnection不为nil

  • imageOutput不为nil

另外:

  • 我使用这个方法而不是UIImagePickerController,因为我需要将预览放置为子视图。

  • 在iPhone5上,调用capture Session上的stopRunning需要几秒钟时间


我认为有两个原因导致了这个问题。1)你在一个特殊的线程中。2)该设备不支持你设置的相机参数。该方法的描述是:当静态图像捕获完成时将调用一个块。该块将传递一个包含图像数据的CMSampleBuffer对象或一个NSError对象(如果无法捕获图像)。所以,你是否尝试过打印NSError的原因? - Vincent Sit
图像样本缓冲区是空的吗? - cph2117
1个回答

0

嗯,这段代码运行得很好。已经在iPhone 4和5上进行了测试(基于SDK 7.1,使用ARC)。

有几件事情你需要考虑。

1)确保你正确设置了后置设备输入。

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[self setRearFacingDeviceInput:[AVCaptureDeviceInput deviceInputWithDevice:device error:nil]];

2) 正如Vincent所提到的,会出现错误,请尝试记录错误和imageSampleBuffer

3) session的-startRunning和-stopRunning操作需要很长时间才能完成(几秒钟,甚至5-6秒),这些方法在完成所有工作之前不会返回,为了避免阻塞UI,您不应该在主线程上调用这些方法,一种方法是使用GCD

dispatch_queue_t serialQueue = dispatch_queue_create("queue", NULL);
dispatch_async(serialQueue, ^{
    [self.captureSession startRunning];
});

如果 still captureStillImageAsynchronously 没有完成(为了确保这一点,在 block 中添加断点并记录所有内容),您应该检查设备的相机。我相信您的代码适用于所有 iPhone 5 设备。希望这可以帮助您,祝您好运。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接