rtmp协议总结

来源:互联网 发布:java被阻止 已过时 编辑:程序博客网 时间:2024/05/23 00:44

一、RTMP流媒体播放过程

本文描述了从打开一个RTMP流媒体到视音频数据开始播放的全过程。

注意:RTMP中的逻辑结构

RTMP协议规定,播放一个流媒体有两个前提步骤:第一步,建立一个网络连接(NetConnection);第二步,建立一个网络流(NetStream)。其中,网络连接代表服务器端应用程序和客户端之间基础的连通关系。网络流代表了发送多媒体数据的通道。服务器和客户端之间只能建立一个网络连接,但是基于该连接可以创建很多网络流。他们的关系如图所示:



1 简要介绍

播放一个RTMP协议的流媒体需要经过以下几个步骤:握手,建立连接,建立流,播放。RTMP连接都是以握手作为开始的。建立连接阶段用于建立客户端与服务器之间的“网络连接”;建立流阶段用于建立客户端与服务器之间的“网络流”;播放阶段用于传输视音频数据。

2 握手(HandShake)

一个RTMP连接以握手开始,双方分别发送大小固定的三个数据块

a)        握手开始于客户端发送C0、C1块。服务器收到C0或C1后发送S0和S1。

b)        当客户端收齐S0和S1后,开始发送C2。当服务器收齐C0和C1后,开始发送S2。

c)        当客户端和服务器分别收到S2和C2后,握手完成。


握手

 3建立网络连接(NetConnection)

a)        客户端发送命令消息中的“连接”(connect)到服务器,请求与一个服务应用实例建立连接。

b)        服务器接收到连接命令消息后,发送确认窗口大小(Window Acknowledgement Size)协议消息到客户端,同时连接到连接命令中提到的应用程序。

c)        服务器发送设置带宽()协议消息到客户端。

d)        客户端处理设置带宽协议消息后,发送确认窗口大小(Window Acknowledgement Size)协议消息到服务器端。

e)        服务器发送用户控制消息中的“流开始”(Stream Begin)消息到客户端。

f)         服务器发送命令消息中的“结果”(_result),通知客户端连接的状态。


建立连接

4建立网络流(NetStream)

a)      客户端发送命令消息中的“创建流”(createStream)命令到服务器端。

b)      服务器端接收到“创建流”命令后,发送命令消息中的“结果”(_result),通知客户端流的状态。


建立流

 

5 播放(Play)

a)        客户端发送命令消息中的“播放”(play)命令到服务器。

b)        接收到播放命令后,服务器发送设置块大小(ChunkSize)协议消息。

c)        服务器发送用户控制消息中的“streambegin”,告知客户端流ID。

d)        播放命令成功的话,服务器发送命令消息中的“响应状态” NetStream.Play.Start & NetStream.Play.reset,告知客户端“播放”命令执行成功。

e)        在此之后服务器发送客户端要播放的音频和视频数据。

播放流


二、rtmp规范简单分析

RTMP协议是一个互联网TCP/IP五层体系结构中应用层的协议。RTMP协议中基本的数据单元称为消息(Message)。当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为消息块(Chunk)。

1 消息

消息是RTMP协议中基本的数据单元。不同种类的消息包含不同的Message Type ID,代表不同的功能。RTMP协议中一共规定了十多种消息类型,分别发挥着不同的作用。例如,Message Type ID在1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需操作其中的数据。Message Type ID为8,9的消息分别用于传输音频和视频数据。Message Type ID为15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等等。消息首部(Message Header)有四部分组成:标志消息类型的Message Type ID,标志消息长度的Payload Length,标识时间戳的Timestamp,标识消息所属媒体流的Stream ID。消息的报文结构如图3所示。

消息

2 消息块

在网络上传输数据时,消息需要被拆分成较小的数据块,才适合在相应的网络环境上传输。RTMP协议中规定,消息在网络上传输时被拆分成消息块(Chunk)。消息块首部(Chunk Header)有三部分组成:用于标识本块的Chunk Basic Header,用于标识本块负载所属消息的Chunk Message Header,以及当时间戳溢出时才出现的Extended Timestamp。消息块的报文结构如图4所示。

 

消息块

3 消息分块

在消息被分割成几个消息块的过程中,消息负载部分(Message Body)被分割成大小固定的数据块(默认是128字节,最后一个数据块可以小于该固定长度),并在其首部加上消息块首部(Chunk Header),就组成了相应的消息块。消息分块过程如图5所示,一个大小为307字节的消息被分割成128字节的消息块(除了最后一个)。

RTMP分块

