• iOS视频流采集概述(AVCaptureSession)


    需求:需要采集到视频帧数据从而可以进行一系列处理(如: 裁剪,旋转,美颜,特效....). 所以,必须采集到视频帧数据.

    阅读前提:

    • 使用AVFoundation框架

    • 采集音视频帧数据

    Overview

    AVCaptureSession:使用相机或麦克风实时采集音视频数据流.

    • AVCaptureSession : 管理输入输出音视频流

    • AVCaptureDevice : 相机硬件的接口,用于控制硬件特性,诸如镜头的位置(前后摄像头)、曝光、闪光灯等。

    • AVCaptureInput : 配置输入设备,提供来自设备的数据

    • AVCaptureOutput : 管理输出的结果(音视频数据流)

    • AVCaptureConnection: 表示输入与输出的连接

    • AVCaptureVideoPreviewLayer: 显示当前相机正在采集的状况

    一个session可以配置多个输入输出

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

    授权

    首先需要在Info.plist文件中添加键Privacy - Camera Usage Description以请求相机权限.

    注意: 如果不添加,程序crash,如果用户不给权限,则会显示全黑的相机画面.

    1. 使用Capture Session管理数据流

    1. AVCaptureSession *session = [[AVCaptureSession alloc] init];
    2. // Add inputs and outputs.
    3. [session startRunning];
    1.1. 使用preset配置分辨率,帧率
    • canSetSessionPreset:检查是否支持指定分辨率

    • setActiveVideoMinFrameDuration: 设置帧率最小值

    • setActiveVideoMaxFrameDuration: 设置帧率最大值

    CMTimeMake: 分子为1,即每秒钟来多少帧.

    • 在低帧率下(帧率<=30)可以用如下方式设置

    1. - (void)setCameraResolutionByPresetWithHeight:(int)height session:(AVCaptureSession *)session {
    2.   [session beginConfiguration];
    3.   session.sessionPreset = preset;
    4.   [session commitConfiguration];
    5. }
    6. - (void)setCameraForLFRWithFrameRate:(int)frameRate {
    7.   // Only for frame rate <= 30
    8.   AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    9.   [captureDevice lockForConfiguration:NULL];
    10.   [captureDevice setActiveVideoMinFrameDuration:CMTimeMake(1, frameRate)];
    11.   [captureDevice setActiveVideoMaxFrameDuration:CMTimeMake(1, frameRate)];
    12.   [captureDevice unlockForConfiguration];
    13. }
    • 高帧率下设置分辨率(帧率>30)

    如果需要对某一分辨率支持高帧率的设置,如50帧,60帧,120帧...,原先setActiveVideoMinFrameDurationsetActiveVideoMaxFrameDuration是无法做到的,Apple规定我们需要使用新的方法设置帧率setActiveVideoMinFrameDurationsetActiveVideoMaxFrameDuration,并且该方法必须配合新的设置分辨率activeFormat的方法一起使用.

    新的设置分辨率的方法activeFormatsessionPreset是互斥的,如果使用了一个, 另一个会失效,建议直接使用高帧率的设置方法,废弃低帧率下设置方法,避免产生兼容问题。

    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. 更改相机设置

    如果你需要在开启相机后进一步调节相机参数,在beginConfigurationcommitConfiguration中写入更改的代码.调用beginConfiguration后可以添加移除输入输出,更改分辨率,配置个别的输入输出属性,直到调用commitConfiguration所有的更改才会生效.

    1. [session beginConfiguration];
    2. // Remove an existing capture device.
    3. // Add a new capture device.
    4. // Reset the preset.
    5. [session commitConfiguration];

    1.3. 监听Session状态

    可以使用通知监听相机当前状态,如开始,停止,意外中断等等...

    • 监听掉帧

    - (void)captureOutput:(AVCaptureOutput *)output didDropSa
  • 相关阅读:
    [LeetCode] 1.两数之和
    ChatGPT的前世今生:从概念到现实的AI之旅
    经验之谈:内存泄露的原因以及分析
    Asp.Net Core服务端处理请求过来的压缩格式
    外包干了2个月,感觉技术明显退步...
    Ubuntu20.4搭建基于iRedMail的邮件服务器
    多核处理器
    list的模拟实现(万字解读+由浅入深)
    【马士兵】Python基础--04
    Easy3D文章目录汇总
  • 原文地址:https://blog.csdn.net/irainsa/article/details/128210186