流媒体传输协议之 RTMP

网友投稿 318 2022-10-14


流媒体传输协议之 RTMP

作者:逸殊审核:泰一

简介

RTMP 在可靠流式传输(TCP)的基础上提供了双向的消息多路复用服务,在通讯双方之间传输与时间相关的并行流数据,如音频,视频和数据消息。协议实现方通常为不同的消息类型指定不同的优先级,这样在网络带宽受限时能改变底层传输顺序。

定义

以下是 C0 和 S0 包的字段解释:

上图提到的状态的解释如下:

上述图中各个部分的含义如下:

cs id (6 位):该字段表示完整的块流 ID,取值在 2-63 之间。0,1 两个值是保留值,用来表示基本头是 2 字节还是 3 字节长度。 fmt:该字段表明了消息头使用的格式。 cs id - 64 (8 位或 16 位):该字段表示块流 ID,取值在 64-63399 之间。

64-319 范围内的块流 ID 可以用 2 字节来表示,也可以用 3 字节表示。

消息头

消息头共有 4 种不同的格式,根据基本头中的 "fmt" 字段值来确定。协议实现方应该用最紧凑的格式来表示块消息头。

类型 0

类型 3

3 类型的块没有消息头,消息流 ID、消息长度和时间戳增量,该类型的块使用和上一个块相同的头数据。当一个消息被分割成块时,除了第一个块,其他块都应该使用该类型。由相同大小、消息流 ID 和时间间隔的消息组成的流,在类型 2 的块之后所有块都应该使用该类型格式。如果第一个消息和第二消息之间的时间增量与第一个消息的时间戳相同,则 0 类型的块之后可以马上发送 3 类型的块,而不必使用 2 类型的块来注册时间增量。如果类型 3 的块跟在类型 0 的块后面,那么 3 类型块的时间戳增量与 0 类型块的时间戳相同。

扩展时间戳

扩展时间戳用来辅助编码超过 16777215 (0xFFFFFF) 的时间戳或时间戳增量,也就说消息头无法用 24 位数字来表示时间戳或时间戳增量时,既 0 类型块的时间戳字段或 1,2 类型的时间戳增量字段值为 16777215 (0xFFFFFF)。当最近的属于相同块流 ID 的 0 类型块、1 类型块或 2 类型块有此字段时有此字段时,3 类型块也应该有此字段。

示例

示例 1

示例 2

第一个块的头信息指明了消息总大小为 307 字节。注意这两个示例,3 类型块可以在两种情况下使用。第一种情况是消息拆分成多个块,另一种情况是新消息复用上一个消息的所有头部内容。

协议控制消息

RTMP 块流用消息类型 1,2,3,5 和 6 来作为协议控制消息,这些消息包含 RTMP 块流协议所需要的信息。这些协议控制消息必须用 0 作为消息流 ID (控制流 ID),并在 ID 为 2 的块流中发送。协议控制消息收到后立即生效,它们的时间戳信息是被忽略的。

设置块大小

设置对方传输带宽

Limit Type(限制类型)有以下值:

消息有效负载

消息的另一部分就是有效负载,也是消息包含的实际数据,可以是音频样本或者压缩的视频数据。

用户控制消息

开头的 2 个字节用于指定事件类型,紧跟着是事件数据。事件数据字段长度可变,但是如果用 RTMP 块流传输,则消息总长度不能超过最大块大小,以使消息可以使用一个单独的块进行传输。

RTMP 指令消息

各种类型的消息在客户端和服务端之间进行交换,包括用于发送音频数据的音频消息,用于发送视频数据的视频消息,用于发送任意用户数据的数据消息,共享对象消息和指令消息等。共享对象消息的主要用途是管理客户端和相同服务器的共享数据。指令消息发送的是客户端与服务端之间的 AMF 编码指令,客户端或服务端也可以通过指令消息来实现远程过程调用(RPC)。

消息类型

客户端和服务端通过在网络上发送消息来实现交互,消息可以是任意类型,包括音频消息、视频消息、指令消息、共享对象消息、数据消息和用户控制消息等。

指令消息

指令消息在客户端和服务端之间传递 AMF 编码的指令,消息类型 20 代表 AMF0 编码,消息类型 17 代表 AMF3 编码。发送这些消息来完成连接、创建流、发布、播放、暂停等操作。像状态、结果这样的指令消息,用于通知发送方请求的指令状态。一条指令消息由指令名、事务 ID 和包含相关参数的指令对象组成。客户端或服务端还可以通过指令消息来实现远程过程调用 (RPC)。

数据消息

客户端或服务端通过该消息来发送元数据或其他用户数据。元数据包括数据 (音频、视频) 的创建时间、时长、主题等详细信息。消息类型 18 代表 AMF0 编码,消息类型 15 代表 AMF3 编码。

共享对象消息

支持以下事件类型:

组合消息的消息流 ID 会覆盖其中子消息的消息流 ID。组合消息的时间戳和其中第一个子消息的时间戳的差值,是用来将所有子消息的时间戳重整为流时间的位移量。位移量会加到每一个子消息的时间戳上来换算出正常的流时间。第一个子消息的时间戳应该与组合消息的时间戳相同,所以位移量应该为 0。Back Pointer (反向指针) 包含前一个消息的长度(包括消息头),这样符合 flv 文件格式,可用于进行后退操作。使用组合消息有以下好处:

用户控制消息支持以下事件:

指令执行的消息流如下:

CreateStream

NetStream 指令

基于 NetConnection 的客户端至服务器间连接,NetStream 定义了一条可以传递音频流、视频流以及消息流的通道。NetConnection 对象支持多个 NetStreams 以传输多个数据流。客户端可在 NetStream 中发送下列指令至服务器:

Play Play2 DeleteStream CloseStream ReceiveAudio ReceiveVideo Publish Seek Pause

Play

指令执行期间的消息流如下:

DeleteStream

服务器不需要发送任何应答。

ReceiveAudio

如果 receiveAudio 指令发送带有 flase 的 bool flag,服务器不发送任何响应。如果这个标志被设置为 true,服务器应答 NetStream.Seek.Notify 和 NetStream.Play.Start 的状态消息。

ReceiveVideo

如果 receiveVideo 指令发送带有 flase 的 bool flag,服务器不发送任何响应。如果这个标志被设置为 true,服务器应答 NetStream.Seek.Notify 和 NetStream.Play.Start 的状态消息。

Publish

服务器应答 onStatus 指令,以标记发布的开始。

Seek

当定位成功,服务器发送 NetStream.Seek.Notify 的状态消息。失败的时候,它返回一个_error 的消息。

Pause

当流被暂停,服务器发送一个 NetStream.Pause.Notify 的状态消息。当一个流变成未暂停状态,NetStream.Unpause.Notify 被发送。失败的时候,它返回一个_error 的消息。

消息交换例子

这里是一些样例,以解释使用 RTMP 的消息交换。

发布视频

广播一个共享对象消息

发布媒体流元数据

参考内容

[1] RTMP 规范[2] RTMP 协议规范翻译工作[3] RTMP 协议规范 1.0 中文版


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:DNS理论篇
下一篇:总结Java对象被序列化的两种方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~