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

}];

captureStillImageAsynchronouslyFromConnection 永远不会为我使用 iPhone5 完成

我已经测试过:

  • 它不是 OS 6,因为此代码适用于已更新的 iPhone 4s 和 iPod(iPod touch(第 4 代)

  • captureSession 正在运行

  • videoConnection 不为零

  • imageOutput 不为零

还:

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

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

4

1 回答 1

0

好吧,这段代码工作正常。针对 iPhone 4 和 5 进行了测试(baseSDK 7.1,在 ARC 下)。

你需要考虑的事情很少。

1)确保正确设置了rearFacingDeviceInput,

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

2)正如文森特所说,会有错误,尝试同时记录错误和imageSampleBuffer

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

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

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

于 2014-05-06T08:37:20.080 回答