流媒体服务新手入门教程03--音视频基础

382 阅读10分钟

对于简单的接入摄像头等硬件或者推送视频流、录制文件,那么直接下载m7s官网编译好的二进制文件即可。

如果要做二次开发,那么就需要了一些基础的音视频基础,及m7s代码了,我们先了解一些音视频基础。

视频基础

视频帧

对于视频来说,我们可以把其想象为一幅一幅图片组成的,当把这些图片连续快速播放时,由于人眼的视觉暂留,只要播放的速度大于1秒24幅图片,那么我们看起来就是连续的。其中这个每秒播放多少张图片就称为帧率 ,一副图片就称为帧。假如就这么把图片放在一起,我们来算一下现在流行的15秒短视频大概有多大。
我们现在的手机摄像头都是千万像素,拍摄出来的照片基本都超过1M,这里就按1M计算,帧率按照24,则15秒的短视频有 24*1*15 = 360M
是不是吓一跳,实际上视频并不简单的把图片组合起来,而是按照一定的规范压缩过。要不然我们刷几个短视频,流量蹭蹭蹭的往下掉,谁也扛不住啊!

帧间压缩

我们比较一下相邻的两幅图片,会发现第二幅图片相对第一幅来说变动很小。如果只记录这个变化的地方,那么存储不就降下来了吗。
于是这些技术专家们提出了三种帧:
I 帧(Intra-coded picture)表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
P帧 (Predictive-coded Picture)前向预测编码图像帧,P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。
B帧 (Bidirectionally predicted picture)双向预测编码图像帧,B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别,换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。

帧内压缩

看到这里,你可能会想到,除了对帧间压缩,我们是否还可以对帧内进行压缩呢?答案是肯定的。
我们常见的图片是利用红、绿、蓝三原色来表示每一个像素点,即RGB模式。但实际上摄像头,流媒体里用的更多的是YUV。
什么是YUV?
Y表示明亮度(Luminance或Luma),也就是灰度值;
U(Cb)表示色度(Chrominance)
V(Cr)表示浓度(Chroma)
它们直接的关系可以参考这副图片,YUV和RGB直接的换算关系可以参考此文

和RGB类似,原始的YUV也是用三个分量代表颜色,这时存储大小也是和RGB一样的。
但是人眼对亮度更敏感。于是我们就可以压缩U和V分量了。
比如常见的YUV 422,表示 UV 分量的是 Y 分量的一半,那么存储空间就相当于以前的 (0.5 + 0.5 + 1) / 3 = 2/3 了。
压缩更高的还有YUV 420,表示UV分量隔行存储,并且只有Y分量的一半,那么存储空间就相当于以前的 (0.25 + 0.25 + 1) / 3 = 1/2 了。
对于YUV其实还有很多情况,我这里就不多说了,请自行查找。
当然帧内压缩还有其它方式,这里只说一下最常见的情况。

编解码和解封包

视频压缩思路确定后,就是具体的压缩算法了。不同的机构提出了各种各样的压缩算法。
压缩视频帧还原视频帧被称为编解码。
编码就是指通过压缩技术,将原始视频格式的文件转换成另一种视频格式文件的方式。
解码即对已编码的数字视频进行还原操作的过程。
常见的编码有:

  • H264 当前主流编码,个人免费,商业收费
  • H265 H264的下一代,压缩率更高,已开始普及,个人免费,商业收费
  • VP8/VP9 Google推出,主要用在webrtc中, 开源免费
  • AV1 Google 推出,想要与H265争夺市场,开源免费
  • AVS 国产视频编码,AVS1替代H264,AVS2 替代H265,比同期的H264和H265都强。个人免费,商业收费,比H264、H265低很多。
    作为国人,希望国产编码标准能够开源免费,这样可以吸引到足够的开发者和硬件厂商,打造良好的生态,逐渐推广到世界。

确定好编解码后,下一步就是怎么保存这些编码后的数据了。可以想象最简单的一种方案是直接保存编解码后的数据,对于直接保存为文件来说,这当然是没有问题的。
但是把原始数据放在网络上传播,就有点困难了。我们知道网络是一个不确定的环境,数据有可能丢失或者顺序错位,这时给原始的视频数据加一层壳,在这层壳上添加
编号,以及一些校验数据,就可以大大降低网络传输的不确定性了。
在网络传输中,为了方便数据传输,常常对数据的打包后发送,被称为封包。打包的数据分成两个部分,包括控制信息,也就是表头(header),和数据本身,也就是负载(payload)。解包即封包的反向操作了,通过读取表头header里的信息,提取负载数据。
虽然文件可以不用封包,但是我们常见的视频文件,其实也是对编码后的视频封包了,方便压缩传输和自定义(比如封装字幕加水印啥的)。

