PS
我们上一个系列 -OpenGL ES
暂告一段落,如果你对相机滤镜
感兴趣,可以参看之前的文章。
从本篇开始呢,开始记录Android音视频的相关知识。
学习路线概览
Android音视频的基础知识
音频和视频的产生
音频
从物理学的角度上来说,声音(音频)是由物体的振动产生的,声音(音频) 由 振幅(响度) 、频率(音调) 、音色(谐波) 3要素组成。
在计算机的领域中,我们用数字模拟电路来去模拟声音,声音的承载形式是 PCM(脉冲编码调制),但是数字信号并不能连续保存所有时间点的振幅(我们事实上也不用这么做)。
根据奈奎斯特采样定理:为了不失真地恢复模拟信号,采样频率应该不小于模拟信号频谱中最高频率的2倍。
这里我们提到了采样频率,
采样频率
采样率要大于原声波频率的2倍,人耳能听到的最高频率为20kHz,所以为了满足人耳的听觉要求,采样率至少为40kHz,通常为44.1kHz,更高的通常为48kHz。
除了采样频率外,在计算机领域我们还有其他方面的术语来描述音频
采样位数
采样位数,涉及到上面提到的振幅量化。波形振幅在模拟信号上也是连续的样本值,而在数字信号中,信号一般是不连续的,所以模拟信号量化以后,只能取一个近似的整数值,为了记录这些振幅值,采样器会采用一个固定的位数来记录这些振幅值,通常有8位、16位、32位。
位数 | 最小值 | 最大值 |
---|---|---|
8 | 0 | 255 |
16 | -32768 | 32767 |
32 | -2147483648 | 2147483647 |
位数越多,记录的值越准确,还原度越高。
声道数
声道数,是指支持能不同发声(注意是不同声音)的音响的个数。
PS
声道有以下几种
单声道:1个声道
双声道:2个声道
立体声道:默认为2个声道
立体声道(4声道):4个声道
码率
码率,是指一个数据流中每秒钟能通过的信息量,单位bps(bit per second)
码率 = 采样率 采样位数 声道数
视频
我们这里的视频与我们平常的最常看到的视频的概念稍微有些不一样,最初的视频的概念来自于动画
,由一张张的图片组成,以超过人眼辨识的速度播放就成了视频
视频帧率
帧,是视频的一个基本概念,表示一张画面,如上面的翻页动画书中的一页,就是一帧。一个视频就是由许许多多帧组成的。
帧率,即单位时间内帧的数量,单位为:帧/秒 或fps(frames per second)。如动画书中,一秒内包含多少张图片,图片越多,画面越顺滑,过渡越自然。
帧率的一般以下几个典型值:
24/25 fps:1秒 24/25 帧,一般的电影帧率。
30/60 fps:1秒 30/60 帧,游戏的帧率,30帧可以接受,60帧会感觉更加流畅逼真。
85 fps以上人眼基本无法察觉出来了,所以更高的帧率在视频里没有太大意义。
分辨率
分辨率就是帧大小每一帧就是一副图像。640*480分辨率的视频,建议视频的码速率设置在700以上,音频采样率44100就行了一个音频编码率为128Kbps,视频编码率为800Kbps的文件,其总编码率为928Kbps,意思是经过编码后的数据每秒钟需要用928K比特来表示。计算输出文件大小公式:(音频编码率(KBit为单位)/8 +视频编码率(KBit为单位)/8)×影片总长度(秒为单位)=文件大小(MB为单位)
色彩空间
这里我们只讲常用到的两种色彩空间。
RGB
RGB的颜色模式应该是我们最熟悉的一种,在现在的电子设备中应用广泛。通过R G B三种基础色,可以混合出所有的颜色。
YUV
这里着重讲一下YUV,这种色彩空间并不是我们熟悉的。这是一种亮度与色度分离的色彩格式。
早期的电视都是黑白的,即只有亮度值,即Y。有了彩色电视以后,加入了UV两种色度,形成现在的YUV,也叫YCbCr。
Y:亮度,就是灰度值。除了表示亮度信号外,还含有较多的绿色通道量。
U:蓝色通道与亮度的差值。
V:红色通道与亮度的差值。
采用YUV有什么优势呢?
人眼对亮度敏感,对色度不敏感,因此减少部分UV的数据量,人眼却无法感知出来,这样可以通过压缩UV的分辨率,在不影响观感的前提下,减小视频的体积。
RGB和YUV的换算
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
——————————————————
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U
编解码
首先为什么要对音视频进行编码(压缩编码),这个问题也很简单,因为原始的音频或者视频数据太大了,并且包含了许多我们不太需要的信息,所以我们要对音视频进行编码,有了编码,那么相应的我们也需要解码来还原我们的数据
音视频编解码技术从大类别上分为 有损编码 和 无损编码
PS
无损 和 有损的在于 能否对编码后的数据进行100%的还原
音频编码
音频编码的技术在这么多年的发展中,有了很多的压缩技术
如:WAV、MP3、WMA、APE、FLAC等等,这里有我们常见的mp3,wav,还有无损压缩的APE以及FLAC。
但是我们要主要介绍的是当前主流的音频压缩技术AAC
AAC是新一代的音频有损压缩技术,一种高压缩比的音频压缩算法。在MP4视频中的音频数据,大多数时候都是采用AAC压缩格式。
AAC格式主要分为两种:ADIF、ADTS。
- ADIF:Audio Data Interchange Format。 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。这种格式常用在磁盘文件中。
- ADTS:Audio Data Transport Stream。 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
ADTS可以在任意帧解码,它每一帧都有头信息。ADIF只有一个统一的头,所以必须得到所有的数据后解码。且这两种的header的格式也是不同的,目前一般编码后的都是ADTS格式的音频流。
ADIF数据格式:
header | raw_data |
---|
ADTS 一帧 数据格式(中间部分,左右省略号为前后数据帧):
视频编码规范
在视频编码发展的过程中,出现了许许多多的技术,但是有两个组织有着举足轻重的作用,他们的影响一直持续到现在甚至将来
PS
这两个组织分别是ITU(International Telecommunication Union)和 MPEG(Moving Picture Experts Group, ISO旗下的组织)
现在主流的编码格式H264就是这两个组织联合定制的编码标准,当然还有下一代更先进的压缩编码标准H265。
H264编码简介
H264是目前最主流的视频编码标准,所以我们后续的文章中主要以该编码格式为基准。
视频帧
我们已经知道,视频是由一帧一帧画面构成的,但是在视频的数据中,并不是真正按照一帧一帧原始数据保存下来的(如果这样,压缩编码就没有意义了)。
H264会根据一段时间内,画面的变化情况,选取一帧画面作为完整编码,下一帧只记录与上一帧完整数据的差别,是一个动态压缩的过程。
在H264中,三种类型的帧数据分别为
I帧:帧内编码帧。就是一个完整帧。
P帧:前向预测编码帧。是一个非完整帧,通过参考前面的I帧或P帧生成。
B帧:双向预测内插编码帧。参考前后图像帧编码生成。B帧依赖其前最近的一个I帧或P帧及其后最近的一个P帧。
图像组:GOP和关键帧:IDR
全称:Group of picture。指一组变化不大的视频帧。
GOP的第一帧成为关键帧:IDR
IDR都是I帧,可以防止一帧解码出错,导致后面所有帧解码出错的问题。当解码器在解码到IDR的时候,会将之前的参考帧清空,重新开始一个新的序列,这样,即便前面一帧解码出现重大错误,也不会蔓延到后面的数据中。
注:关键帧都是I帧,但是I帧不一定是关键帧
DTS与PTS
DTS全称:Decoding Time Stamp。标示读入内存中数据流在什么时候开始送入解码器中进行解码。也就是解码顺序的时间戳。
PTS全称:Presentation Time Stamp。用于标示解码后的视频帧什么时候被显示出来。
在没有B帧的情况下,DTS和PTS的输出顺序是一样的,一旦存在B帧,PTS和DTS则会不同。
帧的色彩空间
前面我们介绍了RGB和YUV两种图像色彩空间。H264采用的是YUV。
YUV存储方式分为两大类:planar 和 packed。
- planar:先存储所有Y,紧接着存储所有U,最后是V;
- packed:每个像素点的 Y、U、V 连续交叉存储。
pakced存储方式已经非常少用,大部分视频都是采用planar存储方式。
对于planar存储方式,通过省略一些色度信息,即亮度共用一些色度信息,进而节省存储空间。因此,planar又区分了以下几种格式: YUV444、 YUV422、YUV420。
YUV 4:4:4采样,每一个Y对应一组UV分量。
YUV 4:2:2采样,每两个Y共用一组UV分量。
YUV 4:2:0采样,每四个Y共用一组UV分量。
其中,最常用的就是YUV420。
YUV420格式存储方式又分两种类型
- YUV420P:三平面存储。数据组成为YYYYYYYYUUVV(如I420)或YYYYYYYYVVUU(如YV12)。
- YUV420SP:两平面存储。分为两种类型YYYYYYYYUVUV(如NV12)或YYYYYYYYVUVU(如NV21)
音视频编解码技术
前面我么说的AAC啦,H264啦都是一种编解码规范,所谓规范就像是接口,在这些规范落地的时候可能不同的平台就有了不同的实现技术。
x264是目前最好的H264的实现了,x264官网
另外我们熟知的FFMpeg,FFMpeg的官方介绍是A complete, cross-platform solution to record, convert and stream audio and video. 详情可参看FFMPeg官网
但在上面的路线图中把它归类为软解,所谓软解码,就是指利用CPU的计算能力来解码,通常如果CPU的能力不是很强的时候,一则解码速度会比较慢,二则手机可能出现发热现象。但是,由于使用统一的算法,兼容性会很好。
那么在Android 系统中我们还存在着另一个选择MediaCodec ,这个是Android 4.1(api 16)版本引入的编解码接口,是所有想在Android上开发音视频的开发人员绕不开的坑。
音视频处理
我们在对音视频进行编码后,可能需要对编码后的数据进行进一步处理,比如对音频进行变声,对 视频应用滤镜,以及音视频的编辑
音频处理库FMOD 和 SoundTouch
SoundTouch 是一个开源的音频处理库,用于改变音频流或音频文件的节奏、音调和播放速率。
FMOD 声音系统是为游戏开发准备的音频引擎,商业用途需要购买许可证。除了 SoundTouch 只能对声音进行变调处理功能外,还包括了前面提高和没提到的高级功能(Reverb、Echo、EQ、Flange、3D...)。
SoundTouch 与 FMOD 对比
SoundTouch
优点:开源!因此具有很高的可塑性,可以自由定制完全适用于自己应用。可以处理音调、速率和节拍功能。
缺点:功能单一,满足不了需求。
如果只需要处理音调,变男声女声童声等功能使用 SoundTouch 是最佳选择。如果还需要对声音做其它处理,时间充足情况下也可以考虑修改源码,加入相应的算法来达到所需的功能。
FMOD
优点:声音处理功能强大,可以方便的对声音进行处理。
缺点:非开源,商用不免费,定制化差。
视频处理
FFMpeg 的功能非常全面,视频剪辑、特效等等操作都能使用FFMpeg来进行完成,兼容性也很好,还是跨平台的,这些都是它现在大火的原因吧。
PS
不过对于GPU(硬件加速),我们还有其他的选择,如OpenGL(同样跨平台),在Android上也有实现,如果你对它感兴趣的话请参看之前的系列OpenGL ESPS
封装格式
我们上面聊了这么久,音频格式有PCM,WAV,MP3,AAC等,视频有yuv,h264,那么我们常见得的mp4、rmvb、avi、mkv、...呢,我们到这里可能才意识到,我们平常所说的视频其实包含画面和声音,而上面所说的视频仅仅是单纯的画面。
我们通常所说的视频其实是包裹了音视频编码数据的容器,用来把以特定编码标准编码的视频流和音频流混在一起,成为一个文件,例如上面的mp4、rmvb、avi、mkv、...。
音视频输出
我们在经过上面一系列的步骤之后终于来到了输出,如果我们是播放音视频文件,那么输出一般是SufaceView或者TextureView,如果是对音视频的录制,那么有可能是输出本地音视频文件,如mp4、rmvb、avi、mkv、...也有可能是在网络上进行传输,那么RTMP,WebRTC之类的传输协议也是我们需要学习的内容。
小结
我们本篇主要介绍了音视频的一些基础知识和学习路线,算是为我们之后的内容做个铺垫吧。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。