rtmp规范1.0全面指南

RTMP(real time messaging protocol)协议程序员

本文为Adobe rtmp规范1.0的中文介绍,其中内容大部分都是翻译自rtmp官方文档rtmp_specification_1.0.pdf算法

具体文章目录参见文章内侧边栏服务器

介绍

Adobe的实时消息传输协议(RTMP)经过可靠的流传输(如TCP [RFC0793])提供双向消息多路传输服务,用于在端到端之间传输带有时序信息的视频,音频和数据消息的并行流。 穿过多层流,RTMP消息块流不提供任何控制的优先级别和类似形式,可是能够用于高层协议提供这样的优先级,例如:一段实时视频服务会选择丢弃给缓慢的客户的视频信息确保音频信息能够及时被接收。RTMP消息块流包含它本身的入队协议控制消息,也提供一个高层协议机制用于嵌入用户的控制消息。网络

定义

有效负载:Payloadapp

包含在包中的数据,就像音频样本或者压缩的视频数据。dom

包:Packet异步

一个数据包由固定的包头和有效负载数据组成,一些底层协议或许须要包的封装来被定义。分布式

端口:Portide

TCP/IP协议中定义的用正整数表示的端口号用于在传输中提取以区分目标主机的不一样应用,用于OSI传输层的传输选择(TSEL)就是端口。性能

传输地址:Transport address

网络地址和端口的组合识别一个传输层终端端口,例如一个IP地址和TCP端口,数据包从一个源传输层地址传送到目标段的传输层地址。

消息流:Message stream

一个通讯的逻辑通道,容许消息流通。

消息流ID:Message stream ID

每个消息拥有一个分配的ID识别跟随的消息流。

消息块:Chunk

消息的片断,消息被分红小的部分,在他们在网络中发送以前交叉存储。消息块确保定制时间戳的端到端全消息传送,穿过多层流。

消息块流:Chunk stream

一个通讯的逻辑通道,容许消息块在一个特定的方向上流通,消息块流能够从客户端传送到服务器,也能够相反。

消息块流ID:Chunk stream ID

每个消息块有一个分配的ID用于识别更随的消息块流。

复合技术:Multiplexing

把分开的音视频数据组合成一条音视频流的过程,使同时传送许多音视频数据成为可能。

逆复合技术:DeMultiplexing

复合的反向过程,交叉存取组装的音频视频数据,使他们成为最初的音视频数据

远程过程调用:Remote Procedure Call (RPC)

容许客户端或服务器在对等端调用子例程或过程的请求。

Action Message Format (AMF)

一种紧凑的二进制格式,用于序列化ActionScript object graphs。 能够透过 AMF overHTTP的方式将flash端资料编码后传回server,server端的remoting adaptor接收到资料后则会译码回正确的native对象,交给正确的程序处理。

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

全部的整数字段都被引入到了字节顺序当中,字节0是第一个显示出来的,也是一个词和一个字段中最重要的。这种顺序就是一般所说的“大端”。若是没有特殊说明,在本文档中数字常量都是用十进制表示。

除另有规定外,RTMP中的全部数据都是字节对齐的。例如,一个16位字段可能处于奇数字节偏移处。 在指定填充的地方,填充字节应该是0。

RTMP中的时间戳相对于未指定的时期是以整数毫秒为单位给出的。 一般,每一个流将以时间戳0开始,但这不是必需的,只要两个终端在时间点上达成一致。 请注意,这意味着跨多个流(尤为是来自不一样主机)的任何同步都须要一些RTMP外的其余机制。

时间戳必须始终在线性的增长,容许应用程序处理异步传输,带宽度量,检测,和流控制。

因为时间戳长度为32位,所以它们每隔49天,17小时,2分钟,47.296秒滚动一次。 因为流能够连续运行,可能持续数年,RTMP应用程序应该在处理时间戳时使用序列号算法[RFC1982],而且应该可以处理回绕。 例如,假定全部相邻的时间戳都在2^31 - 1毫秒之间,因此10000会在4000000000以后,而3000000000会在4000000000以前。

