需求:需要采集到视频帧数据从而可以进行一系列处理(如: 裁剪,旋转,美颜,特效....). 所以,必须采集到视频帧数据.
阅读前提:
-
使用AVFoundation框架
-
采集音视频帧数据
Overview
AVCaptureSession:使用相机或麦克风实时采集音视频数据流.
-
AVCaptureSession : 管理输入输出音视频流
-
AVCaptureDevice : 相机硬件的接口,用于控制硬件特性,诸如镜头的位置(前后摄像头)、曝光、闪光灯等。
-
AVCaptureInput : 配置输入设备,提供来自设备的数据
-
AVCaptureOutput : 管理输出的结果(音视频数据流)
-
AVCaptureConnection: 表示输入与输出的连接
-
AVCaptureVideoPreviewLayer: 显示当前相机正在采集的状况
一个session可以配置多个输入输出

下图展示了向session中添加输入输出后的连接情况

授权
首先需要在Info.plist文件中添加键Privacy - Camera Usage Description以请求相机权限.
注意: 如果不添加,程序crash,如果用户不给权限,则会显示全黑的相机画面.
1. 使用Capture Session管理数据流
AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Add inputs and outputs.
[session startRunning];
1.1. 使用preset配置分辨率,帧率
-
canSetSessionPreset:检查是否支持指定分辨率
-
setActiveVideoMinFrameDuration: 设置帧率最小值
-
setActiveVideoMaxFrameDuration: 设置帧率最大值
CMTimeMake: 分子为1,即每秒钟来多少帧.
-
在低帧率下(帧率<=30)可以用如下方式设置
- (void)setCameraResolutionByPresetWithHeight:(int)height session:(AVCaptureSession *)session {
[session beginConfiguration];
session.sessionPreset = preset;
[session commitConfiguration];
}
- (void)setCameraForLFRWithFrameRate:(int)frameRate {
// Only for frame rate <= 30
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[captureDevice lockForConfiguration:NULL];
[captureDevice setActiveVideoMinFrameDuration:CMTimeMake(1, frameRate)];
[captureDevice setActiveVideoMaxFrameDuration:CMTimeMake(1, frameRate)];
[captureDevice unlockForConfiguration];
}
-
高帧率下设置分辨率(帧率>30)
如果需要对某一分辨率支持高帧率的设置,如50帧,60帧,120帧...,原先setActiveVideoMinFrameDuration与setActiveVideoMaxFrameDuration是无法做到的,Apple规定我们需要使用新的方法设置帧率setActiveVideoMinFrameDuration与setActiveVideoMaxFrameDuration,并且该方法必须配合新的设置分辨率activeFormat的方法一起使用.
新的设置分辨率的方法activeFormat与sessionPreset是互斥的,如果使用了一个, 另一个会失效,建议直接使用高帧率的设置方法,废弃低帧率下设置方法,避免产生兼容问题。
Apple在更新方法后将原先分离的分辨率与帧率的设置方法合二为一,原先是单独设置相机分辨率与帧率,而现在则需要一起设置,即每个分辨率有其对应支持的帧率范围,每个帧率也有其支持的分辨率,需要我们遍历来查询,所以原先统一的单独的设置分辨率与帧率的方法在高帧率模式下相当于弃用,可以根据项目需求选择,如果确定项目不会支持高帧率(fps>30),可以使用以前的方法,简单且有效.
注意: 使用
activeFormat方法后,之前使用sessionPreset方法设置的分辨率将自动变为AVCaptureSessionPresetInputPriority,所以如果项目之前有用canSetSessionPreset比较的if语句也都将失效,建议如果项目必须支持高帧率则彻底启用sessionPreset方法.
具体设置方法参考另一篇文章:iOS相机设置实战
注意: 在将session配置为使用用于高分辨率静态拍摄的活动格式并将以下一个或多个操作应用于AVCaptureVideoDataOutput时,系统可能无法满足目标帧速率:缩放,方向更改,格式转换。
【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~
![]()
1.2. 更改相机设置
如果你需要在开启相机后进一步调节相机参数,在beginConfiguration和commitConfiguration中写入更改的代码.调用beginConfiguration后可以添加移除输入输出,更改分辨率,配置个别的输入输出属性,直到调用commitConfiguration所有的更改才会生效.
[session beginConfiguration];
// Remove an existing capture device.
// Add a new capture device.
// Reset the preset.
[session commitConfiguration];
1.3. 监听Session状态
可以使用通知监听相机当前状态,如开始,停止,意外中断等等...
-
监听掉帧
- (void)captureOutput:(AVCaptureOutput *)output didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
-
处理相机运行中突然出错

本文详细介绍了在iOS中使用AVFoundation框架的AVCaptureSession进行视频流采集,包括管理输入输出流、配置Capture Session、使用AVCaptureDevice、Capture Inputs和Outputs,以及展示预览图的过程。同时,讨论了高帧率视频采集、设备设置、权限处理和预览图显示的相关细节。

3335

被折叠的 条评论
为什么被折叠?



