音视频理论(2)- 音视频传输协议之 RTMP
目录
RTMP
一、总体介绍
RTMP(Real Time Messaging Protocol)实时消息传送协议是 Adobe 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的开放协议。RTMP 协议工作在 TCP 之上,默认使用 1935 端口。
工作原理:RTMP 的 message 会切分为 n 个 chunk,再通过 TCP 协议传输。
为什么 rtmp 基于 tcp 协议,tcp 协议已经有化整为零的方式, rtmp 还需要将 message 划分更小的单元 chunk 呢?
分析原因:
1. tcp 协议划分一个个 tcp 报文,是为了在网络传输层上保障数据连续性,丢包重发等特性。
2. rtmp 划分 chunk 消息块,是为了在网络应用层上实现低延迟的特性,防止大的数据块(如视频数据)阻塞小的数据块(如音频数据或控制信息)。
二、结构组成
1. Message 结构
RTMP 协议消息头(RTMP Message Header)结构如下图所示:
参数分析:
Message Type(1 byte),消息类型,这个参数很重要,当写程序的时候需要根据不同的消息,做不同的处理。
Payload length(3 bytes),表示负载的长度(big-endian 格式)。
Timestamp (4 bytes),时间戳(big-endian 格式),超过最大值后会翻转。
Stream ID (3 bytes) ,消息流 ID(big-endian 格式),用于区分不同流的消息。
Message Payload,真实的数据。
2. Chunk 结构
RTMP 收发的数据称为 Message,所谓 Message 不外乎音视频数据和信令,而真正收发数据时把 Message 拆分为 Chunk 发送,每个 Chunk 的默认大小是 128 字节,当然这个大小可以通过控制信息来修改。Chunk 由 Chunk Header 和 Chuk Data 组成。
2.1 Chunk header:
RTMP 块头(RTMP Chunk Header)结构如下图所示:
2.2 Basic header:
RTMP 块基础头(RTMP Chunk Basic Header),一般是一个字节大小,结构大小如下图所示:
RTMP Chunk 包一般是由一个固定长度的包头和一个最长为 chunk default size 字节的包体(默认 128 字节)组成,包头可以是下面 4 种长度的任意一种:12, 8, 4, or 1 byte(s)。
第一个字节的前两个 Bit 很重要,它决定了包头的长度,它可以用掩码 0xC0 进行"与"计算。
format=0,Chunk Header length = 12 bytes,在一个 chunk 流的开始、时间戳返回的时候必须有这种块,比如:onMetaData, 音视频流刚开始的绝对时间戳,控制消息。
此时,基础头和块消息头(Basic header + Chunk Msg Header)结构如下图所示:
format=1,Chunk Header length = 8 bytes,对于可变大小消息的 chunk 流,在第一个消息之后的每个消息的第一个块应该使用这个格式。
此时,基础头和块消息头(Basic header + Chunk Msg Header)结构如下图所示:
format=2,Chunk Header length = 4 bytes,对于固定大小消息的 chunk 流,在第一个消息之后的每个消息的第一个块应该使用这个格式。
此时,基础头和块消息头(Basic header + Chunk Msg Header)结构如下图所示:
format=3,Chunk Header length = 1 bytes,当一个消息被分成多个块,除了第一块以外,所有的块都应使用这种类型。
此时,基础头和块消息头(Basic header + Chunk Msg Header)结构如下图所示:
注意事项:
1)timestamp 的长度为 3 bytes,当 timestamp 被设置为 0x00ffffff,chunk header 会加上 Extended Time Stamp 字段,否则 Extended Time Stamp 不会出现。
2)多个 Chunk 怎么标记同属于一个 Message 的呢?
其一、是通过 Chunk Stream ID 区分的,同一个 Chunk Stream ID 属于同一个 Message。
其二、因为 TCP 的有序,同一个 Message 中不同的 Chunk 会先后抵达。
音频 Chunk
以 FLV AAC 为例,协议层结构如下图所示:
FLV 音频标识头(FLV AudioTagHeader)结构如下图所示:
视频 Chunk
以 FLV AVC 为例,协议层结构如下图所示:
FLV 视频标识头(FLV VideoTagHeader)结构如下图所示:
FLV 视频标识结构体(FLV VideoTagBody)结构如下图所示:
3. Message 和 Chunk 的组成关系
3.1 Message 结构组成:
3.2 Message 拆分 Chunk 实例:
4. Message 类型
Message 消息主要分为三类: 协议控制消息、数据消息、命令消息等。
a.协议控制消息
Message Type ID = 1~6,主要用于协议内的控制。
b.数据消息
Message Type ID = 8 9 18(15),其中
8: Audio 音频数据
9: Video 视频数据
18(15): 对应 AMF0(AMF3),Metadata 包括音视频编码、视频宽高等信息。
c.命令消息 Command Message (20, 17)
此类型消息主要有 NetConnection 和 NetStream 两个类,两个类分别有多个函数,该消息的调用,可理解为远程函数调用。
最后来张图吧,这样更形象点:
三、建立握手
1. 连接失败(两次试探)
2. 连接成功(握手)
2.1 握手流程:
2.1.1 简单握手模式
2.1.2 复杂握手模式
接下来看一个连接实例,结合 wireshark 抓包结果来看一下整个流程:
2.2 推流
2.3 拉流
四、保存文件
以 flv 文件格式为例,可以通过文件开头的三个字节来判断该文件是否为 FLV,其中 F(46)、L(4c)、V(56)。
五、与其他协议对比
其实,与 RTMP 类似的流媒体协议,还有 HLS、HTTP-FLV,下图对三者进行了一个简单的对比。
版权声明: 本文为 InfoQ 作者【liuzhen007】的原创文章。
原文链接:【http://xie.infoq.cn/article/6c82dfad055da2676c0b21ddc】。文章转载请联系作者。
评论