时间戳增量delta也被指定为相对于先前时间戳的无符号整数毫秒数。 时间戳增量delta能够是24位或32位。

RTMP块流

本节介绍实时消息传送协议块流(RTMP块流)。 它为更高级别的多媒体流协议提供复用和打包服务。 虽然RTMP Chunk Stream旨在与实时消息传送协议配合使用,但它能够处理发送消息流的任何协议。 每条消息都包含时间戳和有效负载类型标识。 RTMP Chunk StreamRTMP一块儿适用于各类音频 - 视频应用,从一对一和一对多实时广播到视频点播服务,再到交互式会议应用。

当与可靠的传输协议(如TCP [RFC0793])一块儿使用时,RTMP块流提供了保证全部消息在多个流中按时间排序的端到端传送。 RTMP块流不提供任何优先级或相似的控制形式,但能够由更高级别的协议提供这种优先级。

消息格式

能够拆分红块以支持复用的消息格式取决于更高级别的协议。 可是,消息格式应该包含下列建立块所必需的字段。

时间戳:

消息的时间戳,这个字段能够传输4个字节。

长度:

消息的有效负载的长度,若是消息头不能被省略,它应该包含在长度中,这个字段在消息块包头中占有3个字节。

类型ID:

协议控制消息的类型字段的范围是被保留的,这些传播信息的消息由RTMP消息块和高层协议处理,全部其余的类型ID可被高层协议使用,对RTMP消息块来讲当作不透明的值,实际上,RTMP Chunk Stream中的任何内容都不须要将这些值用做类型; 全部(非协议)消息能够是相同类型的,或者应用程序可使用类型id来区分同步踪影而不是类型。 该字段占用块头中的1个字节。

消息流ID:

消息流ID能够是任意的值。 复合到相同块流上的不一样消息流能够基于它们的消息流ID进行逆复合操做。 除此以外,就RTMP块流而言,这是一个不透明的值。 该字段以小尾数格式占用块头中的4个字节。

握手

RTMP链接始于握手。 rtmp握手与其余协议的握手不一样; 它由三个相同大小的块组成,而不是由可变大小的块组成。

客户端(链接已初始化的终端)和服务器都发送相同的三个块。 为了说明,由客户端发送的3个块分别为C0, C1, C2,由服务端发送的3个块分别为S0, S1, S2

握手的顺序

握手以客户端发送C0C1消息块位开始,客户端必须等到S1到达在发送C2。客户端必须等到S2接收到才能够发送其余的数据;服务端必须等到C0到达才发送S0S1,在C1以后也会等待。服务端必须等到C1到达才发送S2,服务端必须等到C2到达后才发送其余数据。

C0和S0格式

C0S0都是单个8位字节,能够当作一个8位整形字段。

8比特版本:在C0中,这个字段识别客户端需求的RTMP的版本,在S0中,这个字段识别服务器端选择的RTMP的版本,被定义的是版本3,0到2是早前的版本使用的,4到31保留用于将来使用,32到255尚未被容许。不能区分客户的请求的版本的服务应该以3返回,客户端能够选择降级到版本3,或放弃握手。

C1和S1格式

C1S1包长度为1536个8位字节,包含如下字段:

time(4个字节):这个字段包含时间戳,被当作后续消息块从终端发送的时间点,也许是0,或者一些任意的值。为了同步多路消息块流,终端或许但愿发送其余消息块流的时间戳的当前值。

zero(4各个字节):这个字段必须全0。

random data(1528个字节):这个字段能够包含任何任意的值,由于每一个终端必须区分本身初始化的握手的返回数据和对方初始化的握手的返回数据,这个数据应该发送一些随机数。可是没有必要用密码保护随机数和动态值。

C2和S2格式

C2S2包长度为1536个8位字节,分别相似于S1C1的原样返回,由一下几个字段组成:

time(4个字节)

这个字段必须包含由对端发送的S1(对应C2)或者C1(对应S2)的时间戳.

