音视频传输协议之RTMPRTMP

本文正在参与 “网络协议必知必会”征文活动

目录

RTMP

一、总体介绍

二、结构组成

1. Message结构

2. Chunk结构

注意事项:

         音频Chunk

         视频Chunk

         3. Message和Chunk的组成关系

4. Message类型

三、建立握手

四、保存文件

五、与其他协议对比

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,下图对三者进行了一个简单的对比。 

作者简介:大家好,我是 Data-Mining(liuzhen007),是一位音视频技术爱好者,前后就职于传统广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解,公众号:玩转音视频。同时也是 CSDN 博客专家、华为云社区云享专家、签约作者,欢迎关注我分享更多干货!