AVFoundation在相关框架栈中的的位置
- AVCaptureDevice代表了输入设备,例如摄像头与麦克风。
- AVCaptureInput代表了输入数据源
- AVCaptureOutput代表了输出数据源
- AVCaptureSession 用于协调输入与输出之间的数据流
- 用AVCaptureVideoPreviewLayer提供摄像头的预览功能
通常的步骤包括:
1、建立一个AVCaptureDevice类对象来代表一个输入设备
2、建立一个AVCaptureInput子类的一个对象,来设置和管理输入
3、通过建立一个AVCaptureOutput子类的对象来管理输出并设置输出代理
4、通过一个AVCaptureSession对象来管理输入设备和输出设备间数据流,将input和output添加到session
5、建立一个AVCaptureVideoPreviewLayer(CALayer的子类)的图层来预览摄像头中录制的内容。
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property(nonatomic,strong)AVCaptureSession *session;//捕捉会话
@property(nonatomic,strong)AVCaptureVideoPreviewLayer *preLayer;//二维码生成的图层
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
[selfcreateRcode];
}
#pragma mark --二维码的创建
-(void)createRcode{
//1.摄像头设备
AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
//设置输入由于模拟器没有摄像头,因此在此最好做一个判断
NSError *error =nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInputdeviceInputWithDevice:deviceerror:&error];
if (error) {
NSLog(@"没有摄像头%@",error.localizedDescription);
return;
}
//设置输入(metadata元数据)
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutputalloc] init];
//3.1设置输出代理
//说明:使用主线程队列,相应比较同步,使用其他队列,相应不同步,容易让用户产生不好的用户体验setMetadataObjectsDelegate
[output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];
//4.拍摄会话
_session = [[AVCaptureSessionalloc]init];
//添加session的输入输出
[_sessionaddInput:input];
[_sessionaddOutput:output];
//4.1设置输出的格式
//提示:一定要先设置会话的输出为output之后,在指定输出的元数据类型
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
//设置好预览图层(用来让用户能够看到扫描情况)
_preLayer = [AVCaptureVideoPreviewLayerlayerWithSession:_session];
//5.1设置预览图层的大小
[_preLayersetFrame:self.view.bounds];
//5.3将图层添加到视图的图层
[self.view.layerinsertSublayer:_preLayeratIndex:0];
//6.启动会话
[_sessionstartRunning];
}
//代理方法
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
//会频繁的扫描,调用代理方法
//1.如果扫描完成,停止会话
[self.sessionstopRunning];
//2.删除预览图层
[_preLayerremoveFromSuperlayer];
NSLog(@"%@",metadataObjects);
//3.设置扫描界面显示扫描结果
if (metadataObjects.count>0) {
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
//提示:如果需要对url或者名片等信息进行扫描,可以在此进行扩展
NSLog(@"%@",obj.stringValue);
}
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end