time2(4个字节)

这个字段必须包含先前的由对端发送的数据包(S1或者C1)被读取的时间戳。

random echo(1528个字节)

这个字段必须包含在对端发送的S1(对应C2)或S2(对应C1)数据包中的随机数据字段。 任何一方均可以使用timetime2字段与当前时间戳一块儿快速估算链接的带宽和/或延迟,但这不太可能有用。

握手过程图

下面的表格描述了握手过程的几个阶段

阶段 描述
未初始化 协议版本在此阶段发送。 客户端和服务器都未初始化。 客户端发送数据包C0中的协议版本。 若是服务器支持该版本,则发送S0S1做为响应。 不然,服务器将采起适当的措施进行响应。 在RTMP中,此操做正在终止链接。
版本发送 在未初始化状态以后,客户端和服务器都处于版本已发送状态。 客户端正在等待数据包S1,服务器正在等待数据包C1。 在接收到等待的数据包时,客户端发送C2而且服务器发送S2。 状态而后变成Ack发送。
ACK发送 客户端和服务端分别等待S2C2
握手完成 客户端和服务交换消息。

消息分块

握手后,链接复用一个或多个消息块流。每一个块流从一个消息流携带一种类型的消息。每一个建立的块都有一个与其关联的惟一ID,称为块流ID。这些块经过网络传输。发送时,每一个块必须在下一个块以前所有发送。在接收端,根据块流ID将块组合成消息。

分块容许将较高级别协议中的大的型消息分解为较小的消息,例如防止较大的低优先级消息(例如视频)阻塞较小的高优先级消息(如音频或控制)。

分块还容许以较少的开销发送小消息,由于分块头包含信息的压缩表示信息,这些压缩消息原本应该包含在消息自己的。

块大小是可配置的。它可使用Set Chunk Size控制消息进行设置。

消息块格式

每个消息块有头部和数据组成,头部自身能够被分割成三个部分:

消息块基本头(1到3个字节):这个字段编码了消息块流的ID和消息块的类型,消息块类型决定了消息包头的编码格式,长度彻底取决于可变长的消息块流ID。

消息块消息头(0,3,7或11字节):这个字段编码正在传送的消息的信息,长度能够利用在消息块头中详细的消息块类型来决定。

扩展时间戳(0或4字节):此字段在某些状况下是存在的,取决于消息块消息头中的编码时间戳或时间戳增量字段。

消息块块数据(可变大小):该块的有效负载,直至配置的最大块大小。

消息块基本头

消息块基本头对消息块流的ID和消息块的类型进行编码(在下面的图表中用fmt表示),消息块类型决定了编码的消息头的格式,消息块基本头字段能够是1,2或者3个字节长,取决于消息块流ID。

该协议支持多达65597个ID为3-65599的流。 ID0,1和2被保留。 值0指示2字节形式和64-319范围内的ID(the second byte + 64)。 值1表示3字节形式,ID在64-65599((the third byte) * 256 + the second byte + 64)范围内。 在3-63范围内的值表示完整的流ID。 块ID为2的流ID保留,用于低级别的协议控制消息和命令。

在消息块基本头中0-5比特(最不重要的)表明了消息块流ID。

消息块流ID 2-63 能够被编码成这个字段的单字节的版本号。

块流ID 64-319能够以2字节的形式被编码。 ID计算为(第二个字节+ 64)。

能够在此字段的3字节版本中对块流ID 64-65599进行编码。 ID计算为((第三字节)* 256 +(第二字节)+64)。

cs id(6比特):这个字段包含了消息块流ID,值从2到63,值0和1用于表明这个字段的2个或者3个字节的版本号。

fmt(2比特):这个字段标识消息块消息头使用的四种格式之一。见下一小节

cs id -64(8或者16个比特)

这个字段包含了消息块流ID减64,例如ID 365在cs id段用1表示,在16比特的cs id -64段用301表示。

值为64到319的消息块流ID能够被2字节或者3字节的版本号来表示。

