在实际的传输过程中应该是将Message分成一个一个的Chunk块去传输,图中的1应该为一个chunk块。
RTMP消息的数据格式
(1)RTMP消息由 Header 和 Body 组成。
(2)RTMP的Header 由3个部分组成Basic Header(基本头信息,必须),Message Header(消息头信息,可选),Extended Timestamp(扩展时间戳,可选)
(3)Basic Header(基本头信息)是动态变化的,第一个字节由2部分组成,第一部分fmt(占2位),第2部分,表示chunk stream id(6位,能表示0-63,其中0和1由特殊意义)
对于消息流 ID 小于 64 的消息,基本头部占用 1 个字节,格式如下:第 1 位(Bit 0):格式类型(Fmt Type),占据头部的前两位,用来表示消息类型。后面 6 位:消息流 ID(Chunk Stream ID)的低 6 位,用来表示消息所属的消息流 ID。
对于消息流 ID 大于等于 64,但小于 320,基本头部占用 2 个字节,格式如下:第 1 位(Bit 0):格式类型(Fmt Type)。第 2 位至第 7 位:消息流 ID(Chunk Stream ID)的低 6 位加上 64,用来表示消息所属的消息流 ID。第 8 位至第 15 位:消息流 ID 的高 8 位,用来表示消息所属的消息流 ID。
字节数为3位的如下图所示,分析同上。ID的计算方法为(第三字节*256+第二字节+64)(Basic Header是采用小端存储的方式),范围为 [64,65599]。(在第一幅图中似乎有点偏差,欢迎讨论)
下面分析一下Message Header(可以忽略):
mesage Header(消息头信息) 也是可变的,
3字节的时间戳(TimeStamp),
3字节消息长度(MsgLength),
1字节消息类型(TypeID),
4字节的streamID。
message header 是可选的,由fmt控制,fmt=10b(只有时间戳),fmt=01b(只有前3个),fmt=00b(有全部),fmt=11b(全不要)
对于第一个数据包:fmt=00b,全部都需要。
当一个包非常大,拆成多个chunk,由于是同个流,所以streamID相同fmt=01b,就满足要求 。
当我们设置每个chunk长度相同,msgLength 都一致,所以,fmt=10b,就满足要求
接着介绍一下extended Timestamp:
当3个字节的TimeStamp 不能保存,则可以使用 extended Timestamp(扩展时间戳)
当3个字节的Timestamp位为0xFFFFFF,则使用扩展时间戳
下面介绍一下常见的一些RTMP消息类型
消息类型(typeID) 1-6 控制消息 1 设置 Chunk 大小。默认128 2 流结束 3 ACK (确认) 5 窗口大小 (数据量大小) 6 传输带宽 对于命令类,SID(StreamID)都为0,CSID(chunk stream ID)都为2 8-9 数据类型 8 音频数据 9 视频数据 剩下:命令消息 Data Message:音视频大小,帧率,采样率,采样大小(metaData) AMF0和AMF3:flash的一种格式(类似 KLV) Shared Object Message:共享对象消息 Command Message:命令消息