前端应该了解的RTMP知识

2020-02-29  本文已影响0人  维李设论
前端 | 前端应该了解的RTMP知识.png

概述

RTMP是Real Time Messaging Protocol的简称,是基于何时的传输层协议上(如tcp协议)的应用层级别的协议,其设计是为了组包多媒体传输流(如视频,音频以及交互内容)

介绍

RTMP协议是由Adobe公司提出的一种应用层的协议,上面引述的是RTMP官方文档的introduction部分,其目的是为了给诸如视频、音频以及数据消息通信双方提供实时的信息双向流。RTMP在实现上对不同类型的消息实施不同的权重,这样可以实现对当传输量受限时的底层流传输消息进行排队。

定义

字节序 & 对齐 & 时间格式

所有的整字段以字节序来传输,并且是大端排列,不做特殊说明均为十进制。时间戳以毫秒记,从0开始,32位长;时间间隔用毫秒的无符号整数表示,可能是24或32位长度

RTMP块流

尽管RTMP是被设计用来实时传输消息的,但它也可以用来处理任何消息。RTMP非常适合用于大量的音视频应用,虽然并不会提供任何优化,但却被用于更高级别的协议来进行优化,例如直播视频服务器可能会选择在客户端网速较慢的情况下丢弃视频消息而保证音频消息的实时到达。

消息格式

消息格式可被分成许多块来提供多路复用,这些消息需要包括含以下字段:

字段名 含义 大小
时间戳(Timestamp) 消息的时间戳 4字节
长度(Length) 消息载荷的长度,如果消息头不能被省略,需要包含长度 3字节
类型ID(Type ID) 类型id被用于消息控制 1字节
消息流ID(Message Stream ID) 任意数值,小端存储 4字节

握手

RTMP握手不同于其他协议,它包含3个固定大小的块而不是可变大小的块

握手次序

开始时,客户端发送C0和C1

客户端必须在收到S1才能发送C2,收到S2才能发送任何其他数据

服务端必须等到收到C0才能发送S0和S1,并且最好能在收到C1后。服务端等到收到C1才能发送S2,服务端必须等到收到C2才能发送其他数据

C0 & S0 格式

C0和S0是一个8位组,被认为是一个8位整数段。对C0而言,这个字段被认为是客户端RTMP请求的版本;对S0而言,这个字段被认为是服务端选择的RTMP版本。默认是3,0-2被废弃,4-31被用于未来的版本,32-255没有被允许

 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|   version     |
+-+-+-+-+-+-+-+-+

C1 & S1 格式

C1和S1是一个1536位的长度组,包含如下字段:

字段名 含义 大小
时间(Time) 包含时间戳,可能是0也可能是任意的数值,用于时间标识 4字节
零(Zero) 必须都是0 4字节
任意数据(Random data) 任意数值,并不需要加密 1528字节
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        time (4 bytes)                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        zero (4 bytes)                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         random bytes                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         random bytes                          |
|                             (cont)                            |
|                              ....                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

C2 & S2 格式

C2和S2是一个1536位的长度组,对应S1和C1依次的回复,包含如下字段:

字段名 含义 大小
时间1(Time1) 时间戳,S1(C2发送)或C1(S2发送) 4字节
时间2(Time2) 时间戳,之前S1或C1 4字节
任意数据(Random data) 任意数值,可快速验证连接带宽或延时 1528字节
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        time (4 bytes)                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        time2 (4 bytes)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         random bytes                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         random bytes                          |
|                             (cont)                            |
|                              ....                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

握手简图

+---------------+                             +---------------+
|    Client     |        TCP/IP Network       |    Server     |   
+---------------+              |              +---------------+
        |                      |                      |
  Uninitialized                |                 Uninitialized
        |          C0          |                      |
        | -------------------> |          C0          |
        |                      | -------------------> |
        |          C1          |                      | 
        | -------------------> |          S0          |
        |                      | <------------------- |
        |                      |          S1          |
   Version sent                | <------------------- |
        |          S0          |                      |
        | <------------------- |                      |
        |          S1          |                      |
        | <------------------- |                 Version sent
        |                      |          C1          |
        |                      | -------------------> |
        |          C2          |                      |
        | -------------------> |          S2          |
        |                      | <------------------- |
     Ack sent                  |                    Ack sent
        |          S2          |                      |
        | <------------------- |                      |
        |                      |          C2          |
        |                      | -------------------> |
  Handshake Done               |                Handshake Done
        |                      |                      |

