框架git
首先咱们从总体对所需框架作个初步了解。github
AVFoundation在相关框架栈中的的位置:session
为了捕捉视频,咱们须要这样几种类(与其它的子类)。架构
AVCaptureDevice 表明了输入设备,例如摄像头与麦克风。app
AVCaptureInput 表明了输入数据源框架
AVCaptureOutput 表明了输出数据源ide
AVCaptureSession 用于协调输入与输出之间的数据流工具
而且还有AVCaptureVideoPreviewLayer提供摄像头的预览功能性能
能够用这样一幅图来概述: 学习
例子
实际应用AVFoundation来捕捉视频流并不复杂。
Talk is Cheap,Show me the Code.
咱们用代码简单地描述用AVFoundation捕捉视频的过程,其余捕捉音频,静态图像的过程也是大同小异的。
1.建立AVCaputureSession。
做为协调输入与输出的中心,咱们第一步须要建立一个Session
AVCaptureSession *session = [[AVCaptureSession alloc] init];
2.建立AVCaptureDevice
建立一个AVCaptureDevice表明表明输入设备。在这里咱们制定设备用于摄像。
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
3.建立AVCaptureDeviceInput,并添加到Session中
咱们须要使用AVCaptureDeviceInput来让设备添加到session中, AVCaptureDeviceInput负责管理设备端口。咱们能够理解它为设备的抽象。一个设备可能能够同时提供视频和音频的捕捉。咱们能够分别用AVCaptureDeviceInput来表明视频输入和音频输入。
NSError *error; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; [session addInput:input];
4.建立AVCaptureOutput
为了从session中取得数据,咱们须要建立一个AVCaptureOutput
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc]init];
5.设置output delegate,将output添加至session,在代理方法中分析视频流
为了分析视频流,咱们须要为output设置delegate,而且指定delegate方法在哪一个线程被调用。须要主要的是,线程必须是串行的,确保视频帧按序到达。
videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL); [videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue]; [session addOutput:videoDataOutput];
咱们能够在delegate方法中分析视频流。
captureOutput:didOutputSampleBuffer:fromConnection:,
6.开始捕捉
[session startRunning];
经过上面的简单例子,我么能够看出使用AVFoundation来捕捉视频流并非十分复杂。重点是使用的过程须要了解配置的细节,还有性能问题。
实战
学习基础知识事后,让咱们用个具体例子来进行阐明。
咱们来作一个基于AVFoundation二维码识别应用:QRCatcher
项目架构:
|- Model |- URLEntity |- View |- QRURLTableViewCell |- QRTabBar |- Controller |- QRCatchViewController |- QRURLViewController |- Tools |- NSString+Tools |- NSObject+Macro
项目并不复杂。典型的MVC架构.
Model层只有一个URLEntity用于存储捕捉到的URL信息。 此次项目也顺便学习了一下CoreData。感受良好,配合NSFetchedResultsController工做很幸福。
View层则是一个TableViewCell和Tabbar,继承Tabbar主要用于改变tabbar高度。
Controller层中QRCatchViewController负责捕捉与存储二维码信息, QRURLViewController负责展现与管理收集到的URL信息。
Tools则是一些辅助方便开发的类。出自我本身平时使用收集编写维护的一个工具库 (开源连接)在这个项目中主要用以检查URL是否合法,判断设备类型等。
介绍完基本的架构后,咱们把精力放回AVFoundation模块上来。在这个项目中, AVFoundation主要负责二维码的扫描与解析。
咱们直接来看QRCatchViewController中涉及的代码。
对于咱们这个应用来讲,只需两步核心步骤便可。
1.设置AVFoundation
- (void)setupAVFoundation { //session self.session = [[AVCaptureSession alloc] init]; //device AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; NSError *error = nil; //input AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; if(input) { [self.session addInput:input]; } else { NSLog(@"%@", error); return; } //output AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; [self.session addOutput:output]; [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; //add preview layer self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session]; [self.preview.layer addSublayer:self.previewLayer]; //start [self.session startRunning]; }
在这里咱们能够看到和上面建立捕捉视频流的步骤基本是一致的。
也就是
建立session
建立device
建立input
建立output。
这里是与捕捉视频流所不一致的地方。咱们捕捉视频流须要的是AVCaptureVideoDataOutput,而在这里咱们须要捕捉的是二维码信息。所以咱们须要AVCaptureMetadataOutput。而且咱们须要指定捕捉的metadataObject类型。在这里咱们指定的是AVMetadataObjectTypeQRCode,咱们还能够指定其余类型,例如PDF417条码类型。
完整的可指定列表能够在这里找到。
而后咱们还要指定处理这些信息的delegate与队列。
开始录制
2.实现代理方法:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { for (AVMetadataMachineReadableCodeObject *metadata in metadataObjects) { if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) { self.borderView.hidden = NO; if ([metadata.stringValue isURL]) { [[UIApplication sharedApplication] openURL:[NSString HTTPURLFromString:metadata.stringValue]]; [self insertURLEntityWithURL:metadata.stringValue]; self.stringLabel.text = metadata.stringValue; } else { self.stringLabel.text = metadata.stringValue; } } } }
咱们须要在代理方法里面接收数据,并根据本身的需求进行处理。在这里我简单地进行了URL的测试,若是是的话则打开safari进行浏览。
总结
在这里仅仅是经过一个二维码的应用来展现AVFoundation处理视频流能力。事实上,AVFoundation可以作得更多。可以进行剪辑,处理音轨等功能。若是咱们须要对视频与音频相关的事务进行处理,不妨在着手处理,寻找第三方解决方案前,看看这个苹果公司为咱们带来的强大模块。