消息块消息头

在消息块消息头中有四种不一样的格式,由消息块基本头的fmt字段选择。应该使用最简洁的表达方式表示每个消息块消息头。

类型0

类型0的消息块有11个字节长,这个类型必须在消息块流开始时和消息流的时间戳回溯时使用

时间戳(3个字节):对于类型0的块,消息的绝对时间戳发送到此处。 若是时间戳大于或等于16777215(十六进制0xFFFFFF),则该字段必须是16777215,表示存在扩展时间戳字段以编码完整的32位时间戳。 不然,这个字段应该是整个时间戳。

类型1

类型1的消息块有7个字节长,消息流ID没有被包含,这个消息块获得和先前消息块一样的流ID,带有可变长的消息的流(例如许多视频格式)在类型0消息块后应该使用这种格式做为每个消息的第一个消息块。

类型2

类型2块头长度为3个字节。 流ID和消息长度都不包含在内; 该块与前面的块具备相同的流ID和消息长度。 具备固定大小消息的流(例如,某些音频和数据格式)应该在第一个消息以后使用这种格式做为每一个消息的第一个块。

类型3

类型3 的消息块没有头,流ID,消息长度和时间戳delta,这个类型的消息块在以前的消息块中取值,当单一的消息被分裂成消息块,全部的消息块除了第一个,其他都应该使用这种类型,流由一样大小的消息组成。

公共头字段

块消息头中每一个字段的描述:

字段 描述
timestamp delta (3 bytes) 对于类型1或类型2块,此处能够看到发送前一个块的时间戳和当前块的时间戳之间的差别。 若是增量大于或等于16777215(十六进制0xFFFFFF),则该字段必须是16777215,表示扩展时间戳字段以编码完整的32位增量的形式存在。 不然,这个字段应该是实际的增量。
message length (3 bytes) 对于类型0和类型1的消息块,消息的长度会出如今这里。注意这通常和消息块有效负载长度是不同的。消息块的有效负载长度是除了最后一个消息块的全部消息块的最大的长度。
message type id (1 byte) 对于类型0和类型1的消息块,消息的类型出如今这里。
message stream id (4 bytes) 对于类型为0的块,存储消息流ID。 消息流ID以little-endian格式存储。 一般,同一块流中的全部消息未来自同一个消息流。 虽然能够将单独的消息流多路复用到同一个块流中,但这会破坏头压缩的优势。 可是,若是一个消息流关闭而且另外一个随后打开,则没有理由经过发送新的类型为0的块来从新使用现有的块流。

扩展时间戳

Extended Timestamp字段用于编码大于16777215(0xFFFFFF)的时间戳或时间戳增量; 也就是说,对于时间戳或时间戳增量,它们不适合类型0,1或2块的24位字段。 该字段对完整的32位时间戳或时间戳增量进行编码。 这个字段用于表示将类型0块的时间戳字段或类型1或2块的时间戳增量字段设置为16777215(0xFFFFFF)。 当相同块流ID的最新类型0,1或2的块指示存在扩展时间戳字段时,该字段出如今类型3的块中。

示例

共有2个示例

示例1

本例给出了一个简单的音频消息流,这个例子示范了信息的冗余。

下表显示了在此流中生成的块。 从消息3开始,数据传输获得优化。 除此以外,每消息只有1字节的开销。

示例2

本例说明一个很长的消息被分割成不少消息块。

这里是分割出来的消息块

消息块1的包头数据详细介绍了307个字节的消息的所有。

注意这两个例子,类型3消息块能够用做两种不一样的方式,第一种是表示一条消息的延续,第二种是表示一条新消息的开始,这个新消息能够从已经存在的数据中衍生出来。

协议控制消息

RTMP块流使用消息类型ID 1,2,3,5和6做为协议控制消息。 这些消息包含RTMP Chunk Stream协议所需的信息。

这些协议控制消息务必具备消息流ID 0 (称为控制流)而且以块流ID 2 发送。协议控制消息一旦被接收就会当即生效,同时时间戳被忽略。

