2013-12-23 62 views
6

我在iOS 7中测试新的条形码扫描API时遇到了问题。此示例(单视图应用程序)工作正常,但我想停止AVCaptureSession并在识别出EAN代码后显示第一个视图由相机。iOS正确停止AVCaptureSession

[self.captureSession startRunning];不起作用。

如何正确停止AVCaptureSession?

#import "ViewController.h" 
#import <AVFoundation/AVFoundation.h> 

@interface ViewController() <AVCaptureMetadataOutputObjectsDelegate> 

@property (strong) AVCaptureSession *captureSession; 

@end 

@implementation ViewController 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.captureSession = [[AVCaptureSession alloc] init]; 
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    NSError *error = nil; 
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error]; 
    if(videoInput) 
     [self.captureSession addInput:videoInput]; 
    else 
     NSLog(@"Error: %@", error); 

    AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init]; 
    [self.captureSession addOutput:metadataOutput]; 
    [metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; 
    [metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]]; 

    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; 
    previewLayer.frame = self.view.layer.bounds; 
    [self.view.layer addSublayer:previewLayer]; 

    [self.captureSession startRunning]; 

} 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection 
{ 
    for(AVMetadataObject *metadataObject in metadataObjects) 
    { 
     AVMetadataMachineReadableCodeObject *readableObject = (AVMetadataMachineReadableCodeObject *)metadataObject; 
     if([metadataObject.type isEqualToString:AVMetadataObjectTypeQRCode]) 
     { 
      NSLog(@"QR Code = %@", readableObject.stringValue); 
     } 
     else if ([metadataObject.type isEqualToString:AVMetadataObjectTypeEAN13Code]) 
     { 
      NSLog(@"EAN 13 = %@", readableObject.stringValue); 



     } 
    } 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

回答

18

实际上,你可以因此停止AVCaptureSession:

[self.captureSession stopRunning]; 

但我怀疑你真正想要做的是,定格画面。在属性中保留对您的previewLayer的引用是有帮助的。然后:

[[self.previewLayer connection] setEnabled:NO]; 

你可以尝试这样的事情,定格画面,然后几秒钟

- (void)  captureOutput:(AVCaptureOutput *)captureOutput 
    didOutputMetadataObjects:(NSArray *)metadataObjects 
      fromConnection:(AVCaptureConnection *)connection 
{ 
    [[self.previewLayer connection] setEnabled:NO]; 

    double delayInSeconds = 2.0; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 
            (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     [[self.previewLayer connection] setEnabled:YES]; 

    }); 

    ... 

} 

更新
整个下架后解冻它:

[self.captureSession stopRunning]; 
[self.previewLayer removeFromSuperlayer]; 
self.previewLayer = nil; 
self.captureSession = nil; 
+0

喜代工,感谢您的回复。我只是想将已识别的ean解析为变量以备后用,并立即关闭捕获会话。 – Boeringer

+0

@ Boeringer-见我的更新。希望能帮助到你... – foundry

0

你应该在主线程中调用performViewController。如下面:

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ 
if (metadataObjects != nil && [metadataObjects count] > 0) { 
    AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0]; 
    if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { 

     [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO]; 
     // should call the view controller transfer method in the main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self performSegueWithIdentifier:@"show first view controller" sender: self]; 
     }); 

    } 
} 

}