浅谈网络-直播都使用什么流媒体协议?

2018-10-27  本文已影响40人  封不然

说起直播这个词现在好像并不陌生,在我认识的人中,这两个月跳槽到有直播业务的公司的就三个人。有的问我做过直播吗?哈哈,我只能明白的告诉他们我没做过了,不过虽然没具体做过这个业务,理论知识还是知道些的,下面就大体谈下这种直播的过程大概是个什么样的逻辑吧。

视频

要说直播的话,肯定首要了解的是视频的相关知识。大家都知道视频的很多后缀,例如AVI、MPEG、RMVB、MP4、MOV、FLV、WebM、H.261等等的吧,其实简单的介绍视频的话,就是一组连续播放的图片,想象下幻灯片自动播放速度如果快的话是不是就像一个视频了。其中快速播放的每一张图片,我们称之为,每秒图片播放速度,我们称之为帧率(FPS),播放速度快些的话,我们就不会感觉它是一张张图片了。

但是这会引出一个问题,那就是如果那是一张张图片的集合的话,那这种高清的视频会多大,咱们一张按照700K来计算的话,每秒30帧,那一个小时的视频将会达到1200多G,这就很恐怖来,尤其是在网络上想要看一个高清视频的话,简直是绝望。那么改如何解决呢?那就是编码

之所以能够通过编码进行视频压缩,是因为视频和图片有以下几个特点。
1.空间冗余:图像的相邻像素之间有较强的相关性,一张图片相邻像素往往是渐变的,不是突变的,没必要每个像素都完整地保存,可以隔几个保存一个,中间的用算法计算出来。
2.时间冗余:视频序列的相邻图像之间内容相似。一个视频中连续出现的图片也不是突变的,可以根据已有的图片进行预测和推断。
3.视觉冗余::人的视觉系统对某些细节不敏感,因此不会每一个细节都注意到,可以允许丢失一些数据。
4.编码冗余::不同像素值出现的概率不同,概率高的用的字节少,概率低的用的字节多,类似霍夫曼编码的思路。

当前主流的编码套路:
套路一:ITU(International Telecommunications Union)的 VCEG(Video Coding Experts Group),这个称为国际电联下的 VCEG。他们最初做视频编码,主要侧重传输。
套路二:ISO(International Standards Organization)的 MPEG(Moving Picture Experts Group),这个是ISO 旗下的 MPEG,本来是做视频存储的。例如,编码后保存在 VCD 和 DVD 中。当然后来也慢慢侧重视频传输了。

后来,ITU-T(国际电信联盟电信标准化部门,ITU Telecommunication Standardization Sector)与 MPEG 联合制定了 H.264/MPEG-4 AVC。经过编码后的视频就比之前体积小了很多,编码后的二进制文件也就以我们最开始说的那几种格式分别存储。这些二进制通过某些协议的封装就可以在网络中传播了。

具体视频是怎么进行编码的,我就不做说明了,因为我也不太清楚。

直播

对于视频的基本有了些认识了以后,咱们开始今天的正题,直播都经历了什么过程?简单的说,其实这个直播可以被分成以下几个部分:
主 播 :录制 -> 转码 -> 推流
服务端: 接流 -> 流处理 -> 分发
用 户 :拉流 -> 解码 -> 播放

主播对自己进行实时录像,通过设备将实时视频转化为二进制流,网络协议将这编码好的二进制视频流推送到服务器。服务器接收到二进制流后,可以对视频流进行一定的处理,例如解码处理等,也即从一个编码格式,转成另一种格式。因为观众使用的客户端千差万别,要保证他们都能看到直播,由于考虑到并发等系列的问题,可能会将流分发到不同的服务器上。用户登陆进直播间后,就开始拉流到客户端本地,并将二进制流进行解码转化,就可以播放了。

这个过程是不是看起来很简单?那么我们又是通过什么,将流打包,发送到服务端的呢?直接推送二进制文件内容?当然不是。在这里我们使用RTMP协议进行说明,当然由于RTMP是建立在TCP基础上的,可能效率不是那么让人满意,初次之外咱们还可以使用建立在UDP上的流媒体协议RTCP等。(当然这系列的协议挺多,并且各有所长,有需要的可以进行深入了解。)

RTMP 是基于 TCP 的,因而肯定需要双方建立一个 TCP 的连接。在有 TCP 的连接的基础上,还需要建立一个 RTMP 的连接,也即在程序里面,你需要调用 RTMP 类库的 Connect 函数,显示创建一个连接。RTMP 为什么需要建立一个单独的连接呢?

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

具体的交互流程如图示所示,首先,客户端发送 C0 表示自己的版本号,不必等对方的回复,然后发送 C1 表示自己的时间戳。服务器只有在收到 C0 的时候,才能返回 S0,表明自己的版本号,如果版本不匹配,可以断开连接。服务器发送完 S0 后,也不用等什么,就直接发送自己的时间戳 S1。客户端收到 S1 的时候,发一个知道了对方时间戳的 ACK C2。同理服务器收到 C1 的时候,发一个知道了对方时间戳的 ACK S2。则建立起了连接。之后,双方需要互相传递一些控制信息,例如 Chunk 块的大小、窗口大小等。


交互流程

实际上,真正传输的时候,还需要建立一个流Stream,放在一个Message中(也就是一个RTMP Packet 包中)。格式如下图所示


image.png

需要注意的是RTMP 在收发数据的时候并不是以 Message 为单位的,而是把 Message 拆分成 Chunk 发送,而且必须在一个 Chunk 发送完成之后,才能开始发送下一个 Chunk。每个 Chunk 中都带有 Message ID,表示属于哪个 Message,接收端也会按照这个 ID 将 Chunk 组装成 Message。

拆分示例如下图所示:


image.png

前面连接的时候,设置的 Chunk 块大小就是指这个 Chunk。将大的消息变为小的块再发送,可以在低带宽的情况下,减少网络拥塞。Chunk 的 Type=0,表示 Chunk 头是完整的;Chunk Type=3,表示头一样就不再发送了;头里面 Timestamp 为 1000,总长度 Length 为 307,类型为 9,是个视频,Stream ID 为 12346,正文部分承担 128 个字节的 Data。

一个视频直播里面就那么多门道,看样子看直播这种事情是多么的难得。且看且珍惜吧?顺便问下大家都喜欢看直播吗?喜欢的话一般在哪个平台上看直播?

上一篇 下一篇

猜你喜欢

热点阅读