设置消息块大小

协议控制消息1:设置消息块大小。用来通知对方新的最大的消息块大小。

消息块的大小能够被设置成一个默认的值,128字节,可是客户端或者服务端能够改变这个值,而且发送消息通知对方更新。例如:假设一个客户端想要发送131字节的音频数据,消息块的大小为128字节,在这种状况下,客户端能够发送这个协议控制消息给服务端以通知消息块的大小被设置成了131字节,那么客户端就能够用一个消息块发送音频数据。

最大块大小应该不能小于128个字节,而且必须不能小于1个字节。 每一个方向的最大块大小都是独立维护的。

0: 这一位必须为0。

chunk size 块大小(31位):该字段保存新的最大块大小(以字节为单位),这将用于发件人的全部后续块,直至另行通知。 有效大小为1到2147483647(0x7FFFFFFF)(含); 可是,大于16777215(0xFFFFFF)的全部大小都是等效的,由于没有块大于一条消息,而且没有消息大于16777215字节。

中断消息

协议控制消息2:停止消息。用于通知对方是否正在等待块完成消息,而后丢弃部分接收到的消息。 对方接收块流ID做为该协议消息的有效载荷。 应用程序可能会在关闭时发送此消息,以指示不须要进一步处理消息。

chunk stream ID 块流ID (32 位): 该字段保存块流ID,对应的当前消息将被丢弃。

Acknowledgement

客户端或服务器在收到等于窗口大小的字节后,必须向对端发送Acknowledgement确认。 窗口大小是发送方未收到接收方确认而发送的最大字节数。 该消息指定了序列号,它是到当前为止收到的字节数。

sequence number 序列号(32 位):字段表示到当前为止收到的字节数。

Window Acknowledgement Size

客户端或服务器发送此消息以通知对方在发送Acknowledgement 确认之间使用的窗口大小。 发送人但愿在发送窗口大小字节后获得对方的确认。

设置对等带宽

客户端或服务器发送此消息来限制另外一方的输出带宽。 收到此消息的另外一方经过将已发送但未确认的数据量限制为此消息中指示的窗口大小这种方式用来限制其输出带宽。若是窗口大小与发送给此消息发送者的最后一个窗口大小不一样,那么接收此消息的另外一方应该使用"Window Acknowledgement Size"消息进行响应。

限制类型Limit Type是如下值之一:

  • 0 - Hard:对方应该限制其输出带宽到指定的窗口大小。
  • 1 - Soft:对方应该限制其输出带宽到本消息中指示的窗口或已经生效的限制,以较小者为准。
  • 2 - Dynamic:若是之前的限制类型是Hard,请将此消息视为Hard类型消息,不然能够直接忽视。

RTMP消息格式

本部分主要介绍RTMP消息的格式,在网络实体之间使用较低级传输层(如RTMP块流)传输这些消息。

虽然RTMP旨在与RTMP块流一块儿使用,但它可使用任何其余传输协议发送消息。 RTMP Chunk StreamRTMP一块儿适用于各类音视频应用,从一对一和一对多实时广播到视频点播服务,再到交互式会议应用。

RTMP消息格式

服务器和客户端经过网络发送RTMP消息以相互通讯。 消息可能包括音频,视频,数据或任何其余消息。

RTMP消息有两部分,头部和有效负载。

消息头

消息头包含如下字段:

字段 描述
Message Type 一个字节的字段来表示消息类型。 一系列的类型ID(1-6)被保留用于协议控制消息
Length 三字节字段,以字节表示有效负载的大小。 它以big-endian格式设置。
Timestamp 包含消息时间戳的四字节字段。 这4个字节按big-endian顺序排列。
Message Stream Id 标识消息流的三字节字段。 这些字节以big-endian格式设置。

消息有效负载

消息的另外一部分是有效负载,它是消息中包含的实际数据。 例如,它多是一些音频样本或压缩的视频数据。

