前言
文章开始之前先给大家分享一个B站的视频教程,感兴趣的小伙伴可以去看看。
音视频开发全系列教程:https://www.bilibili.com/video/BV1fb4y1d7JU?spm_id_from=333.999.0.0
那些必须懂得的基础知识点
其实我们应该从两个角度来理解这个事情,音视频开发其实可以拆解为两部分,一是音频,一是视频。
音频
声音是怎样产生的? 在初中的书本也应该有这样的定义,物体振动产生声音。就像人如果没有声带,就会变成哑巴,可能还是会有咿咿呀呀的声音,但是失去了这个基础,终究说不成话。
到了高中,你会接触到波的概念,而声波也就是我们日常生活中最常接触到的波之一。我们评价一个人的声音如何,是不是会用洪亮,尖锐、浑厚这样的词汇来进行形容呢。其他他就是我们声波的三个要素:频率、振幅、波形。
人的听力同样也是有一个接收频率存在的,就像是你听不到蝙蝠的超声波一样,科学家给出的数据如下:20Hz~20kHz
,具体范围因人而异。
数字音频
上面讲述的是我们在日常生活的体验,但是计算机呢,它所保存的数据一般都是离散型的。那他如何识别我们的声音,并进行一个记录呢,如何将我们的话翻译成只包含0
和1
的二进制文件,有将他翻译回来成为我们的声音的呢?
音频处理需要经过3大步骤:采样 -> 量化 -> 编码
采样
首先就是采样的过程,一般我们采用的频率是44.1kHz
。也就是1
秒的采样次数为44100
次。
当然可能会有读者问,为什么要是
44.1kHz
呢,我大点小点不可以吗?其实可以,但是别人用44.1kHz
,总有他的道理,所以就找了一个比较好的答案给你们。跳转链接
量化
这就是离散化的作用了,想想我们的圆面积在以前是如何来进行运算的,兀
的出现是一个怎样的过程?
有n
边形来进行一个替换,那这个时候n
越大,求得的数值越接近圆真正的值,而兀
的值,我们求得的也更为接近。这其实也就是离散化的音频恢复的做法。
离散数据
恢复数据
编码
通常我们所说的音频的裸数据格式就是 脉冲编码调制(PCM) 数据,而他的组成分别有量化格式、采样率、声道数。
- 量化格式:
位数 | 最小值 | 最大值 |
---|---|---|
8 | 0 | 255 |
16 | -32768 | 32767 |
32 | -2147483648 | 2147483647 |
如果位数越大,那么对一个音的描述越明确,那么还原度就越高
- 采样率: 在上文我们已经提及过了
- 声道数: 单声道、双声道、立体声道(2或4个声道)
》》例题《《
如果一个量化格式为16位
,采样率为44.1kHz
,声道数为2
,那么他的比特率是多少?如果存储一分钟,产生的数据量是多少?
比特率可以理解为存储时长为
1s
时数据的产生量。即,比特率 = 量化格式 * 采样率 * 声道数
一分钟产生的数据量 = 比特率 * 存储时间 = 44100 * 16 * 2 * 60 = 84672000 Bit
音频编码
这一部分的内容涉及的是一个数据压缩的问题,因为一个数据量过大的文件,其实是不适合在网络中进行传输的,压缩就成为他们的必须要进行处理的事件,当然分为形式有两种:有损压缩、无损压缩。
常见的压缩方式其实有很多,最常见的有:(1)WAV编码 (2)MP3编码 (3)AAC编码 (4)Ogg编码
AAC编码
使用场景: 128Kbit/s以下的音频编码,多用于视频中音频轨的编码。
AAC的音频文件格式有ADIF & ADTS:
- ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
- ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
对AAC编码格式的详细介绍详见于AAC 文件解析及解码流程
Ogg编码
使用场景: 语音聊天的音频消息场景。
特点: 实现比MP3编码的码率更小,但是音质更优。不支持流媒体
视频
在介绍视频之前,我们需要知道视频是怎么呈现的。
作为一个要传输的数据,自然也是需要进行量化和编码的过程的。
图像数值表示
RGB表示方式
两种表现方式:
- 浮点表示: 取值范围
0.0 ~ 1.0
,OpenGL ES
中采用的表示方式。 - 整数表示: 取值范围
0 ~ 255
或00 ~ FF
,8
位一个子像素,32
位一个像素。存在一些平台的图片格式为RGBA_8888
,而Android平台上是RGB_565
表示方式,也就是R用5
位表示,G用6
位表示,B用5
位表示,也就是16位来表示一个像素。
那么我们就需要对单张的图像进行一次计算了。以一张1280 * 720
的RGB_565
的图像作为例子来计算。
存储空间 = 1280 * 720 * 16 = 1.758MB
这只是单张图片的计算结果,我们对于视频的传输是几张图片嘛?
为了让人的视频感觉出“ 视频 ”真的是视频,那必然要有一定的刷新率,刷新率为24fps
,36fps
,甚至更高时,这样海量的数据,1个小时的电影下载都不知道要废去多少时间。
YUV表示方式
相较于RGB
表示方式的优势在于RGB
要求三个独立的视频信号同时传输。
对于YUV
的定义:
-
Y
:描述明亮度,也称灰度值;是将RGB
信号的特定部分叠加。 -
U
/Cb
:蓝色通道和明亮度的差异值。 -
V
/Cr
:红色通道和明亮度的差异值。
YUV
采样的常见格式为YUV420
,这并不是说的Y:Cb:Cr = 4:2:0
,代表其实是对每行扫描线来说,一种色度分量是以2:1
的抽样率来存储的。
你可以看出的U
和V
是交替出现和Y
进行比较的。
和RGB
表示方法一样,来进行一次计算
存储空间 = 1280 * 720 * 8 + 1280 * 720 * 4 = 1.318MB
可能读者没明白为什么是
8
和4
,其实从上面的图中已经说明YUV
应该成组出现,那么联合的时候一个完整YUV
就应该是12Bit
,你也可以选择改写成12
。
显然他的存储空间更小了,而且实际应用上更为方便。
YUV和RGB的换算
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
----- 再推算回RGB-----
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U
视频编码
因为现在主要流行的编码标准为H.264
,因为他创造了多参考帧、多块类型、整数变换、帧内预测等新型压缩技术。
在H.264
中,三种类型的帧数据分别为:
- I帧: 帧内编码帧,用于去除空间冗余信息。
- P帧: 前向预测编码帧,参考前面的一个I帧或P帧生成。
- B帧: 双向预测内插编码帧,参考前面的一个I帧或P帧,和后面的一个P帧图像帧编码生成。
P帧
和B帧
简化去的是视频帧在时间维度上的冗余信息。
关于IDR帧
这是一个特殊的I帧
,因为会存在这样的情况。
多帧预测中,P帧
参考前面的是前面的一个I帧
或P帧
生成的,P帧
是一个不断向前参考的帧,也就是说前一个I帧
并不一定是关键帧,所以就算找到了I帧
也不能说能够成为参考条件。而IDR帧
就是为了解决这样的问题,一旦找打了IDR帧
,也就不会再向前探索参考了,直接成为参考帧。
DTS与PTS
DTS: 标示读入内存中数据流在什么时候开始送入解码器中进行解码。也就是解码顺序的时间戳。
PTS: 用于标示解码后的视频帧什么时候被显示出来。
在没有
B帧
的情况下,两者一致;反之则不同了。
GOP
GOP: 指的是两个I帧
之间形成的一组图片。必要设置的参数为gop_size
,也就是两个I帧
之间的帧的数量,如此通过改变gop_size
的大小,来控制视频的质量。
音视频开发全系列教程:https://www.bilibili.com/video/BV1fb4y1d7JU?spm_id_from=333.999.0.0
本文转自 https://juejin.cn/post/6844904081102897159,如有侵权,请联系删除。