Newer
Older
XinYang_IOS / XYSW / YHScanQRTool / YHScanQREngineManager.m
@zhangfeng zhangfeng on 7 Dec 4 KB 1.8.0
//
//  YHScanQREngineManager.m
//  YHAVFoundtionQRScan
//
//  Created by Foxconn on 2018/1/25.
//  Copyright © 2018年 Foxconn. All rights reserved.
//
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
#import "YHScanQREngineManager.h"


@interface YHScanQREngineManager()<AVCaptureMetadataOutputObjectsDelegate>

@property (strong,nonatomic) AVCaptureMetadataOutput *scanOutput;
@property (strong,nonatomic) AVCaptureSession *scanSesion;
@end

@implementation YHScanQREngineManager

static YHScanQREngineManager *_instance;

+(instancetype) sharedEngineManager{
    return [[self alloc] init];
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

-(id)copyWithZone:(NSZone *)zone {
    return _instance;
}

-(id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}

-(void) setupSessionPreset:(NSString *)sessionPreset metadataObjectTypes:(NSArray *)metadataObjectTypes currentController:(UIViewController *)currentController scanViewX:(float) X scanViewY:(float) Y scanViewWidth:(float) width scanViewHeight:(float) height{
    // 1、获取摄像设备
    _nativeDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    // 2、创建设备输入流
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:_nativeDevice error:nil];
    
    // 3、创建数据输出流
    _scanOutput = [[AVCaptureMetadataOutput alloc] init];
    [_scanOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    //4、创建会话对象
    _scanSesion = [[AVCaptureSession alloc] init];
    [_scanSesion setSessionPreset:AVCaptureSessionPresetHigh];
    //4、会话采集率
    _scanSesion.sessionPreset = sessionPreset;
    if ([_scanSesion canAddInput:deviceInput]) {
        [_scanSesion addInput:deviceInput];
    }
    if ([_scanSesion canAddOutput:self.scanOutput]) {
        [_scanSesion addOutput:self.scanOutput];
    }
    
    //5、设置数据输出类型
    _scanOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
    CGFloat x = X / ScreenWidth;
    CGFloat y = Y / ScreenHeight;
    CGFloat Width = width / ScreenWidth;
    CGFloat Height = height / ScreenHeight;
    //5(1)、设置扫描范围 因为默认是横屏状态 所以要交换Y X Width Height
    [_scanOutput setRectOfInterest:CGRectMake(y, x, Height, Width)];
    //6、添加扫描画面
    _scanPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_scanSesion];
    _scanPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _scanPreviewLayer.frame = CGRectMake(0, 0, currentController.view.bounds.size.width, currentController.view.bounds.size.height);
    [currentController.view.layer insertSublayer:_scanPreviewLayer atIndex:0];
    //7、开始扫描
    [_scanSesion startRunning];
    
}
#pragma mark - - - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    if (_delegate && [_delegate respondsToSelector:@selector(scanQREngineManager:didOutputMetadaObjects:)]) {
        [_delegate scanQREngineManager:self didOutputMetadaObjects:metadataObjects];
    }
}
#pragma mark - Setter
-(void)setIsTorch:(BOOL)isTorch{
    _isTorch = isTorch;
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    [captureDevice lockForConfiguration:&error];
    if (_isTorch) {
        // 手电筒打开
        [captureDevice setTorchMode:AVCaptureTorchModeOn];
    }else{
        // 手电筒关闭
        [captureDevice setTorchMode:AVCaptureTorchModeOff];
    }
    // 请求解除独占访问硬件设备
    [captureDevice unlockForConfiguration];
}

- (void)scanSuccessStopRunning {
    [_scanSesion stopRunning];
}

-(void) scanSuccessRemoveVideoPreviewFromSuperLayer{
    [_scanPreviewLayer removeFromSuperlayer];
}

-(void)scanSuccessPlaySoundPath:(NSString *)path{
    /**
     1 判断有没有传入图片
     2 如果没有传入图片,则显示framework自带的图片
     3 如果有传入的图片,最好是有图片的路径
     */
    NSString *audioFile = [[NSBundle mainBundle] pathForResource:path ofType:nil];
    NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
    
    SystemSoundID soundID = 0;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
    AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
    AudioServicesPlaySystemSound(soundID); // 播放音效
}

void soundCompleteCallback(SystemSoundID soundID, void *clientData){
    
}


@end