用户控制消息

RTMP使用消息类型ID 4 做为用户控制消息。 这些消息包含RTMP流层使用的信息。 带有ID 1,2,3,5和6的协议消息由RTMP块流协议使用。

用户控制消息应该使用消息流ID 0(称为控制流),而且当经过RTMP块流发送时,在消息流ID 2上发送。用户控制消息在流中被接收时生效, 他们的时间戳被忽略。

客户端或服务器发送此消息以通知对端用户控制事件。 该消息携带事件类型和事件数据。

消息数据Event Data的前2个字节用于标识事件类型Event Type。 事件类型后面跟着事件数据。 事件数据字段的大小是可变的。 可是,在消息必须经过RTMP块流层的状况下,最大块的大小应该足够大,以容许这些消息适合单个块。

RTMP命令消息

本节介绍在服务器和客户端之间用于相互通讯的不一样类型的消息和命令。

在服务器和客户端之间交换的不一样类型的消息包括用于发送音频数据的音频消息,用于发送视频数据的视频消息,用于发送任何用户数据的数据消息,共享对象消息和命令消息。 共享对象消息提供了一种通用的方式来管理多个客户端和服务器之间的分布式数据。 命令消息在客户端和服务器之间传送AMF编码的命令。 客户端或服务器能够经过流使用命令消息请求对方的远程过程调用(RPC)。

消息类型

服务器和客户端经过网络发送消息以相互通讯。 消息能够是任何类型,包括音频消息,视频消息,命令消息,共享对象消息,数据消息和用户控制消息。

命令消息

命令消息在客户端和服务器之间传送AMF编码命令。 这些消息的AMF0编码的消息类型值为20,AMF3编码的消息类型值为17。 这些消息被发送来执行一些操做,例如connectcreateStreampublishplaypause等。 诸如onstatusresult等命令消息用于通知发送者有关请求的命令的状态。 命令消息由命令名称,事务ID和包含相关参数的命令对象组成。 客户端或服务器能够经过流使用命令消息请求对方的远程过程调用(RPC)。

数据消息

客户端或服务器发送此消息用于向对方发送元数据或任何用户数据。 元数据包括有关数据(音频,视频等)的详细信息,如建立时间,持续时间,主题等。 AMF0的消息类型值为18,AMF3的消息类型值为15。

共享对象消息

共享对象是一个Flash对象(name-value对的集合),在多个客户端,实例等之间同步的。 AMF0的消息类型19和AMF3的消息类型16保留用于共享对象事件。 每条消息能够包含多个事件。

支持如下事件类型:

音频消息

客户端或服务器发送此消息来向对等方发送音频数据。 消息类型值8保留给音频消息。

视频消息

客户端或服务器发送此消息以向对等方发送视频数据。 消息类型值9保留给视频消息。

聚合消息

聚合消息是单个消息。消息类型22用于聚合消息。

聚合消息的消息流ID会覆盖聚合内的子消息的消息流ID。

聚合消息的时间戳与第一个子消息之间的差别是用于将子消息的时间戳从新归一化为流时间尺度的偏移量。 将偏移量添加到每一个子消息的时间戳以达到标准化的流时间。 第一个子消息的时间戳应该与聚合消息的时间戳相同,因此偏移量应该为零。

后向指针包含前一个消息的大小,包括其头部。 它被包含来匹配FLV文件的格式并用于向后搜索。

使用聚合消息有几个性能优点:

  • 消息块流最多能够在块内发送单个完整的消息。 所以,增长块大小并使用聚合消息可减小发送的块的数量。
  • 子消息能够连续地存储在内存中。 在进行系统调用向网络上发送数据时效率更高。

用户控制消息事件

客户端或服务器发送此消息以通知对端关于用户控制事件。

支持如下用户控制事件类型:

命令类型

客户端和服务器交换AMF编码的命令。发送方发送一条命令消息,其中包含命令名称,事务ID和包含相关参数的命令对象。例如,connect命令包含'app'参数,它告诉客户端链接到的服务器应用程序名称。接收方处理该命令并以相同的事务ID发送响应。响应字符串能够是_result_error或方法名称,例如verifyClientcontactExternalServer

