首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使AVCaptureSession只扫描一次

使AVCaptureSession只扫描一次
EN

Stack Overflow用户
提问于 2014-01-26 09:21:32
回答 1查看 873关注 0票数 3

如何使AVCaptureSession只扫描一次AVCaptureMetadataOutput。我一直有问题,它扫描了一个条形码超过30次,延迟扫描声音约2-3秒,然后它变成蜂鸣疯狂(字面意思)和显示~30 UIAlertViews!

下面的代码是我只扫描一次的尝试。

代码语言:javascript
复制
    - (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);
    }
    }

任何帮助都很感激。

EN

回答 1

Stack Overflow用户

发布于 2014-01-26 10:09:14

iOS中的条形码扫描器是AV管道的一部分。扫描仪将查看每个捕获的图像,如果它识别图像中的条形码,则调用委托。因此,如果它在连续30个图像中识别一个条形码,它将连续调用委托30次。

这取决于你的应用程序如何处理这样的案件。有些应用程序可能需要不断地了解已识别的条形码。很明显,您只对一个识别事件感兴趣。要做到这一点,您有几种选择:

  1. 完全停止视频捕捉。这通常是适当的,如果你的应用程序切换到一个不同的场景,如果它已经捕获了条形码。
  2. 从AV管道中删除条形码扫描器(AVCaptureMetadataOutput)。
  3. 记住最后一次捕获的条形码和最后一次捕获的时间,如果在最后一次捕获后的2到3秒内再次捕获相同的条形码,则不要采取行动。

你发布的代码不完整。您可能已经实现了类似于选项2(和/或1)的东西。这些选项可能不够,因为AV管道可能有几个帧的积压。一旦停止捕获,它将继续处理已经捕获的帧,但不处理条形码。

我预计大约有五帧正在制作中。如果您真的体验了多达30帧,这将表明您的主线程太忙,无法跟上捕获过程。

因此,最好的方法可能是实现选项3(除了您已经拥有的选项之外),并确保主线程不会太忙。

代码语言:javascript
复制
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];
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21361747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档