阅读 418

【从零冲击音视频开发】音视频开发必备知识基础

目录

【1】【从零冲击音视频开发】音视频开发必备知识基础

【2】【从零冲击音视频开发】移动环境搭建

【3】【从零冲击音视频开发】FFmpeg的介绍和基本使用

前言

之前已经出过了FFmpeg环境搭建的文章了,当然那是专门针对iOS的开发而言的,之后会重新补过对Android Studio的开发环境该怎么搭建。主要原因是因为,我想要专攻的方向还是安卓,之前找到了教程都是关于XCode的安装,所以还是需要重构过的。

文章内容参考书目《音视频开发进阶指南 -- 基于 Android 与 iOS 平台的实践》

那些必须懂得的基础知识点

其实我们应该从两个角度来理解这个事情,音视频开发其实可以拆解为两部分,一是音频,一是视频。

音频

声音是怎样产生的? 在初中的书本也应该有这样的定义,物体振动产生声音。就像人如果没有声带,就会变成哑巴,可能还是会有咿咿呀呀的声音,但是失去了这个基础,终究说不成话。

到了高中,你会接触到波的概念,而声波也就是我们日常生活中最常接触到的波之一。我们评价一个人的声音如何,是不是会用洪亮,尖锐、浑厚这样的词汇来进行形容呢。其他他就是我们声波的三个要素:频率、振幅、波形

人的听力同样也是有一个接收频率存在的,就像是你听不到蝙蝠的超声波一样,科学家给出的数据如下:20Hz~20kHz,具体范围因人而异。

数字音频

上面讲述的是我们在日常生活的体验,但是计算机呢,它所保存的数据一般都是离散型的。那他如何识别我们的声音,并进行一个记录呢,如何将我们的话翻译成只包含01的二进制文件,有将他翻译回来成为我们的声音的呢?

音频处理需要经过3大步骤:采样 -> 量化 -> 编码

采样

首先就是采样的过程,一般我们采用的频率是44.1kHz。也就是1秒的采样次数为44100次。

当然可能会有读者问,为什么要是44.1kHz呢,我大点小点不可以吗?其实可以,但是别人用44.1kHz,总有他的道理,所以就找了一个比较好的答案给你们。跳转链接

量化

这就是离散化的作用了,想想我们的圆面积在以前是如何来进行运算的,的出现是一个怎样的过程?

n边形来进行一个替换,那这个时候n越大,求得的数值越接近圆真正的值,而的值,我们求得的也更为接近。这其实也就是离散化的音频恢复的做法。

离散数据 恢复数据

编码

通常我们所说的音频的裸数据格式就是 脉冲编码调制(PCM) 数据,而他的组成分别有量化格式、采样率、声道数

  1. 量化格式:
位数 最小值 最大值
8 0 255
16 -32768 32767
32 -2147483648 2147483647

如果位数越大,那么对一个音的描述越明确,那么还原度就越高

  1. 采样率: 在上文我们已经提及过了
  2. 声道数: 单声道、双声道、立体声道(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表示方式

两种表现方式:

  1. 浮点表示: 取值范围0.0 ~ 1.0OpenGL ES中采用的表示方式。
  2. 整数表示: 取值范围0 ~ 25500 ~ FF8位一个子像素,32位一个像素。存在一些平台的图片格式为RGBA_8888,而Android平台上是RGB_565表示方式,也就是R用5位表示,G用6位表示,B用5位表示,也就是16位来表示一个像素。

那么我们就需要对单张的图像进行一次计算了。以一张1280 * 720RGB_565的图像作为例子来计算。

存储空间 = 1280 * 720 * 16 = 1.758MB
复制代码

这只是单张图片的计算结果,我们对于视频的传输是几张图片嘛?

为了让人的视频感觉出“ 视频 ”真的是视频,那必然要有一定的刷新率,刷新率为24fps36fps,甚至更高时,这样海量的数据,1个小时的电影下载都不知道要废去多少时间。

YUV表示方式

相较于RGB表示方式的优势在于RGB要求三个独立的视频信号同时传输。

对于YUV的定义:

  • Y:描述明亮度,也称灰度值;是将RGB信号的特定部分叠加。
  • U / Cb:蓝色通道和明亮度的差异值。
  • V / Cr:红色通道和明亮度的差异值。

YUV采样的常见格式为YUV420,这并不是说的Y:Cb:Cr = 4:2:0,代表其实是对每行扫描线来说,一种色度分量是以2:1的抽样率来存储的。

你可以看出的UV是交替出现和Y进行比较的。

RGB表示方法一样,来进行一次计算

存储空间 = 1280 * 720 * 8 + 1280 * 720 * 4 = 1.318MB
复制代码

可能读者没明白为什么是84,其实从上面的图中已经说明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的大小,来控制视频的质量。

以上就是我的学习成果,如果有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。


相关文章推荐:

答应我,收好这份钉钉和抖音的面经,真的很重要!!!

操作系统中的三大经典同步问题,你如何复现?

Android自定义View,你摸的透透的了?