玩转iOS开发:使用AVFoundation实现扫码
2016-07-30 00:05
435 查看
目录
简介作者感言
初识AVFoundation框架
创建AVCaptureDevice
创建AVCaptureDeviceInput
创建AVCaptureOutput
设置代理
补充一丢丢知识点
开始演示
CALScanQCode使用方法
继承
获取数据
扫码类型
调整摄像头焦点
总结
GitHub地址
简介
在iOS7当中, Apple就已经在
AVFoundation当中加入对扫码的支持, 大家从此就可以和
ZXing说拜拜了, 也感谢
ZXing长期以来为我们提供扫码的功能.
作者感言
如果你有更好的建议或者对这篇文章有不满的地方, 请联系我, 我会参考你们的意见再进行修改, 联系我时, 请备注AVFoundation实现扫码,
最后:
祝大家学习愉快~谢谢~
Cain(罗家辉)
联系方式: zhebushimengfei@qq.com
腾讯QQ: 350116542
初识AVFoundation框架
首先我们从整体对所需框架做个初步了解。AVFoundation在相关框架栈中的的位置:
为了捕捉视频,我们需要这样几种类(与其它的子类)。
AVCaptureDevice代表了输入设备,例如摄像头与麦克风。
AVCaptureInput代表了输入数据源
AVCaptureOutput代表了输出数据源
AVCaptureSession用于协调输入与输出之间的数据流
并且还有
AVCaptureVideoPreviewLayer提供摄像头的预览功能
可以用这样一幅图来概述:
实际应用
AVFoundation来捕捉视频流并不复杂。
我们用代码简单地描述用
AVFoundation捕捉视频的过程,其他捕捉音频,静态图像的过程也是大同小异的。
创建
AVCaputureSession, 作为协调输入与输出的中心,我们第一步需要创建一个
Session
AVCaptureSession *session = [[AVCaptureSession alloc] init];
创建AVCaptureDevice
创建一个AVCaptureDevice代表代表输入设备, 在这里我们制定设备用于摄像。
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
创建AVCaptureDeviceInput
创建AVCaptureDeviceInput, 并添加到
Session中, 我们需要使用
AVCaptureDeviceInput来让设备添加到session中,
AVCaptureDeviceInput负责管理设备端口。我们可以理解它为设备的抽象。一个设备可能可以同时提供视频和音频的捕捉。我们可以分别用
AVCaptureDeviceInput来代表视频输入和音频输入。
NSError *error; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; [session addInput:input];
创建AVCaptureOutput
为了从session中取得数据,我们需要创建一个AVCaptureOutput
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc]init];
设置代理
设置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:
开始捕捉
[session startRunning];
通过上面的简单例子,我么可以看出使用
AVFoundation来捕捉视频流并不是十分复杂。重点是使用的过程需要了解配置的细节,还有性能问题。
补充一丢丢知识点
学习基础知识过后,让我们用个具体例子来进行阐明。在这里我们可以看到和上面创建捕捉视频流的步骤基本是一致的。
创建
session
创建
device
创建
input
创建
output
这里是与捕捉视频流所不一致的地方。我们捕捉视频流需要的是
AVCaptureVideoDataOutput, 而在这里我们需要捕捉的是二维码信息。因此我们需要
AVCaptureMetadataOutput。并且我们需要指定捕捉的
metadataObject类型。在这里我们指定的是
AVMetadataObjectTypeQRCode, 我们还可以指定其他类型, 例如
PDF417条码类型, 完整的可指定列表可以在这里找到。
然后我们还要指定处理这些信息的
delegate与队列。
开始录制
开始演示
讲了那么多废话, 现在我们要正式去设置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]; }
设置完成之后, 我们要去实现代理方法, 这样子才能实现我们要的功能
- (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进行浏览。
CALScanQCode使用方法
继承
首先我提供的是Controller, 所以如果需要使用, 直接继承于我这个
Controller就可以了:
#import "CALScanQRCodeViewController.h" @interface CALScanQRCodeExampleViewController : CALScanQRCodeViewController @end
获取数据
在Controller当中, 我提供了两个
Block函数, 用来获取纯字符串数据和整个扫码数组的数据, 前提当然是要继承与
CALScanQRCodeViewController才可以这么写:
[self setCALScanQRCodeGetMetadataStringValue:^(NSString *stringValue) {
NSLog(@"Scan Straing Value = %@", stringValue); }]; [self setCALScanQRCodeGetMetadataObjectsBlock:^(NSArray *array) { NSLog(@"Scan array = %@", array); }];
扫码类型
支持的条码类型都是使用Apple系统所提供的, 详情可以去这里查找:
AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode, AVMetadataObjectTypeInterleaved2of5Code, AVMetadataObjectTypeITF14Code, AVMetadataObjectTypeDataMatrixCode
调整摄像头焦点
如果你需要更改摄像头的对焦Y轴, 你可以在项目中找到以下的代码, 把它的
Y轴设置成你要偏移的位置就可以了.
// _captureMetadataOutPut.rectOfInterest = CGRectMake(0, 0, CALScreenWidth, CALScreenHeight); _captureMetadataOutPut.rectOfInterest = CGRectMake(0, -20, CALScreenWidth, CALScreenHeight);
总结
在这里仅仅是通过一个二维码的应用来展示AVFoundation处理视频流能力。事实上,
AVFoundation能够做得更多。能够进行剪辑, 处理音轨等功能。如果我们需要对视频与音频相关的事务进行处理, 不妨在着手处理, 寻找第三方解决方案前,看看这个苹果公司为我们带来的强大模块。
GitHub地址
工程地址: https://github.com/CainRun/CALScanQRCode相关文章推荐
- Objective-C ,ios,iphone开发基础:picker控件详解与使用,(实现省市的二级联动)
- (转)在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送
- IOS开发之使用Speex格式实现简单的语音聊天功能(一)
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- Objective-C ,ios,iphone开发基础:picker控件详解与使用,(实现省市的二级联动)
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录
- IOS应用开发14——使用UICollectionView实现图片列表显示
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录
- 从今天开始学习iOS开发(iOS 7版)--实现一款App之Foundation框架的使用
- 从今天开始学习iOS开发(iOS 7版)--实现一款App之使用设计模式
- IOS开发之使用Speex格式实现简单的语音聊天功能(二)
- iOS 开发 高级:通过AirServer使用AirPlay镜像并实现多屏幕显示控制
- Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- iOS开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- 在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送
- (视频)玩转Membership视频之二:使用系列“登录控件”实现高效开发
- iOS开发之使用XMPPFramework实现即时通信(二)