视频直播常见协议: RTMP

RTMP

RTMP(real time messaging protocol)实时消息传输协议
RTMP 给予TCP协议 是一个协议族 包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种
RTMP 内部使用的格式为 FLV

基本原理: RTMP是基于TCP的三次握手之后的 它本身是基于TCP的可靠性连接
客户端与服务器端通过字段内容协商来完成可信度认证
client 客户端需要发三个包 C0 C1 C2
server 服务器端需要发送三个包 S0 S1 S2
握手方式:

  1. 客户端发送 C0 C1 到服务器端
  2. 服务器端发送 S0 S1 到客户端
  3. 客户端发送C2到服务器端 服务器端发送S2到客户端

有一些细节需要注意
握手开始

  • 客户端发送C0 C1 包
    此时客户端处于等待状态 有两个限制: 1.客户端在未接收到S1之前不能发送C2包;2.客户端在未接收到S2之前不能发送任何实际数据包
  • 服务器端在接收到C0后 发送S0 S1包 也可以等到接收到C1之后一起发送 C1包的等待不是必须的
    此时服务器端处于等待状态 有两个限制:1.服务器端在未接收到c1前不能发送S2;2.服务器端在未接收到C2前不能发送任何实际数据包
  • 客户端在接收到 S0 S1包后 发送C2包
  • 服务器端在接收到C2包后 发送S2包 此时三次握手完成

在实际应用中 因为RTMP不是强安全性的协议 所以S2/C2只需C1/S1包中的内容 就可以完成内容的拼接

C/S 0 1 2包

C0 S0
C0 S0 长度为 1B
C0 客户端发送2其所支持的RTMP版本号 3~31 一般为3
S0 服务器端反悔哦其所支持的RTMP的版本号 默认返回3

C1 S1
C1 S1 长度为 1536B
格式为 时间戳(time 4B) + 保留值(0 4B) + 随机值(random 1528B)
random 主要用于保证此次握手的唯一性 和确定握手的对象

C2 S2
C2 S2 长度为 1536B 相当于是 S1 C1的响应值
在内容上
服务器端将收到的C1中的保留值替换为time2(S1发送的时间戳)
客户端将受到的S1中的保留值替换为time2(C1发送的时间戳)
其余部分与S1 C1一致

RTMP基本架构

  • message
  • – PCM(type id 1~6 ex4)
  • – UCM(type id 4)
  • – Command Msg(type id >=7)

Message作为父项 其基本结构为 Header + Body
Header 分为 basic header 和 message header 后者的结构由前者的内容决定

Basic Header (BH)
定义了该CS ID(chunk stream id) 和 chunk type
BH是变长的 长度范围为 1-3B 根据不同的CSid 决定具体长度
RTMP中规定 CSid 的0 1 2为保留字 设置时只能从3开始
CS ID:0 BH长2B
CS ID:1 BH长3B
CS ID:2 BH长2B

Message Header (MH)
根据前面BH中fmt字段的定义可以分为四种MH 或者说就是一种MH格式化会存在从繁到简四种
fmt:0 完整的MH
fmt:1 MH长7B 此类型不带msg stream id
fmt:2 MH长3B 此类型质保函一个timestamp delta字段
fmt:3 此时RTMP中就没有了MH 此情况要求前面几个包必须存在 fmt为0/1/2的情况

以上为Message Header的共用部分 对于具体的RTMP Message 里面的type会针对不同的业务场景有不同的格式

Message Body (MB)
PCM
全称为 Protocol Control Messages 主要用来沟通RTMP初始状态的相关链接信息
PCM一共有5种不同的Message类型 是根据Header中的typeID决定的 范围是1-6(不包括4)
PCM在构造时需要将Header中的 message stream id 和 chunk stream id设置为固定值
message stream id 为 0
chunk stream id 为 2

  • typeID:1 ==>SCS(Set Chunk Size) 设置server 和 client之前正式传输信息的chunk的大小 一般默认为128B
  • typeID:2 ==>Abort Message 告诉client 丢弃指定的stream中 已经加载到一半或者还未加载完的Chunk Message;他需要一制定一个Chunk stream ID
  • typeID:3 ==>Acknowledgement 实际为一个ACK包 表示两次ACK之间 接收端所能接收的最大字节数
  • typeID:5 ==>Window Acknowledgement Size 用来协商发送包的大小 主要针对客户端可接收的最大数据包的值 而chunk size是指每次发送包的大小 。 此处也可以叫做 Window size 一般电脑设置的大小都是500000B
  • typeID:6 ==>Set Peer Bandwidth 根据网速来改变发送包的大小 他的格式和WAS类似 后面带上一个Type用来标明当前带宽限制算法

UCM
全称为 User Control Message 它的typeID只能为 4 用于发送一些对视频 的控制信息
UCM在构造时也有一定限制
message stream id 为 0
chunk stream id 为 2

Command Msg
typeID 包括8-22 具体内容如图视频直播常见协议: RTMP
的选项中有两个ID 这个AMK版本选择有关
第一个ID表示AMK0的编解码方式
第二个ID表示AMK3的编解码方式
比较重要的是 command Msg Video Auido 这三个Msg

Video Msg
RTMP协议是一个长链接 是根据自己的自定义协议来分端传输FLV Tag的
RTMP只是一个传输工具 具体传送内容是由具体的流生成框架来决定的
RTMP是主动将Video和Audio分开传输的 所以他需要交叉发布Video和Audio 以保证音视频的同步
音视频同步
有三种:

  1. 以Audio为准 Video同步Audio
  2. 以Video为准 Audio同步Video
  3. 以外部时间为准AV同时同步

Command Msg
Command Msg 是RTMP里面的一个主要信息传递工具 常用在RTMP前期和后期处理
Command Msg 通过AMF金信传输的 主要分为两大块
net connect
net stream
他的交流方式是双向的 另外一端都必须返回一个_result或者_error

NetStream Msg
在直播流中 比较重要的只有play包
play包用来告诉Server正是播放音视频流 由于RTMP天然做多流分发的 如果遇到网络出现相应的波动 客户端可以根据的条件多次调用play命令 来切换不同模式的流