在iOS中,我使用代码从AVCaptureStillImageOutput捕获,因此:
[_captureStillOutput captureStillImageAsynchronouslyFromConnection:_captureConnectioncompletionHandler:asyncCaptureCompletionHandler];
为了简化我的代码,我的asyncCaptureCompletionHandler块如下所示:
void(^asyncCaptureCompletionHandler)(CMSampleBufferRef imageDataSampleBuffer, NSError *error) =
^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (CMSampleBufferIsValid(imageDataSampleBuffer)) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
}
}
我已经研究了我所有的代码和堆栈溢出的交叉引用,没有发现任何建议,说明为什么在没有正确JPEG的情况下会捕获有效的样本缓冲区。
_captureStillOutput = [[AVCaptureStillImageOutput alloc] init];
_captureStillOutput.outputSettings =
[NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecJPEG, AVVideoCodecKey,
nil];
if ([session canAddOutput:_captureStillOutput]) {
[session addOutput:_captureStillOutput];
}
调试器中有补充信息:*由于未捕获的异常"NSInvalidArgumentException"而终止应用程序,原因:"*+[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:]-不是jpeg示例缓冲区。"
在谷歌和堆栈中搜索"Not a jpeg sample buffer"都没有产生任何结果。我被卡住了。啊。
这个问题由来已久。我来自未来,可以确认这种情况在2015年仍然会发生。我试图通过同样的步骤来解决这个问题,但没有成功。然而,这个问题让我意识到,当在captureStillImageAsynchronouslyFromConnection
的完成处理程序之外处理CMSampleBufferRef imageDataSampleBuffer
时,它的行为很奇怪。
简而言之:
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection
completionHandler:^( CMSampleBufferRef imageDataSampleBuffer, NSError *error )
{
//call another method to handle the sample buffer causes weird behaviour
//maybe the buffer is not being safely referenced by AVFoundation?
[self handleBufferSomewhereElse:imageDataSampleBuffer]; //will behave strangely
//even more so if you move to another thread
}];
更喜欢这样做:
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection
completionHandler:^( CMSampleBufferRef imageDataSampleBuffer, NSError *error )
{
//handle the buffer right here
NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
//works better
}];
希望这能帮助到别人。
此解决方案的下一步是使用记录调试器中报告的所有数据
po imageDataSampleBuffer
在抛出异常时,这总是会产生很多细节,比如样本缓冲区上的大量信息。然后,自从把它发布到SO之后,我注释掉了一些代码,然后取消了注释,现在它就可以工作了。我的代码没有任何变化,但是,我确实关闭了一些在mac上运行的程序。也许这是一个开发机器错误。在这之后,我关闭并重新打开了Xcode,并且没有抛出异常。