音视频-基础概念
需要要做一个IM项目、直播等项目。有没有开源的方案可以选择,或者直接拿来使用?
我们通常会接到这类的项目,里面涉及到了音视频技术。业务代码可以跑Springboot+ Mysql + Websocket + Redis使我们搭建一个聊天Demo。小项目或者外包项目适合这类的客服系统,没什么要求只要能用。比如 京东客服系统 只有一个网页,断开了就无法聊天。
发发文字、图片、小视频都可以实现。但涉及到的语音通话、视频通话、视频播放这些功能一般就不熟悉了。当然我们普遍的方式是使用第三方SDK的方式集成。比如:环信SDK、网易云信SDK、融云SDK。但这些技术都是需要收费的,按流量计费。并不适合做外包项目或成本预算比较低的小项目。
对我们普通的
Java开发来说,音视频是另外的领域。跟业务代码完全不一样。
那么问题来了,音视频领域里面难道就没有开源框架可以使用吗?
当然有
音视频开源框架
我们在音视频世界里,也可以找到像Spring这样的开源生态,来解决很多编码、解码、转码、推流等问题。
我介绍一下开源框架以及他们的功能,只是做个最简单的介绍:
FFmpeg:目前最常用的音视频处理库。客户端使用得比较多libwebrtc:目前最常用的RTC库。Chrome浏览器音视频能力底层通过这个库ijkPlayer:目前最常用的移动端播放器。介绍一下是bilibili开源的。(ffplay:PC端的播放器。(ijplayer是基础这个库做的二开)VLC:常用的播放器。跨平台支持pc和移动端(不推荐做二开,只是调用api没关系)SRS:最常用的流媒体服务器(对,音视频也是前后端分离的)Pion:WebRTC流媒体服务器,使用Golang开发的(适合中小团队音视频创业项目哦)ZlMediaKit:流媒体服务器(非常稳定,问题少。可以作为实时音视频系统服务器)speex:音频处理(主要用来回声消除)soundtouch:音频处理库(可以在Mac系统上捕捉系统内部音)
上面的库是比较常用的。
移动端基于
ijkPlayer库做二开的比较多。针对播放器、直播、实时音视频很多场景可以使用。很nice
视频封装格式和编码格式区别
好多人都听过mp4、ts、flv、h264、h265、aac。那这些有什么区别呢?
mp4、ts、flv属于封装格式h264、h265、aac属于编码格式
这两者属于上下级关系:封装格式 = 视频编码格式 + 音频编码格式
例如微信小视频:
- 封装格式:
mp4 - 视频编码格式:
h264 - 音频编码格式:
aac - 视频分辨率:
1280*720
操作步骤:
- 把朋友圈微信小视频保存下来并发送到电脑,我们可以看到视频的封装格式是
mp4

- 使用
vlc播放器打开这个mp4视频,查看媒体信息。我们可以看到视频的编码格式为h264、音频编码格式为aac
总结:封装格式跟编码格式经常会弄错。经常视频播放不了,黑屏等问题,一般是查看编码格式是否被电脑支持。要分清封装格式和编码格式
错误例子:微信小视频的视频编码格式是
mp4(错误)
正确例子:微信小微信的视频编码格式是
h264(正确)
播放器的过程
重点内容来了,图是网上找的。因为画得比较清楚,所以选了这张图
上图是一个播放器从传入URL到播放所经历的全部过程:
- 解协议
- 解封装
- 解码
- 同步
- 画面渲染播放
流媒体协议:常见的协议有HTTP、RTSP、RTMP等。HTTP协议是最常见的媒体协议,用于电影、电视剧可以点播;RTMP常用于直播场景,比如抖音直播、淘宝直播;RTSP协议常用于军工、安防监控、等传统领域。例如:海康摄像头、360摄像头。
封装协议:常见的协议有mp4、avi、rmvb、mkv、flv。这是多媒体封装协议,就是把视频跟音频一起打包进行封装,播放器播放的时候就需要单独把封装里面的视频跟音频分离开来。
那么为什么要封装起来,这么麻烦呢?对,是为了方便传输。我们后台报表的时候,也会把所有
excel表格打包成zip文件,点击就下载了。这样是不是很方便
视频编码、解码
视频编码:常见的格式有 h264、h265、vp8、vp9。最通用的是h264
视频解码分为软角和硬解。
- 软件编码、解码
- 硬件编码、解码(GPU/CPU内置编解码器)
视频编码的本质是对传输的图片进行压缩,以更小的体积在网络上传输。
视频压缩后的数据叫帧数据,有3种帧数据类型:
I帧:关键帧是每个画面的参考帧P帧:前向预测帧B帧:双向预测帧
所有的视频格式都是无数个I帧、P帧、B帧组成的。每个帧等价于每张压缩的图片
根据压缩的级别不同,按压缩率从高到低排列:B帧、P帧、I帧。
那么问题又来了,帧数据是怎么排列的。为什么图片上看到的每个帧数据都是不规则并且带箭头方向的呢?
I/P/B帧压缩是根据增量压缩的。I帧压缩了当前的图片;P帧是I帧的差异数据;B帧是2个P帧的差异数据。所以B帧压缩率最高。
增量压缩的场景例子:
我们手机抖音进行升级。一般是增量更新,最新的安装包和当前安装包不同的数据就是需要增量的数据,这样升级所需要的流量就会最小。
两个帧数据之前不同的点,就是增量的参考数据。I帧不需要参数;P帧有1个参考点;P帧有2个参考点。
空间压缩的概念,可能不太容易懂。不懂也没关系,只是介绍概念
视频压缩前的数据叫图像格式。只有一种类型叫:YUV格式
图片中一般使用
RGB,视频中一般使用YUV。两个是图像格式,例如:图片的jpeg和png都是图片的格式
为什么视频是用YUV格式而不是RBG格式呢?
视频这种格式,可以使体积更小。其中 Y 表示的是亮度(灰度),而 U 和 V 表示的是色度(饱和度)。
图像格式,一种3种类型:
- Y类型
- U类型
- V类型
YUV 最常用的采样比例是 4:2:0 ,我们称为yuv420
在一个6*6的方格中,他们各自的比例如下图:
从图中可以看到几种颜色分类:
- 蓝色
- 绿色
- 红色
- 紫色
- 黄色
- 橘色
每一种颜色都是一帧YUV420格式。其中蓝色的分为上面4个和下面2个,箭头把上下连接起来了。上面4个都是Y,下面的2个分别是U和V。这样分是为了提高压缩率,节省空间。
节省空间、节省空间、节省空间
总结:YUV的比例为
4:2:0。非常节省空间
为什么视频压缩很重要。如果不压缩的情况下。视频到底会有多少大呢?
拿1080P视频举例,一帧视频的大小如下:
Y = 1920*1080
U = 1920*1080/4
V = 1920*1080/4
简化公式: 1920*1080(Y) + 1920*1080*0.5(U+V) = 2.9MB
以上公式得出:一帧的数据为2.9MB
我们一秒钟的1080P视频有多大呢?
1秒 = 60帧
1帧 = 2.9MB
60*2.9MB = 504.6MB
1秒钟的视频这么大。那我们一部电影算90分钟。算一下没压缩的话需要多大的硬盘空间:
1分钟 = 60秒
90分钟 = 60*90 = 5400秒
1080P视频大小: 504.6MB * 5400秒 = 2660.977GB
总结:视频的编码对空间进行压缩,对于我们是非常重要的
通用我们使用
H264编码。
H265空间可以在H264编码基础上再节省50%空间,但硬件对H265编码支持不太好,普及度远远没有H264的高。
所以微信是使用了
H264编码技术
音频编码、解码
音频编码:常见格式有MP3、aac、pcm、WAV 、opus等
音频的由3部分组成:
- 采样率
- 样本大小
- 声道数
这部分知识就是音频的基础概念。
采样率可以分为7个等级,等级越高声音品质越好:
11025:AM调幅广播所用采样率22050:FM调频广播所用采样率44100:音频 CD, VCD, SVCD, MP3 所用采样率47250:商用 PCM 录音机所用采样率48000:miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率50000:商用数字录音机所用采样率96000:DVD、蓝光盘、高清晰度 DVD
常用的是
44100和48000。电脑采集的音频就是48000,我使用mac电脑。windows下也是这样的。除非特别差的电脑
音频格式常用的是
aac和opus。微信也是用的是aac格式;视频会议和语音电话一般用的是opus
计算原始音频大小,例如我的电脑采集的音频文件。我拿到的音频参数为:
- 采样率:48000
- 样本格式:16bit
- 声道数:双声道(大部分笔记本音频都是双声道)
- 时长:25秒
48000*16*2*24/8 = 4.39MB
除以8是因为,一个字节=8位
这里计算有多少个字节
计算出来的是字节数量,除以1024是kb,再除以1024是mb
音频的原始文件没有视频这么大,但还是很大。
后续还想再接着写。把流媒体协议、编码再扩展一下,当前的一些场景使用的是什么技术,什么协议,编码格式。比如说微信的视频电话、语音电话使用到的技术;直播时延迟、抖动、卡顿等