比如常见的mkv格式,mkv实际是容器,内部可以装不同编码类型的原始视频,既可以是h264,也可以是h265的。

音频基础

采样率

我们听到的声音是声波,声波是一种模拟信号,要想让计算机处理,得把其变成数字信号,这个转换被叫做A/D(模数)转换。
怎么把声波变为数字信号呢?这就需要采样,或者叫抽样了。采样率则是指录音设备在一秒钟内对声音信号的采样次数,单位Hz(赫兹)
如下图,如果采样的间隔越小,那么对声音的还原度不久越高了吗?

音频压缩

同视频一样,如果未经压缩,原始数字音频信号流(PCM编码)文件也是大的吓人。
音频压缩也是应用了人的听觉差异,包括时域和空域。
空域:人耳对低频和高频不敏感,可以直接把这些信号去除。
时域:高频声音会覆盖前后几十毫秒的低频声音,那么这几十毫秒的信号也可以去除。
当然这个同视频一样,这个是基础压缩,在这么处理后,还能够继续用算法来压缩。
音频压缩又分为有损压缩(即能够还原原始音频),和无损压缩(即不能还原)。
常见的音频编码又:

  • aac 收费
  • mp3 收费
  • ogg 开源
  • wav 原始 直接在PCM上加了描述信息,没有压缩
  • ape 无损压缩

其它理论

位数

视频:比如我们保存图片有8位、16位,位数越多则单个像素点的色彩种类越多。
音频:对声音来说,比如上面的采样率,如果纵坐标范围划分的越细,那么记录的声音强弱范围也越详细。

码率/码流/比特率

在摄像头配置界面,我们常见的一个选项就是码率了。知道码率后,可以直接用 码率x时间/8 来估算 文件大小。
为什么除以8呢?因为码率的单位是b(bit),文件用的是B(Byte),一个字节是8位。
码率有动态码率和静态码率,在确定分辨率和帧率后,码率仍然是可以调整的,码率调整的是压缩率。码率不仅是视频,也是音频的一个参数。
码率越高,质量越好。但是网络传输条件下,我们往往要做取舍,选择适当的码率。
我们先使用ffprobe -i 文件路径 发现输出了下面的内容,展示了视频文件的元数据、包括时长、码率、音视频编码器,分辨率等

 Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2019-10-22T07:09:16.000000Z
  Duration: 00:31:46.72, start: 0.000000, bitrate: 15047 kb/s
    Stream #0:0(zho): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 251 kb/s (default)
    Metadata:
      creation_time   : 2019-10-22T07:09:16.000000Z
      handler_name    : Core Media Audio
    Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 14791 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)
    Metadata:
      creation_time   : 2019-10-22T07:09:16.000000Z
      handler_name    : Core Media Video


常见码率

dts pts gop

在播放视频的时候,网络情况不好,或者拖动进度条,会出现音视频不同步的问题。音视频不同步,就和下面两个概念有关了:
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

要实现音视频同步,通常需要选择一个参考时钟,参考时钟上的时间是线性递增的,编码音视频流时依据参考时钟上的时间给每帧数据打上时间戳。在播放时,读取数据帧上的时间戳,同时参考当前参考时钟上的时间来安排播放。

有时候还会遇到花屏,然后过一段时间后,自己又恢复了。这就和GOP有关了。
GOP ( Group of Pictures) 是一组连续的画面,由一张 I 帧和数张 B / P 帧组成。花屏一般是因为中间有丢帧,造成解码失败,但上一组GOP结束后,便是新的GOP,新GOP的第一帧是I帧,可以独立解码。所以花屏后,过一会便自动恢复了。如果一直花屏,那么可能是视频文件错误了。

下一章,我将分析m7s的代码结构,开始正式的音视频开发之旅。另外欢迎大家加入m7s微信群,共同探讨进步,加群链接

参考文章及图片来源 :

流媒体技术学习笔记之(五)码流、码率、采样率、比特率、帧速率、分辨率、高清视频的概念
I帧、P帧、B帧、GOP、IDR 和PTS, DTS之间的关系
音频开发基础
什么是音频的采样率?采样率和音质有没有关系?