如何使AVCaptureSession只扫描一次AVCaptureMetadataOutput。我一直有问题,它扫描了一个条形码超过30次,延迟扫描声音约2-3秒,然后它变成蜂鸣疯狂(字面意思)和显示~30 UIAlertViews!
下面的代码是我只扫描一次的尝试。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
CGRect highlightViewRect = CGRectZero;
AVMetadataMachineReadableCodeObject *barCodeObject;
NSString *detectionString = nil;
NSArray *barCodeTypes = @[AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code];
for (AVMetadataObject *metadata in metadataObjects) {
for (NSString *type in barCodeTypes) {
if ([metadata.type isEqualToString:type])
{
barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
highlightViewRect = barCodeObject.bounds;
detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
break;
}
}
if (detectionString != nil)
{
[_session removeOutput:_output];
[_session stopRunning];
_session = nil;
_output = nil;
[_prevLayer removeFromSuperlayer];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/barcodeBeep.wav", [[NSBundle mainBundle] resourcePath]]];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[audioPlayer play];
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
}任何帮助都很感激。
发布于 2014-01-26 10:09:14
iOS中的条形码扫描器是AV管道的一部分。扫描仪将查看每个捕获的图像,如果它识别图像中的条形码,则调用委托。因此,如果它在连续30个图像中识别一个条形码,它将连续调用委托30次。
这取决于你的应用程序如何处理这样的案件。有些应用程序可能需要不断地了解已识别的条形码。很明显,您只对一个识别事件感兴趣。要做到这一点,您有几种选择:
你发布的代码不完整。您可能已经实现了类似于选项2(和/或1)的东西。这些选项可能不够,因为AV管道可能有几个帧的积压。一旦停止捕获,它将继续处理已经捕获的帧,但不处理条形码。
我预计大约有五帧正在制作中。如果您真的体验了多达30帧,这将表明您的主线程太忙,无法跟上捕获过程。
因此,最好的方法可能是实现选项3(除了您已经拥有的选项之外),并确保主线程不会太忙。
if (detectionString != nil)
{
if ([detectionString isEqualToString:_lastCapturedBarcode]
&& [_lastCaptureTime timeIntervalSinceNow] < -3.0)
return; // do nothing; the barcode was already captured
_lastCapturedBarcode = detectionString;
_lastCapturedBarcode = [NSDate date];
[_session removeOutput:_output];
[_session stopRunning];
_session = nil;
_output = nil;
[_prevLayer removeFromSuperlayer];https://stackoverflow.com/questions/21361747
复制相似问题