这个公众号会路线图式的遍历分享音视频技术:音视频基础(完成) → 音视频工具(完成) → 音视频工程示例(完成) → 音视频工业实战(进行中)。关注一下成本不高,错过干货损失不小 ↓↓↓
这篇文章是音视频工业实战主题专栏的第一篇,我们就从音视频生产侧开始,来先粗略的介绍一下音视频生产相关的大体框架和模块。
话不多说,直接上图:
在上图中,我们把音视频生产的框架划分成了 3 层:
生产组件层,是对接和支持音视频生产业务层的各种组件。 生产内核层,是支持各生产组件的可复用的基础模块集。 底层能力层,是对生产内核层各能力的垂直扩展,用于扩展支持更强大的底层能力。
其中,音/视频采集
、音/视频前处理
、特效
、预览渲染
等模块一般会在拍照、录制视频、直播推流等场景被组装起来使用。
在音/视频前处理
、特效
模块中一般也会结合端侧智能
模块提供比如人脸识别、背景分割、人像美化等丰富的能力。
在音视频采集之后,则需要使用音/视频编解码
和音/视频封装
模块对采集到的数据编码(转码)和封装为指定媒体格式的文件。在对音视频进行编解码时,我们可以选择硬件编解码器,也可以集成和使用软编解码器
模块来优化编解码质量和性能,支持更多的特性。
在完成音视频编码和封装后,对于直播则使用音视频推流
模块来推流到服务端,对于视频则使用音视频上传
模块来上传视频到服务端。有时,为了提供更好的推流或上传性能,我们还可以自研传输协议
模块来进行优化。
以上便是常见的音视频生产框架的分层和模块介绍。接下来我们继续介绍生产组件层各种组件的常见框架和模块设计。
1、音视频拍摄组件框架
音视频拍摄组件的采集模块包括了图像采集
和音频采集
,采集后还可能进行图像前处理
和声音前处理
,随后提供的能力包括预览渲染
、拍照
和录制
。
这里的前处理通常包括图像的滤镜
、特效
、降噪
、锐化
等,声音的降噪
、回声消除
等。
2、音视频编辑组件框架
音视频编辑组件在最上层提供几个大的功能模块:抽帧
、预览播放器
和导出
。
抽帧
模块主要支持各种场景下的视频截图展示,常见的如视频缩略图展示。
预览播放器
模块主要支持编辑过程中的视频预览,不仅仅包括视频的预览,还包括叠加在视频上的各种滤镜、特效、贴纸等素材的渲染。
导出
模块主要支持对编辑后的视频进行导出,当然也包括叠加在视频上的各种滤镜、特效、贴纸等素材。
支撑以上几个功能模块的底层基础模块有很多,包括:Composition/Track/Segment
等基础数据结构;还有编/解码
、Muxer/Demuxer
、Mixer
、特效
等模块,以及基于它们支持的用于资源读写的AssetReader/Writer
模块等。
3、音视频上传组件框架
音视频上传组件主要服务于音视频文件的上传。
当我们仅从文件角度去看音视频时,那么适用于其他文件类型的普通文件上传
和大文件分片上传
和秒传
自然也适用于音视频文件。其中,普通文件上传
适用于较小的文件;大文件分片上传
可以用于较大的文件,对大文件进行切片后再上传可以在某个分片上传失败时仅对该分片进行重传从而提高效率,同时也可以尝试对不同的分片进行并行上传来提高效率;秒传
则是通过计算待上传文件数据的 Hash 值(常用 MD5、CRC 等算法)与服务端已有文件集的 Hash 值集合进行比对,对已有文件不进行实际上传只进行存储拷贝,这样也能提高上传效率。
如果进一步结合音视频格式的特性去理解音视频文件时,我们还可以采用流式上传
的方式来上传音视频文件。流式上传
是指将视频切割成独立的切片(FMP4、TS 等支持独立转码的可分片格式),按流水线的方式上传。所谓的流水线,即对于上传客户端,切好一个分片就上传一个分片,并且只要第一个分片上传成功后,就可以拿到服务端存储服务返回的视频地址,完成业务数据提交;对于服务端,收到一个分片就可以对这个分片进行转码,不必等一个视频的全部数据完全上传完成。这样也提高了上传效率。
4、直播推流器组件框架
直播推流器组件包括了采集
、前处理
、编码
、发送控制
、封装
和传输
等模块,这些模块组装成了一个推流的 Pipeline。
采集
、前处理
模块主要是依赖上面介绍的音视频拍摄组件
提供的能力来实现音视频的采集和前处理。
编码
模块则接收采集和前处理后的音视频数据(PCM、RGB/YUV),对其进行编码(AAC、H.264/H.265)。
封装
模块则将编码后的音视频数据(AAC、H.264/H.265)封装成 FLV 格式。
传输
模块则根据情况使用不同的传输协议(RTMP/KCP/RTP)将封装好的 FLV 数据发送给服务端。
为了能够适应网络情况,在直播推流组件中我们还会增加一个发送控制
模块来结合传输
模块的数据发送情况来进行网络评估从而控制缓冲区的数据量以及数据发送的速度。
小结
以上便是音视频生产相关的大体框架以及常用功能组件和模块的介绍。在实战中,不同的实现方案可能会有架构上的差异,但大体上应该差不多。对于不同功能组件和模块的实现细节,我们会在后面的文章中继续探讨。