Ios AVCaptureOutput captureStillImageAsynchronouslyFromConnection在iPhone 5上从未完成

Ios AVCaptureOutput captureStillImageAsynchronouslyFromConnection在iPhone 5上从未完成,ios,Ios,在我的应用程序中,我正在显示一个AVCaptureVideoPreviewLayer,然后当用户使用AVCaptureOutput中的captureStillImageAsynchronouslyFromConnection功能单击按钮时,我会捕获一幅静态图像。这对我来说一直很好,直到iPhone5,它从来没有完成过 我的设置代码是: ... self.imageOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary *ou

在我的应用程序中,我正在显示一个AVCaptureVideoPreviewLayer,然后当用户使用AVCaptureOutput中的captureStillImageAsynchronouslyFromConnection功能单击按钮时,我会捕获一幅静态图像。这对我来说一直很好,直到iPhone5,它从来没有完成过

我的设置代码是:

...
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

}];
captureStillImageAsynchronouslyFromConnection在我使用iPhone 5时从未完成

我测试过:

  • 它不是操作系统6,因为该代码适用于已更新的iPhone4S和iPod(第四代iPod touch)

  • captureSession正在运行

  • 视频连接不是零

  • imageOutput不是零

此外:

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

  • 在iPhone 5上,在捕获会话中调用stopRunning也需要几秒钟


好吧,这段代码很好用。在iPhone 4和5上都进行了测试(baseSDK 7.1,在ARC下)

你必须考虑的事情很少。

1) 确保正确设置后面板设备输入

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[self setRearFacingDeviceInput:[AVCaptureDeviceInput deviceInputWithDevice:device error:nil]];
2) 如前所述,将出现错误,请尝试记录错误和imageSampleBuffer

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

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

如果静态捕获静态图像异步未完成(为了确保这一点,请在块中添加断点,并记录所有内容),您应该检查设备的摄像头。我相信你的代码适用于所有iPhone5设备。希望这有帮助,祝你好运。

我认为有两个原因导致这个问题。1) 你处于一种特殊的状态。2) 此设备不支持您设置的相机参数。此方法的描述为:静态图像捕获完成时将调用的块。如果无法捕获图像,则将向该块传递包含图像数据的CMSampleBuffer对象或NSError对象。那么,您是否尝试过打印N错误的原因?imageSampleBuffer是否为空?