文章

音视频拍摄组件

介绍音视频拍摄组件的架构和模块设计思路。

音视频拍摄组件

本文转自微信公众号 关键帧Keyframe,推荐您关注来获取音视频、AI 领域的最新技术和产品信息

微信公众号 微信扫码关注我们

您还可以加入知识星球 关键帧的音视频开发圈 来一起交流工作中的技术难题、职场经验

知识星球 微信扫码加入星球

1、音视频拍摄组件框架:

音视频拍摄组件的采集模块包括了图像采集音频采集,采集后还可能进行图像前处理声音前处理,随后提供的能力包括预览渲染拍照录制

这里的前处理通常包括图像的滤镜特效降噪锐化等,声音的降噪回声消除等。

2、实战解析

2.1、iOS 平台的拍摄基础能力

iOS 拍摄框架主要包括几个主要部分:拍摄会话、输入、输出。

当进行音视频采集时,我们使用 AVCaptureSession 来组装各路数据。

2.2、相机拍摄参数

相机拍摄相关的参数通常有:

  • 帧率:在实际应用场景,短视频通常选择帧率为 30fps,直播一般选择帧率为 15fps。
  • 分辨率:高端机可配置 1080P(1080×1920),低端机可设置为 720P(720×1280) 或者 540P(540×960)。
  • 视频图像输出格式:可选择 BGRA 或 YUV420,但最好设置为 YUV420,这样可以大大降低内存占用,底层会有 CVPixelBuffer 队列,大约为 13 帧左右,以 720P(720×1280) 为例,可节约 13 * (BGRA:3.5M - NV12:1.5M) = 26M
  • 缩放大小:调节焦距。
  • 镜像设置:直播模式下通常本地应用镜像,观看端主播可以配置是否镜像。

2.3、AudioUnit 音频采集

AudioUnit 音频采集、可用于回声消除等更强大特性。

2.4、AUGraph 音频处理

AUGraph 可以连接一组 AudioUnit 之间的输入和输出,构成一张图,同时也为 AudioUnit 的输入提供了回调。AUGraph 抽象了音频流的处理过程,子结构可以作为一个 AUNode 嵌入到更大的结构里面进行处理。AUGraph 可以遍历整个图的信息,每个节点都是一个或者多个 AUNode,音频数据在点与点之间流通,并且每个图都有一个输出节点。输出节点可以用来启动、停止整个处理过程。混音则是将 MixUnitOutputUnit 连接在一起即可。

2.5、对焦策略

相机的对焦策略首先是要支持『手动对焦』,即用户点击哪里就对焦哪里。

同时也要支持『自动对焦』,即基于系统能力在识别场景发生变化后,进行一次中心对焦;如果有识别到画面从无人脸到有人脸时,做一次人脸对焦(这里是只做一次人脸对焦,不能一直跟着人脸对焦,这样可以防止用户不想对焦人脸的场景:在有人脸时,点击了其他地方进行手动对焦)。

手动对焦后,在满足这些条件时会切换到自动对焦:

  • 前后摄像头切换。
  • 场景发生较大切换。比如,相机位移或晃动加大,外部光线敏感度变化较大等。
  • 画面中从无人脸变为有人脸。

2.6、线程模型

把采集和视频特效放在同一个线程,随着特效功能越来越强,计算越来越重,会影响到最终的输出帧率。要优化可以改为多线程加上 buffer 控制的线程模型。相机采集模块可以使用 3 线程模型:

  • 采集线程:使用系统相机能力实现图像采集。
  • CPU 处理线程:跑一些 AI 模型。
  • GPU 处理线程:跑一些图像处理。

3、问题集锦

1、在拍照、拍视频、直播等多种模式下共享相机预览画面并支持切换时,由于不同模式需要设置的帧率不一样(比如拍视频用 30fps,直播用 15fps),切换时可能会发生卡顿的问题,怎么优化?

在预览时可以统一使用 30fps,这样在切换 Tab 时则不会因为设置不同的帧率而造成卡顿。当切到直播 Tab 下,只有当主播点击开始直播时才切到 15fps。

2、直播模式下实时人脸对焦的重要性?以及如何实现?

通常直播时长比较长,一直手动对焦不太现实,自动对焦模式通常会脸部反光,所以可以通过人脸对焦模式来避免这种情况。在 iOS 平台可以根据 MetaDataObjectTypes 添加 AVMetadataObjectTypeFace,拿到每一帧人脸矩形框的位置并对焦矩形框中心,这样人脸进行移动后灯光也会及时调整。

3、采集线程如何优化?

音视频采集线程最好拆分为 2 个线程进行处理,这样可以避免主线程卡顿,会更加流畅,但释放情况下最好异步关闭相机,可以通过全局线程捕获 AVCaptureSession 对象,进行 StopRunning 操作,否则非常容易触发卡顿发生。

4、相机首帧如何优化?

可以从业务层进行处理,优先将 CPU 资源让给相机,相机打开后回调给业务首帧已出的事件,这样业务收到该事件后再进行其它初始化,体验会得到很大提升。

5、相机如何共享?

部分业务连续多个 Tab 可能都需要打开相机,如果每次切换 Tab 都关闭再打开相机则会闪一下,体验不好。这时候,架构可以设计为相机与渲染视图抽象为单独的模块,多个页面创建多个渲染视图,但仅有一个相机实例,通过传递 Capture 实例进行共享,到新页面输出 delegate 更新到当前渲染视图即可。

6、采集性能优化有哪些需要注意的地方?

可以注意下列几点:

  • 1)采集和前处理(AI 模型、图像处理、特效等)模块交互时,注意下采样不仅要对齐分辨率,还要对齐下采样的方式。
  • 2)GPU 和 CPU 要尽量少做数据拷贝,性能比较差。Android 可以使用系统能力来实现 GPU 和 CPU 的内存共享来做相关的优化。
  • 3)做图像的裁剪、缩放、尺寸变化时要注意优化性能。
本文由作者按照 CC BY-NC-ND 4.0 进行授权