趣谈网络协议-应用层(流媒体协议)

一、概述

1. 名词定义

帧:视频中的每一张图片

帧率(FPS):每秒图片数

像素:每一张图片,都是由像素组成的。像素由 RGB 组成,每个 8 位,共 24 位。

编码:用尽量少的位保存视频数据

2. 视频和图片的压缩的特点

视频中图片的特点:

  • 空间冗余:图片通常是渐变,相邻像素之间有更高的相关性,因此不需要保存所有像素,只需要间隔几个像素,保存一个。其余的像素用算法计算出来
  • 时间冗余:视频中,相邻的图像具有相关性,因此视频中也不需要保存所有图片,只需要在相邻的图片中保存一个,其余的根据已有的图片进行推测
  • 视觉冗余:人的视觉对一些细节不敏感,因此可以丢失一些数据
  • 编码冗余:不同像素值在图片中出现的次数不一样,出现概率高的使用更短的字节进行编码,概率 低的使用字节多的(哈夫曼编码思路)

编码过程:

二、流媒体数据传输

1. 流媒体传输流程

直播数据传输过程:

  • 视频通过上述编码流程转换成二进制数据,
  • 接流:将编码好的视频封装到网络协议中,通过直播端推送到服务器,服务器有一个运行了同样网络协议的进程接收网络包,从中得到视频流
  • 转码:服务端接收到视频流后,对视频进行一些处理(如转码等),确保客户端不同解码器也可以观看到视频
  • 拉流:视频处理完后,客户端请求视频流,这个过程叫拉流。若观看的用户很多,可以先将视频分发到边缘节点(CDN),大部分观众观看视频时,直接从边缘节点拉取,缓解服务端压力
  • 解码:客户端拉取到数据后,将二进制数据转换成一帧帧的图片,在客户端播放

2. 编码

a. 视频序列

I帧:关键帧,里面包含完整的图片,不依赖于前后帧

P帧:前向预测编码帧,记录这一帧跟之前的一个关键帧(或 P 帧)的差别,依赖之前的帧,叠加上和本帧的区别,生成最终画面

B帧:双向预测内插编码帧,记录这一帧与前后帧的区别,依赖于前后的帧,通过前后画面的数据与本帧数据的叠加,获取最终画面

b. 视频编码方式

时序上的编码:I 帧最完整,B 帧压缩率最高,而压缩后帧的序列,应该是在 IBBP 的间隔出现的。

空间上的编码:在一帧中,分成多个片,每一片都放在一个 NALU 里面,NALU 之间都是通过特殊的起始标识符分隔,在每一个 I 帧的第一片前面,要插入单独保存 SPS 和 PPS 的 NALU,最终形成一个长长的 NALU 序列。

NALU结构:

起始标识符:0000001,标识 NALU 之间的间隔

NALU头:配置了 NALU 的类型,只要内容为 NAL Type,为了保证容错性,每一个 I 帧前面,都会传一遍这两个参数集合。

  • 0x07 表示 SPS,是序列参数集, 包括一个图像序列的所有信息,如图像尺寸、视频格式等。
  • 0x08 表示 PPS,是图像参数集,包括一个图像的所有分片的所有相关信息,包括图像类型、序列号等。
  • 0x01/0x05表示I/P/B帧

Payload:真正的视频数据,由header定义了该数据保存的是I帧还是P帧

3. 推流

RTMP 协议:

  • 经过上述流程后,视频数据转换成了二进制流,在推流时,需要将二进制流打包成网络包,经过RTMP协议传输
  • RTMP协议基于TCP协议,双方需要建立TCP连接。在TCP 的连接的基础上,还需要建立RTMP连接
  • RTMP连接主要用以协定版本号和时间戳(视频播放中,时间是很重要的,后面的数据流互通的时候,经常要带上时间戳的差值,因而一开始双方就要知道对方的时间戳。)

RTMP连接握手流程:

  1. 客户端发送自己的版本号(C0),不需等待应答,发送自己的时间戳(C1)
  2. 服务端收到C0后,返回自己的版本号(S0),若版本号不一致,断开连接。不需要等待客户端应答,服务端继续发送自己的时间戳(S1)
  3. 客户端在收到S1后,发送应答ACK  C2。同理,服务端在接收到客户端时间戳C1后,发送ACK S2。握手完成
  4. 握手完成后,双方传输控制信息(Chunk 块的大小、窗口大小等)

推流数据传输过程:

  1. 将 NALU 放在 Message 里面发送(RTMP Packet 包)
  2. 发送的时候,去掉 NALU 的起始标识符。因为这部分对于 RTMP 协议来讲没有用。接下来,将 SPS 和 PPS 参数集封装成一个 RTMP 包发送,然后发送一个个片的 NALU。
  3. RTMP 在收发数据的时候并不是以 Message 为单位的,而是把 Message 拆分成 Chunk 发送,而且必须在一个 Chunk 发送完成之后,才能开始发送下一个 Chunk。每个 Chunk 中都带有 Message  ID,表示属于哪个 Message,接收端也会按照这个 ID 将 Chunk 组装成 Message。(前面连接的时候,设置的 Chunk 块大小就是指这个 Chunk。将大的消息变为小的块再发送,可以在低带宽的情况下,减少网络拥塞。)

例子:假设一个视频消息长307,chunk大小为128,于是拆成以下三个

  • Chunk 的 Type=0,包含所有头部信息与128字节视频数据
  • Chunk的Type=3,不包含头部信息,包含128字节视频数据
  • Chunk的Type=3,不包含头部信息,包含51字节视频数据

完整推流过程:

  1. 建立RTMP连接,传输窗口大小、带宽等信息
  2. CreateStream创建流
  3. 发起推送publish,流开始,发送视频数据流

客户端拉取视频流程: 

  • 推送完后,观众可以通过 RTMP 协议从流媒体服务器上拉取直播视频。
  • 为了缓解服务器压力,可以使用分发网络。分发网络分为中心和边缘两层。边缘分发网络服务器部署在全国各地,和用户距离很近。中心网络是流媒体服务集群,可以进行视频内容转码和转发。智能负载均衡可以根据用户的地理位置,就近选择边缘服务器

4. 拉流

RTMP拉流过程:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值