_result_error命令字符串表示响应。事务ID指示响应引用的未完成的命令。它与IMAP和许多其余协议中的标签相同。命令字符串中的方法名称指示发送方正试图在接收方端运行方法。

如下类对象用于发送各类命令:

  • NetConnection:一个对象,它是服务器和客户端之间链接的更高级别表示。
  • NetStream:表示发送音频流,视频流和其余相关数据的通道的对象。咱们还发送控制数据流的播放,暂停等命令。

NetConnection命令

NetConnection管理客户端应用程序和服务器之间的双向链接。 另外,它为异步远程方法调用提供支持。

如下命令能够在NetConnection上发送:

  • connect
  • call
  • close
  • createStream

connect

客户端向服务端发送链接(connect)命令请求链接一个服务器应用实例。如下为命令的结构:

如下是链接命令的命令对象中使用的name-value对的描述:

audioCodecs属性的标志值:

videoCodecs属性的标志值:

videoFunction属性的标志值:

对象编码(object Encoding)属性的值:

如下是服务端到客户端命令的结构:

如下是链接命令中的消息流:

命令执行期间的消息流是:

  1. 客户端将链接命令发送到服务器以请求链接服务器应用程序实例。
  2. 接收到链接命令后,服务器将协议消息'Window Acknowledgement Size'发送给客户端。 服务器还链接到connect命令中提到的应用程序。
  3. 服务器将协议消息 'Set Peer Bandwidth' 发送给客户端。
  4. 在处理协议消息'Set Peer Bandwidth'后,客户端向服务器发送协议消息'Window Acknowledgement Size'
  5. 服务器将类型为User Control Message(StreamBegin)的另外一个协议消息发送给客户端。
  6. 服务器发送结果命令消息,通知客户端链接状态(成功/失败)。 该命令指定事务ID(链接命令始终等于1)。 该消息还指定了属性,例如Flash Media Server版本(字符串)。 此外,它还指定其余链接响应相关信息,如级别(字符串),代码(字符串),描述(字符串),对象编码(数字)等。

Call

NetConnection对象的调用方法在接收端运行远程过程调用(RPC)。 被调用的RPC名称做为参数传递给call命令。

从发送方到接收方的命令结构以下:

响应的命令结构以下:

createStream

客户端将此命令发送到服务器以建立用于消息通讯的逻辑通道。音频,视频和元数据的发布是经过使用createStream命令建立的流通道执行的。

NetConnection是默认通讯通道,其流ID为0。协议和一些命令消息(包括createStream)使用默认通讯通道。

从客户端到服务器的命令结构以下所示:

从服务器到客户端的命令结构以下:

NetStream命令

NetStream定义了流式音频,视频和数据消息能够经过将客户端链接到服务器的NetConnection流动的通道。 一个NetConnection对象能够为多个数据流支持多个NetStream

如下命令能够由客户端在NetStream上发送到服务器:

  • play
  • play2
  • deleteStream
  • closeStream
  • receiveAudio
  • receiveVideo
  • publish
  • seek
  • pause

服务器使用'onStatus'命令将NetStream状态更新发送到客户端:

play

客户端将此命令发送到服务器以播放流。 播放列表也可使用此命令屡次建立。

若是您想要建立一个可在不一样直播流或录像流之间切换的动态播放列表,请屡次调用play,每次给reset传递false。相反,若是要当即播放指定的数据流,请清空播放队列中的其余流,给reset传递true

从客户端到服务器的命令结构以下所示:

Play命令中的消息流:

