在目前iOS的技术栈里面,视频流一直是比较主流的一个学习方向,今天,在这写上一些上周在AVFoundation框架下,所学所讲的。数组
咱们在理解AVFoundation 这个框架的时候,要学会 Apple 对这个框架有什么做用:bash
照片/视频的捕捉 小视频/直播session
AVCaptureSession 设备捕捉会话框架
AVCaptureDevice 捕捉设备异步
AVCaptureDeviceInput 捕捉设备输入async
AVCaptureFileOutput (一个抽象类) 多类型音频文件ide
捕捉链接 AVCaptureConnection 创建输入输出的链接学习
AVCaptureVideoPreviewLayer 渲染捕捉涂层 预览内容ui
##干货 直接上代码 写注释spa
//初始化 AVCaptureSession 对象
self.captureSession = [[AVCaptureSession alloc] init];
//设置高分辨率 其余参数 请查看 sessionPreset 内的设置
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
// 获取到设备 MediaType 表明的是获取设备的哪一种类型
AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//输入设备 将设备转化为 AVCaptureDeviceInput
AVCaptureDeviceInput * videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
if (videoDevice) {
//判断是否有效
if ([self.captureSession canAddInput:videoDeviceInput]) {
[self.captureSession addInput:videoDeviceInput];
}
}
// 获取设备的音频输出处理装置
AVCaptureDevice * audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput * audiodeViceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
if (audiodeViceInput) {
if ([self.captureSession canAddInput:audiodeViceInput]) {
[self.captureSession addInput:audiodeViceInput];
}
}
//静态图片输出对象的初始化
self.imageOutput = [[AVCaptureStillImageOutput alloc]init];
//设置 视屏的格式 JPEG
self.imageOutput.outputSettings = @{AVVideoCodecKey:AVVideoCodecTypeJPEG};
if ([self.captureSession canAddOutput:self.imageOutput]) {
[self.captureSession canAddOutput:self.imageOutput];
}
//建立一个文件
self.movieOutPut = [[AVCaptureMovieFileOutput alloc] init];
if ([self.captureSession canAddOutput:self.movieOutPut]) {
[self.captureSession addOutput:self.movieOutPut];
}
self.videoQuect = dispatch_queue_create("jz.videoqueue", NULL);
复制代码
做为捕捉音视频的链接者,咱们能对视频的状态作出处理 以及切换
例如:
self.captureSession isRunning // 判断的就是当前的session 是不是在运行中
我的建议同步调用会损耗必定的时间,则用异步的方式处理
dispatch_async(self.videoQueue, ^{
[self.captureSession stopRunning];
});
// 同道理 开始的时候 可检测
if (![self.captureSession isRunning])
{
dispatch_async(self.videoQueue, ^{
[self.captureSession startRunning];
});
}
复制代码
// 判断设备 是否拥有物理设备
<!-- NSArray * devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
获取当前设备的数组设备 而后进行判断
for (AVCaptureDevice *device in devices)
{
if (device.position == position) {
return device; //获取到我当前的 position 而后返回设备
}
}
-->
// 判断设备 当前的物理设备数
//获取当前视频捕捉设备的数量
NSInteger deviceCount = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
// 获取当前的活跃设备
self.videoDeviceInput.device
// 获取当前先后置摄像头的处理
AVCaptureDevice *device = nil;
if(deviceCount > 1)
{
//返回获取到逆向切换的物理设备
if (self.videoDeviceInput.device.position == AVCaptureDevicePositionBack)
{
//AVCaptureDevicePositionFront 后置摄像头
}
else
{
//AVCaptureDevicePositionBack 前置摄像头
}
}
复制代码
// 生成当前的输入源 videoDevice 是你当前的切换的设备信息
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
//判断videoInput 是否为nil
if (videoInput)
{
//标注原配置变化开始
[self.captureSession beginConfiguration];
//将捕捉会话中,本来的捕捉输入设备移除
[self.captureSession removeInput:self.activeVideoInput];
//判断新的设备是否能加入
if ([self.captureSession canAddInput:videoInput])
{
//能加入成功,则将videoInput 做为新的视频捕捉设备
[self.captureSession addInput:videoInput];
//将得到设备 改成 videoInput
self.activeVideoInput = videoInput;
}else
{
//若是新设备,没法加入。则将本来的视频捕捉设备从新加入到捕捉会话中
[self.captureSession addInput:self.activeVideoInput];
}
//配置完成后, AVCaptureSession commitConfiguration 会分批的将全部变动整合在一块儿。
[self.captureSession commitConfiguration];
}
else
{
//建立input设备出错 的处理机制
}
复制代码