// // 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