命令执行期间的消息流是:

  1. 在客户端收到服务器返回的createStream命令的成功结果后,客户端就开始发送play命令。
  2. 在收到play命令后,服务器发送协议消息来设置块大小。
  3. 服务器发送另外一个协议消息(用户控制),用于指定事件'StreamIsRecorded'的和该消息中的流ID。 该消息在前2个字节中携带事件类型,在最后4个字节中携带流ID。
  4. 服务器发送另外一个指定事件'StreamBegin'的协议消息(用户控制),以指示流传输到客户端的开始。
  5. 若是客户端发送的播放命令成功了,则服务器发送onStatus命令消息NetStream.Play.StartNetStream.Play.ResetNetStream.Play.Reset只有在客户端发送的播放命令设置了重置标志时才由服务器发送。 若是没有找到要播放的流,则服务器发送onStatus消息NetStream.Play.StreamNotFound
  6. 在此以后,服务器发送客户端播放所需的音频和视频数据。

play2

与播放命令不一样,play2能够切换到不一样的比特率流,而不改变播放内容的时间线。 服务器维护多个文件,用于支持客户端在play2中请求的全部比特率。

从客户端到服务器的命令结构以下所示:

ActionScript 3语言参考[AS3]中描述了NetStreamPlayOptions对象的公共属性。

下图显示了该命令的消息流:

deleteStream

NetStream对象被破坏时,NetStream发送deleteStream命令。

从客户端到服务器的命令结构以下所示:

服务器不发送任何响应。

receiveAudio

NetStream发送receiveAudio消息以通知服务器是否将音频发送给客户端。

从客户端到服务器的命令结构以下所示:

若是在将Bool Flag设置为false的状况下发送receiveAudio命令,则服务器不会发送任何响应。 若是Bool Flag设置为true,则服务器会使用状态消息NetStream.Seek.NotifyNetStream.Play.Start做为响应。

receiveVideo

NetStream发送receiveVideo消息以通知服务器是否将视频发送给客户端。

从客户端到服务器的命令结构以下所示:

若是在将Bool Flag设置为false的状况下发送receiveVideo命令,则服务器不会发送任何响应。 若是Bool Flag设置为true,则服务器会使用状态消息NetStream.Seek.NotifyNetStream.Play.Start做为响应。

publish

客户端发送publish命令以将已命名的流发布到服务器。 使用该名称,任何客户端均可以播放此流并接收已发布的音频,视频和数据消息。

从客户端到服务器的命令结构以下所示:

服务器使用onStatus命令进行响应以标记publish的开始。

seek

客户端发送seek命令来查找媒体文件或播放列表中的偏移量(以毫秒为单位)。

从客户端到服务器的命令结构以下所示:

seek成功时,服务器发送状态消息NetStream.Seek.Notify。 若是失败,它将返回一个_error消息。

pause

客户端发送暂停命令以通知服务器暂停或开始播放。

从客户端到服务器的命令结构以下所示:

当流暂停时,服务器发送状态消息NetStream.Pause.Notify。当流处于未暂停状态时发送NetStream.Unpause.Notify。 若是失败,将返回一个_error消息。

消息交换示例

如下是几个解释RTMP消息交换的示例。

发布录制的视频

此示例说明发布者如何发布流并将视频流式传输到服务器。 其余客户端能够订阅此发布的流并播放视频。

广播共享对象消息

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

从录像的流发布元数据

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

FMS: Flash Media Server


参考:


记得帮我点赞哦!

精心整理了计算机各个方向的从入门、进阶、实战的视频课程和电子书,按照目录合理分类,总能找到你须要的学习资料,还在等什么?快去关注下载吧!!!

resource-introduce

念念不忘,必有回响,小伙伴们帮我点个赞吧,很是感谢。

我是职场亮哥,YY高级软件工程师、四年工做经验,拒绝咸鱼争当龙头的斜杠程序员。

听我说,进步多,程序人生一把梭

若是有幸能帮到你,请帮我点个【赞】,给个关注,若是能顺带评论给个鼓励,将不胜感激。

职场亮哥文章列表:更多文章

wechat-platform-guide-attention

本人全部文章、回答都与版权保护平台有合做,著做权归职场亮哥全部,未经受权,转载必究!

相关文章
相关标签/搜索