前言
这篇文章简单聊聊我对音视频技术栈的理解,方便入门的同学做个参考。可以规划一下自己的学习路线。
话不多说先上一张 XMind 截图
音视频技术一句话简单来说就是通过网络将图像和声音从生产端分发给消费端的技术。可以是以点播的方式,也可以是直播的方式,也可以是像视频会议一样互动的方式。现在的网络流量一多半都是在传输音视频的数据,音视频相关的app几乎每个人都在使用,占据了大众娱乐的半壁江山。
上面的截图类似于OSI网络体系分层一样, 消费端的处理流程是生产端的逆流程。
音视频生产端: 音视频的采集 -> 预处理 -> 编码 -> 封装 -> 网络发送
音视频消费端: 网络接收 -> 解封装 -> 解码 -> 渲染
音视频的采集
音视频的采集包括摄像头的采集,麦克风,扬声器,本地视频,游戏图像,显示器桌面的采集等等。
不同平台有对应的编程框架,比如 windows 下的 DirectShow 框架可以采集摄像头的图像数据,macOS Android Linux都有相应的框架采集音视频的数据, obs stuido 这个开源项目可以作为学习各平台音视频的采集的入口。
预处理
视频数据的预处理一般包括视频图像的滤镜处理、美颜处理、加字幕,绿幕抠图。
音频的预处理一般包括声音的3A算法和变速变调处理,这个在 WebRTC里面有详细的介绍和实现。
- AGC:自动增益补偿功能(Automatic Gain Control)
- ANS:背景噪音抑制功能(Automatic Noise Suppression)
- AEC:回声消除器(Acoustic Echo Canceller)
编码
视频的编码标准:
- H264
- H265
- VP8
- VP9
- AV1
音频的编码标准:
- AAC
- Opus
- mp3
以我目前的工作经验最常用的视频编码是 h264 音频编码是 AAC 编码。
封装
音视频编码后需要将音视频包以某种容器封装起来,这个步骤成为音视频的封装。常见的封装格式
- flv
- mp4
- ts
- rtp
ffmepg 支持非常丰富的媒体封装格式。查看 ffmepg 支持的封装格式命令如下
ffmpeg -muxers
传输
常见的音视频的网络传输协议有 rtmp http-flv rtsp srt hls rtc udp ,各有优劣,这里不做详细对比。
感兴趣可以百度 google搜索了解。
解封装
解封装是上面介绍的封装的逆操作,从音视频的容器中将音频包、视频包分离出来放到各自的队列,等待各自的解码线程去解码渲染视频,播放音频。
解码
编码的逆操作,将视频包解码成原始的视频帧,将音频包解码成原始的pcm音频数据。
渲染
视频的渲染 windows 平台下可以使用 Direct3D 技术渲染视频,macOS,Android 和 Linux 可以使用 OpenGL 、OpenGLES 技术渲染视频。
音频的播放各平台有各自的音频播放api,这里不做介绍,OBS Studio 开源项目里面有对应平台的音视频的渲染播放源码。大家可以参考学习。
常用开源项目和工具
- obs studio 直播客户端的综合性开源项目,包含各个平台下的音视频的采集、编码、传输、渲染。涉及到的知识非常丰富。是一个非常好的入门音视频的项目。
- FFmpeg 最牛逼的编解码工具,不解释音视频开发者必须要掌握的编解码库。
- SDL2 跨平台的音视频的渲染播放工具。
- libyuv 谷歌开源的跨平台的图像格式转换,裁剪,缩放库,效率比 ffmpeg的 sws_scale 要高跟多。
- SoundTouch C++编写的音频处理工具,支持变速变调。
- ijkplayer bilibili开源的跨平台播放器,播放器内核基于 ffplay
- srs 开箱即用的流媒体服务器,非常方便的可以搭建推拉流环境。
- ZLMediaKit 也是一款优秀的国人开源的流媒体服务器,使用 C++11 标准开发,代码写的非常漂亮。
- WebRTC 谷歌开源的音视频全家桶项目,项目非常的大,非常值得学习。
总结
音视频的技术非常的深,设计的面又非常的广,想要精通上面的所有的技术成为六边形战士,需要付出大量的时间和精力。如果你也喜欢音视频技术,可以参考上面的技术栈,一点一点搭建自己的技术体系。
冰冻三尺非一日之寒,滴水石穿非一日之功。
加油!让我们早日成为音视频开发者六边形战士!
技术参考
本文部分技术点出处:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发