网络:流媒体协议

视频是什么?

  • 其实就是快速播放的一连串连续的图片。
  • 每一张图片,我们称为一帧。只要每秒钟帧的数据足够多,也就是播放得足够快。 比如每秒30帧,以人的眼睛的敏感度,是看不出这是一张张独立的图片的,这就是我们常说的帧率(FPS)

每一张图片都是由像素组成的,假设为1024*768。每个像素由RBG组成,每个8位,供24位

我们来算一下,每秒钟的视频多大:30帧 * 1024 * 768 * 24 = 566,231,040bits = 70,778,880Bytes。

如果是一分钟内?4,46,732,800Bytes,应该是4个G了。

这个数据量是在太大,根本没办法存储和传输。如果这样存储,你的硬盘很快就满了;如果这样传输,那多少带宽也不够用啊!

怎么办呢?编码,就是看如果用尽量少的bit保存数据,使得播放的时候画面看起来仍然很精美。编码是一个压缩的过程

视频和图片的压缩过程有什么特点?

之所以能够对视频流中的图片进行压缩,因为视频和图片有这样一些特点。

  • 空间冗余:图像的相邻像素之间有较强的相关性,一张图片相邻像素往往是渐变的,不是突变的,没必要每个像素都完整地保存,可以隔几个保存一个,中间的用算法计算出来。
  • 时间冗余:视频序列的相邻图像之间内容相似。一个视频中连续出现的图片也不是突变的,可以根据已有的图片进行预测和推断。
  • 视觉冗余:人的视觉系统对某些细节不敏感,因此不会每一个细节都注意到,可以允许丢失一些数据。
  • 编码冗余:不同像素值出现的概率不同,概率高的用的字节少,概率低的用的字节多,类似霍夫曼编码(Huffman Coding)的思路。
    总之,用于编码的算法非常复杂,而且多种多样,但是编码过程其实都是类似的。

经过编码之后,生动活泼的一帧一帧的图像,就变成了一串串让人看不懂的二进制,这个二进制可以放在一个文件里面,按照一定的格式保存起来

其实AVI、MPEG、RMVB、MP4、MOV、FLV、WebM、WMV、ASF、MKV就是视频保存成文件的格式。例如,前几个字节是什么意义,后几个字节是什么意义,然后是数据,数据中保存的就是编码好的结果。

当然,这个二进制也可以通过某种网络协议进行封装,放在互联网上传输,这个时候就可以进行网络直播了。

  • 网络协议将编码好的视频流,从主播端推送到服务器,在服务器上有个运行了同样协议的服务端来接收这些网络包,从而得到里面的视频流,这个过程称为接流。

  • 服务端接到视频流之后,可以对视频流进行一定的处理,例如转码,也即从一个编码格式,转成另一种格式。因为观众使用的客户端千差万别,要保证他们都能看到直播。

  • 流处理完毕之后,就可以等待观众的客户端来请求这些视频流。观众的客户端请求的过程称为拉流

  • 如果有非常多的观众,同时看一个视频直播,那都从一个服务器上拉流,压力太大了,因而需要一个视频的**分发*网络,将视频预先加载到就近的边缘节点,这样大部分观众看的视频,是从边缘节点拉取的,就能降低服务器的压力。

  • 当观众的客户端将视频流拉下来之后,就需要进行解码,也即通过上述过程的逆过程,将一串串看不懂的二进制,再转变成一帧帧生动的图片,在客户端播放出来

整个直播过程,可以用这个的图来描述。

在这里插入图片描述

接下来,我们依次来看一下每个过程。

编码:如何将丰富多彩的图片变成二进制流?

虽然我们说视频是一张张图片的序列,但是如果每张图片都完整,就太大了,因而会将视频序列分成三种帧。

  • I帧,也称关键帧。里面是完整的图片,只需要本帧数据,就可以完成解码。
  • P帧,前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面,叠加上和本帧定义的差别,生成最终画面。
  • B帧,双向预测内插编码帧。B帧记录的是本帧与前后帧的差别。要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的数据与本帧数据的叠加,取得最终的画面。

可以看出,I帧最完整,B帧压缩率最高,而压缩后帧的序列,应该是在IBBP的间隔出现的。这就是通过时序进行编码。

推流:如何把数据流打包传输到对端?

那编码得到二进制流是不是立刻就能到网络上传输了?还不能,还需要将这个二进制的流打包成网络包进行发送,这里我们使用RTMP协议,这就引入了第二个过程,推流

RTMP就是基于TCP的,因而肯定需要双方建立一个TCP的连接,在有TCP的连接的基础上,还需要建立一个RTMP的连接,也就是在程序里面,还需要调用RTMP类库的connect函数,显示创建一个连接。

RTMP为什么还需要建立一个单独的连接呢?

  • 因为它们需要商量一些事情,保证以后的传输能正常运行,主要是为了两个事情:
    • 一个是版本号,如果客户单和服务器的版本号不一致,就不能工作;
    • 另一个是时间戳,视频播放中,时间是很重要的,后面的数据流互通的时候,经常要带上时间戳的差值,因而一开始双方就要知道对方的时间戳。

为了沟通这些事情,需要发送六条消息:客户单发送C0、C1、C2,服务器发送S0、S1、S2,

  • 首先,客户端发送C0表示自己的版本号,不必等对方的回复,然后发送C1表示自己的时间戳。
  • 服务器只有要收到C0的时候,才能返回S0,表明自己的版本号,需要版本不匹配,就可以断开连接。
  • 服务端发送完S0之后,也不用等什么,就直接发送自己的时间戳S1,客户端收到S1的时候,发送一个知道了对方时间戳的ACK C2,同理服务器收到C1的时候,也需要ACK S2,表示知道了对方时间戳

于是,握手完成。
在这里插入图片描述
握手之后,双方需要互相传递一些控制信息,比如chunke块的大小,窗口大小等。

真正传输数据的时候,还是需要创建一个stream流,然后通过这个stream来推送publish。

拉流:客户端如何看到视频

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值