-
视频采集:
iOS
平台基于
AVCaptureDevice
的实现
入门知识
AVCaptureSession
在
iOS
平台开发中只要跟硬件相关的都要从会话开始进行配置
,
如果我们使用摄
像头的话可以利用
A
VCaptureSession
进行视频采集,其可以对输入和输出数据
进行管理,负责协调从哪里采集数据,输出到哪里去。
AVCaptureDevice
一
个
AVCaptureDevice
对应的是一个物理采集设备
,
我们可以通过该对象来获取
和识别设备属性。
例如通过
on
检测其摄像头
的方向。
AVCaptureInput
AV
CaptureInput
是一个抽象类,
AVCapture
Session
的输入端必须是
AVCaptureInput
的实现类。
例如利用
AVCaptureDevice
构建
AVCaptu
reDeviceInput
作为采集设备输入端。
AVCaptureOutput
A
VCaptureOutput
是一个抽象类,
AVCaptu
reSession
的输出端必须是
AVCaptureOut
put
的实现类。
例如
AVCaptureVideoDataOutput
可以作为一个原始视频
数据的输出端。
AVCaptureConnection
< br>AVCaptureConnection
是
AVCap
tureSession
用来建立和维护
AVCaptureI
nput
和
AVCaptureOutput
< br>之间的连接的,一个
AVCaptureSession
可能会有多个
AVCaptureConnection
实例。
采集步骤
1.
创建
A
VCaptureSession
并初始化。
2.
通过前后置摄像头找到对应的<
/p>
AVCaptureDevice
。
3.
通过
A
VCaptureDevice
创建输入端
AVCapture
DeviceInput
,并将其添加
到
AVCaptureSession
的输入端。
4.
创建输出端
AVCaptureVideoDataOutput
,
并
进行
Format
和
Delgate<
/p>
的配
置,最后添加到
AVCapture
Session
的输出端。
5.
获取
A
VCaptureConnection
,并进行相应的参数设置。
6.
调用
AVCaptureSession
的
startRunn
ing
和
stopRunning
设置
采集状态。
配置会话
创建一个
AVCaptureSession
很简单
:
AVCaptureSession
*captureSession;
captureSession =
[[AVCaptureSession alloc] init];
我们可以在<
/p>
AVCaptureSession
来配置指定所需的图像质量和
分辨率,可选参数
请参考
AVCaptureSessionP
reset.h
。
在设置前需要检测
是否支持该
Preset
是否被支持:
//
指定采集
1280x720
分辨率大小格式
AVCaptureSessionPreset preset =
AVCaptureSessionPreset1280x720;
//
检查
AVCaptureSession
是否支持
该
AVCaptureSessionPreset
if
([captureSession canSetSessionPreset:preset]) {
nPreset = preset;
}
else {
//
错误处理
,不支持该
AVCaptureSessionPreset
类
型值
}
配置输入端
通过
AVCaptureDevice
的
devicesWit
hMediaType
的方法来获取摄像头,
由于
iOS
存在多个摄像头,所以这里一般返回一个设备的数组。
根据业务需要
(
例如前后置
摄像头
)
,我们找到其中对应的
AVC
aptureDevice
,并
将其构造成
AVCaptureDeviceInput
实例。
AVCaptureDevice *device;
AVCaptureDeviceInput *captureInput;
//
获取前后置摄像头的标识
AVCaptureDevicePosition position =
_isFront ?
AVCaptureDevicePositionFront
: AVCaptureDevicePositionBack;
//
获取设备的
AVCaptureDevice
列表<
/p>
NSArray *devices =
[AVCaptureDevice
devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *item in devices)
{
//
如果找到对应的摄像头
if ([item position] == position) {
device = item;
break;
}
}
if
(device == nil) {
//
错误处理,没有找到对应的摄像头
}
//
创建
AVCaptureDeviceInput
输入端
captureInput = [[AVCaptureDeviceInput
alloc] initWithDevice:device
error:nil];
配置输出端
如果我们想要获取到摄像头采集到的原始视频数据的话,需要配置一个
< br>AVCaptureVideoDataOutput
作为
AVCaptureSession
的输出端,
我们需要给其
设
置采集的视频格式和采集数据回调队列。
AVCaptureVideoDataOutput
*captureOutput;
//
创建一个输出端
AVCaptureVideoDataOutput
实例
captureOutput =
[[AVCaptureVideoDataOutput new];
//
配置输出的数据格式
[captureOutput
setVideoSetti
ngs:@{(id)kCVPixelBufferPixelFormatTypeKey:
@(kCVPixelFormatType_420YpCbCr8PlanarFullRang
e)}];
//
设置输出代理和采集数据的队列
dispatch_queue_t outputQueue =
< br>dispatch_queue_create(
DISPATCH_QUEUE
_SERIAL);
[captureOutput
setSampleBufferDelegate:self queue:outputQueue];
//
丢弃延迟的帧
DiscardsLateVideoFrames = YES;
需要注意的几个点
对于
setVideoSettings
,
虽然
AVCaptureVideoDataOutput
提供的是一个
p>
字典设置,
但是现在只支持
kCVPixe
lBufferPixelFormatTypeKey
这个
k
ey
。
?
像素格式默认使用的是
YUVFullRange
类型,
表示其
YUV
取值范
围是
0~255
,
而还有另外一种类型
YUVVideoRange
类型则是为了防止溢出,
将
YUV
的取
值范围限
制为
16~235
。
?
setSampleBuffer
Delegate
必须指定串行队列来确保视频数据获取委托
调
用的正确顺序,当然你也可以修改队列来设置视频处理的优先级别。
?