RTMP传输媒体数据的过程中,发送端首先把媒体数据封装成消息,然后把消息分割成消息块,最后将分割后的消息块通过TCP协议发送出去。接收端在通过TCP协议收到数据后,首先把消息块重新组合成消息,然后通过对消息进行解封装处理就可以恢复出媒体数据。


三、消息块格式分析

1.块基本头(Chunk Basic Header)(1-3字节)

块基本头由chunk Type + chunk stream id 组成,其中chunk Type占前2Bit,chunk stream id可能是1,2或3个字节,支持65597种流,ID从3-65599。ID 0、1、2作为保留。

chunk Type:2bit  标识块消息头(Chunk Message Header)的4种格式。

chunk Type(2bit)               Chunk Message Header Length

     00                                        11 bytes

     01                                        7 bytes
     10                                        3 bytes
     11                                        0 byte
ChannelID 用途
02              Ping 和ByteRead通道
03              Invoke通道 我们的connect() publish()和自字写的NetConnection.Call() 数据都是在这个通道的
04              Audio和Vidio通道
05 06 07     服务器保留,经观察FMS2用这些Channel也用来发送音频或视频数据

2.块消息头(Chunk Message Header)(11-7-3-0字节):

>类型0:长度11字节,timestamp(3byte)+msg length(3byte)+msg type id(1byte)+ msg stream id(4byte).

其中msg type id是一个枚举变量:
type为1,2,3,5,6的时候是协议控制消息
type为4的时候表示 User Control Messages [Event_type + Event_Data] Event_type有Stream BeginStream End...
type为8,音频数据
type为9,视频数据
type为18 元数据消息[AMF0]
type为20 命令消息 Command Message(RPC Message)

命令消息主要分成两种NetConnection和NetStream。
connect,call,close,createStream命令可以在NetConnection中发送。
coonect(name,TranscationID,Command Object pair) ,play,publish,seek,pause等命令可以在NetStream中发送。

>类型1:长度7字节,timestamp delta(3byte)+msg length(3byte)+msg type id(1byte).

>类型2:长度3字节,timestamp delta(3byte).

>类型3:长度0字节.

3.额外时间戳(Extended Time Stamp): 只有当块消息头中的普通时间戳设置为0x00ffffff时,本字段才被传送.


四、RTMP流媒体播放过程
RTMP协议规定,播放一个流媒体有两个前提步骤:第一步,建立一个网络连接(NetConnection);第二步,建立一个网络流(NetStream)。其中,网络连接代表服务器端应用程序和客户端之间基础的连通关系。网络流代表了发送多媒体数据的通道。服务器和客户端之间只能建立一个网络连接,但是基于该连接可以创建很多网络流。

播放一个RTMP协议的流媒体需要经过以下几个步骤:握手,建立连接,建立流,播放。RTMP连接都是以握手作为开始的。建立连接阶段用于建立客户端与服务器之间的“网络连接”;建立流阶段用于建立客户端与服务器之间的“网络流”;播放阶段用于传输视音频数据。


五、示例

例1:展示一个简单的音频消息流。这个例子显示了信息的冗余。         

 

Message Stream ID

Message Type ID

Time

Length

Msg # 1

  12345

  8 

1000

32

Msg # 2

  12345

  8 

1020

32

Msg # 3

  12345

  8 

1040

32

Msg # 4

  12345

  8 

1060

32


下表显示了这个流产生的块。从消息3开始,数据传输开始优化。在消息3之后,每个消息只有一个字节的开销。     

 

Chunk Stream ID

Chunk Type

Header Data

No.of Bytes After Header

Total No.of

Bytes in the Chunk

Chunk#1

3

0

delta: 1000

length: 32

type: 8

stream ID:1234

(11bytes)

32

44

Chunk#2

3

2

20 (3 bytes)

32

36

Chunk#3

3

3

none(0 bytes)

32

33

Chunk#4

3

3

none(0 bytes)

32

33

Figure14  Format of each of the chunks of audiomessages above

例2:

  例2演示一个消息由于太长,而被分割成128字节的块。    

 

Message Stream ID

Message TYpe ID

Time

Length

Msg # 1

12346

9 (video)

1000

307

 下面是产生的块。

 

Chunk Stream ID

Chunk Type

Header Data

No. of Bytes after Header

Total No. of bytes in  the chunk

Chunk#1

4

0

delta: 1000

length: 307

type: 9

streamID: 12346

(11 bytes)

128

140 

Chunk#2

4

3

none (0 bytes)

128  

129

Chunk#3

4

3

none (0 bytes)

51

52


0 0