分块

握手之后,连接便可以进行多路传输块流,每个块携带着一种信息流的一种类型,每块流都有一个独一无二的id即块流id,通过网络传输,每个块必须满载,在接收端会根据id进行重新组装。分块允许通过更高阶的协议进行小信息的分拆,比如可以通过阻止大的低优先级消息(如视频)而阻塞小的高优先级消息(如音频或控制)。分块同样也允许更少的间接消耗将小的消息进行发送,比如块头包含有代表内容的压缩信息,也可能反过来包含在信息之中。块的大小是可配置的,大的块可减少CPU使用,但是却可能由于较多的写操作而带来其他内容低带宽的延迟,小的块不适合高比特流的传输,块的大小在每个方向上独立保持。

块格式

每个块包含头和数据,头包含三部分:

字段名 含义 大小
基础头(Basic Header) 块流id和块类型 1或3字节
消息头(Message Header) 消息的主要内容 0,3,7或11字节
扩展时间戳(Extended Timestamp) 某种情境下的时间戳 0或4字节
块数据(Chunk Data) 块的载荷 可变字节
+---------------+----------------+--------------------+----------------+
|  Basic Header | Message Header | Extended Timestamp |   Chunk Data   |
+---------------+----------------+--------------------+----------------+
|                                                     |
| <------------------ Chunk Header -----------------> |
                              Chunk Format

1.块基本头

有三种类型:

字段名 含义 大小
块流id(cs id) 数值2~63 6位
格式(fmt) 格式标识 2位
块流id-64(cs id - 64) 数值减去64 8或16位

块基础头1:

 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|fmt|   cs id   |
+-+-+-+-+-+-+-+-+

块基础头2:

 0                   1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt|     0     |   cs id - 64  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

块基础头3:

 0                   1                   2
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt|     1     |           cs id - 64          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2.块消息头

有四种类型:

Type 0:11字节

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   timestamp                   | message length|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   message length (cont)       |message type id| msg stream id |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            message stream id (cont)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 Chunk Message Header - Type 0

Type 1:7字节

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              timestamp delta                  | message length|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   message length (cont)       |message type id| 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 Chunk Message Header - Type 1

Type 2:3字节

 0                   1                   2      
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              timestamp delta                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         Chunk Message Header - Type 2

Type 3:没有头

公共头字段:

字段名 含义 大小
事件戳间隔(timestamp delta) 类型1或类型2 3字节
消息长度(message length) 类型0或类型1 3字节
消息类型id(message type id) 类型0或类型1 1字节
消息流id(message stream id) 类型0 4字节

3.扩展时间戳

当时间戳大于 16777215(0xFFFFFF)时使用

协议控制消息

消息类型ID为1,2,3,5,6是协议控制消息,这些内容需要块流协议做基础

设置块大小

用于提示设置最大字节,最大128字节,服务端和客户端可以修改这个值,并升级另一端的大小

中止消息

用于提示等待完成消息,之后丢弃部分接收的消息

识别

当接收字节和视窗大小相同时,客户端或服务端必须发送给对应端确认消息

视窗识别大小

当进行确认时,客户端或服务端发送给对应端视窗大小

设置端带宽

客户端和服务端向对应端发送输出限制

RTMP消息格式

RTMP可用各种传输层协议

RTMP消息

消息可以包含音频,视频,数据以及其他消息格式


1.消息头

包含消息类型,长度,时间戳,消息流id


2.消息载荷

实际消息承载内容

用户控制消息

消息类型为4

RTMP命令消息

客户端和服务端的消息相互操作

消息类型


1.命令消息

AMF0格式值为20 AMF3格式值为17


2.数据消息

AMF0格式值为18 AMF3格式值为15


3.共享对象消息

AMF0格式值为19 AMF3格式值为16


4.音频消息

值为8


5.视频消息

值为9


6.聚合消息

值为22


7.用户控制消息事件

命令类型


1.网络连接命令

连接 调用 创建流


2.网络流命令

播放 播放2 删除流 接收音频 接收视频 发布 寻址 暂停

参考

上一篇 下一篇

猜你喜欢

热点阅读