【问题标题】:Making AVCaptureSession Only Scan Once使 AVCaptureSession 只扫描一次
【发布时间】:2014-01-26 09:21:32
【问题描述】:

如何使AVCaptureSession 只扫描AVCaptureMetadataOutput ONCE。我一直在扫描一个条形码超过 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);
    }
    }

任何帮助表示赞赏。

【问题讨论】:

    标签: ios7 avcapturesession


    【解决方案1】:

    iOS 中的条码扫描器是作为 AV 管道的一部分实现的。扫描仪将查看每个捕获的图像并在识别图像中的条形码时调用代理。因此,如果它在 30 个连续的图像中识别出一个条形码,它将连续调用代理 30 次。

    如何处理这种情况取决于您的应用。某些应用程序可能希望不断收到有关已识别条形码的通知。您显然只对单个识别事件感兴趣。为此,您有多种选择:

    1. 完全停止视频捕获。如果您的应用程序在捕获条形码后切换到不同的场景,这通常是合适的。

    2. 从 AV 管道中移除条码扫描器 (AVCaptureMetadataOutput)。

    3. 记住上次捕获的条码和上次捕获的时间,如果在上次捕获后 2 到 3 秒内再次捕获相同的条码,则不要采取行动。

    您发布的代码不完整。可能是您已经实现了类似于选项 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];
    

    【讨论】:

      猜你喜欢
      • 2014-01-11
      • 1970-01-01
      • 2018-07-05
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多