Adobe RTMP 规范:实时消息传递协议详解

Adobe 的实时消息传递协议(RTMP),是一种应用层协议,旨在通过适当的传输协议(如 TCP)多路复用和打包多媒体传输流(如音频、视频和交互内容)。以下是对 RTMP 规范的详细解析。

友情链接:ACEJoy

文档概述

文件状态

本文档是 2012 年 12 月 21 日发布的 “Adobe 的实时消息传递协议” 规范的机器可读版本。自 2012 年 PDF 版本以来,规范内容并未发生实质性变化,仅在格式和文字编辑上有所调整。

引言

RTMP 提供了在可靠的流传输(如 TCP)上的双向消息多路复用服务,旨在携带视频、音频和数据消息的并行流,并附带相关的时间信息。实现通常会为不同类别的消息分配不同的优先级,这会影响在传输容量受限时消息入队到底层流传输的顺序。

术语

  • MUST: 必须
  • REQUIRED: 必需
  • SHALL: 应该
  • SHOULD: 建议
  • MAY: 可以

贡献者

  • Rajesh Mallipeddi:原 Adobe Systems 编辑,提供了大部分原始文本。
  • Mohit Srivastava:Adobe Systems 贡献者。

定义

  • Payload: 包含在数据包中的数据,如音频样本或压缩视频数据。
  • Packet: 由固定头和负载数据组成的数据包。
  • Port: 传输协议用来区分主机内多个目的地的抽象。
  • Transport address: 用于识别传输层端点的网络地址和端口的组合。

字节顺序、对齐和时间格式

  • 所有整数字段按网络字节顺序(大端序)传输。
  • 时间戳以毫秒为单位,相对于一个未指定的纪元。

RTMP 块流

消息格式

消息格式应包含以下必要字段:

  • Timestamp: 消息的时间戳(4 字节)。
  • Length: 消息负载的长度(3 字节)。
  • Type ID: 消息类型 ID(1 字节)。
  • Message Stream ID: 消息流 ID(4 字节,小端序)。

握手

RTMP 连接从握手开始,客户端和服务器各发送相同的三个块(C0、C1、C2 和 S0、S1、S2)。

块化

在握手后,连接多路复用一个或多个块流。每个块流携带一种类型的消息。每个块都有唯一的块流 ID。块的传输顺序必须完整发送。接收端根据块流 ID 重新组装消息。

块格式

每个块由一个头和数据组成。头有三个部分:

  • Basic Header: 编码块流 ID 和块类型(1-3 字节)。
  • Message Header: 编码关于消息的信息(0、3、7 或 11 字节)。
  • Extended Timestamp: 编码完整的 32 位时间戳(0 或 4 字节)。

RTMP 消息格式

消息头

消息头包含以下字段:

  • Message Type: 消息类型(1 字节)。
  • Length: 负载大小(3 字节)。
  • Timestamp: 消息的时间戳(4 字节)。
  • Message Stream ID: 消息流 ID(3 字节)。

用户控制消息

RTMP 使用消息类型 ID 4 进行用户控制消息。这些消息包含 RTMP 流层使用的信息。

RTMP 消息类型

命令消息

携带客户端和服务器之间的 AMF 编码命令。命令消息有两个类型值:20 表示 AMF0 编码,17 表示 AMF3 编码。

数据消息

用于发送元数据或用户数据。类型值为 18(AMF0)和 15(AMF3)。

共享对象消息

用于管理多个客户端和服务器之间的分布式数据。类型值为 19(AMF0)和 16(AMF3)。

音频消息

用于发送音频数据,类型值为 8。

视频消息

用于发送视频数据,类型值为 9。

聚合消息

包含一系列RTMP 子消息的单一消息。类型值为 22。

消息交换示例

发布录制视频

此示例说明发布者如何发布流并将视频流发送到服务器。其他客户端可以订阅此发布的流并播放视频。

+--------------------+                     +-----------+
|  Publisher Client  |        |            |   Server  |
+----------+---------+        |            +-----+-----+
          |           Handshaking Done           |
          |                  |                  |
          |                  |                  |
---+---- |----- Command Message(connect) ----->|
   |     |                                     |
   |     |<----- Window Acknowledge Size ------|
Connect |     |                                     |
   |     |<------ Set Peer BandWidth ----------|
   |     |                                     |
   |     |------ Window Acknowledge Size ----->|
   |     |                                     |
   |     |<----- User Control(StreamBegin) ----|
   |     |                                     |
---+---- |<-------- Command Message -----------|
          |   (_result- connect response)       |
          |                                     |
---+---- |--- Command Message(createStream) -->|
Create |     |                                     |
Stream |     |                                     |
---+---- |<------- Command Message ------------|
          | (_result- createStream response)    |
          |                                     |
---+---- |---- Command Message(publish) ------>|
   |     |                                     |
   |     |<----- User Control(StreamBegin) ----|
   |     |                                     |
   |     |---- Data Message (Metadata) ------->|
Publishing|     |                                     |
Content   |     |------------ Audio Data ------------>|
   |     |                                     |
   |     |------------ SetChunkSize ---------->|
   |     |                                     |
   |     |<--------- Command Message ----------|
   |     |      (_result- publish result)      |
   |     |                                     |
   |     |------------- Video Data ----------->|
   |     |                  |                  |
   |     |                  |                  |
          |    Until the stream is complete     |
          |                  |                  |

广播共享对象消息

此示例说明在创建和更改共享对象期间交换的消息。它还说明了共享对象消息广播的过程。

+----------+                       +----------+
|  Client  |           |           |  Server  |
+-----+----+           |           +-----+----+
       |   Handshaking and Application    |
       |          connect done            |
       |                |                 |
       |                |                 |
       |                |                 |
       |                |                 |
Create and ---+---- |---- Shared Object Event(Use)---->|
connect       |     |                                  |
Shared Object |     |                                  |
---+---- |<---- Shared Object Event --------|
       |       (UseSuccess,Clear)         |
       |                                  |
---+---- |------ Shared Object Event ------>|
Shared object |     |         (RequestChange)          |
Set Property  |     |                                  |
---+---- |<------ Shared Object Event ------|
       |            (Success)             |
       |                                  |
---+---- |------- Shared Object Event ----->|
Shared object|     |           (SendMessage)          |
Message      |     |                                  |
Broadcast ---+---- |<------- Shared Object Event -----|
       |           (SendMessage)          |
                          |                 |
                          |                 |

从录制流发布元数据

此示例描述了发布元数据的消息交换。

+------------------+                       +---------+
| Publisher Client |         |             |   FMS   |
+---------+--------+         |             +----+----+
       |     Handshaking and Application     |
       |            connect done             |
       |                  |                  |
       |                  |                  |
---+--- |-- Command Messsage (createStream) ->|
Create |    |                                     |
Stream |    |                                     |
---+--- |<-------- Command Message -----------|
       |   (_result - command response)      |
       |                                     |
---+--- |---- Command Message (publish) ----->|
Publishing |    |                                     |
metadata |    |<----- UserControl (StreamBegin) ----|
from file |    |                                     |
          |    |---- Data Message (Metadata) ------->|
       |                                     |

参考文献

  • RFC0791: Postel, J., “Internet Protocol”, STD 5, RFC 791, September 1981.
  • RFC0793: Postel, J., “Transmission Control Protocol”, STD 7, RFC 793, September 1981.
  • RFC1982: Elz, R. and R. Bush, “Serial Number Arithmetic”, RFC 1982, August 199

发表评论