【问题标题】:AVCaptureSession output is not properly displayed and AVCaptureMetadataOutputObjectsDelegate method is not calledAVCaptureSession 输出未正确显示且未调用 AVCaptureMetadataOutputObjectsDelegate 方法
【发布时间】:2013-09-25 15:00:26
【问题描述】:

我有一个单视图应用程序,我正在尝试根据this 解释测试 iOS7 的 AVCaptureMetadataOutput。我的 ViewController 符合AVCaptureMetadataOutputObjectsDelegate,代码看起来像这样(几乎和 Mattt 的完全一样):

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // Testing the VIN Scanner before I make it part of the library
    NSLog(@"Setting up the vin scanner");
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                        error:&error];
    if (input) {
        [session addInput:input];
    } else {
        NSLog(@"Error: %@", error);
    }

    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    [session addOutput:output];

    [session startRunning];
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
       fromConnection:(AVCaptureConnection *)connection
{
    NSString *code = nil;
    for (AVMetadataObject *metadata in metadataObjects) {
        if ([metadata.type isEqualToString:AVMetadataObjectTypeCode39Code]) {
            code = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
            break;
        }
    }

    NSLog(@"code: %@", code);
}

当我在 iOS7 设备上运行它时(我尝试过 iPhone 4 和 iPhone 4s)XCode 记录“正在设置 vin 扫描仪”但相机(即 AVCaptureSession)永远不会打开。

编辑 1:

我添加了以下代码以在屏幕上显示相机输出:

AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];

// Display full screen    
previewLayer.frame = self.view.frame;

// Add the video preview layer to the view
[self.view.layer addSublayer:previewLayer];

但是显示很奇怪,不符合屏幕,旋转的方式也没有意义。另一个问题是,当我将相机聚焦在条形码上时,元数据委托方法永远不会被调用。请看下面的图片:

【问题讨论】:

  • 永远不会打开是什么意思?你测试了什么?
  • 当视图加载到我的 iPhone 上时,avcapturesession 不会启动,因为相机没有出现让我捕捉 av。我上面的内容实际上是单个视图应用程序中的所有附加代码,另外还有一个 AVFoundation 的导入。

标签: ios avfoundation ios7 avcapturesession


【解决方案1】:

相机不会像 UIImagePickerController 那样打开。问题是您的代码对输出没有任何作用。您需要添加一个预览层来显示相机在流入时的输出。

AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];

// Display full screen    
previewLayer.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);

// Add the video preview layer to the view
[self.view.layer addSublayer:previewLayer];

[session startRunning];

编辑**
在深入了解您的代码后,我发现了更多问题。

首先,您还需要设置要搜索的 MetaDataObjectTypes,现在您不需要寻找任何有效的对象类型。这应该在您将输出添加到会话之后添加。您可以在documentation中查看可用类型的完整列表

[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]];

其次,你的 AVCaptureSession *session 是你 viewDidLoad 中的一个局部变量,把它放在你的 @interface ViewController() 之后,如下所示。

@interface ViewController ()
@property (nonatomic, strong) AVCaptureSession *session;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.session = [[AVCaptureSession alloc] init];

    // Testing the VIN Scanner before I make it part of the library
    NSLog(@"Setting up the vin scanner");
    self.session = [[AVCaptureSession alloc] init];
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;

    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                    error:&error];
    if (input) {
        [self.session addInput:input];
    } else {
        NSLog(@"Error: %@", error);
    }

    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    [self.session addOutput:output];

    [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]];

    [self.session startRunning];
}

【讨论】:

  • 我认为这让我更接近,我已将问题编辑得更清楚。至少现在相机正在显示,虽然肯定不正确
  • 乔,我的儿子,你在回答这个问题上做得非常出色。我为你感到骄傲。 ——爸爸
猜你喜欢
  • 1970-01-01
  • 2019-01-05
  • 2013-05-15
  • 2023-03-26
  • 2021-10-01
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多