RTMP協(xié)議v1.0(中文翻譯)-1

來源:彩色世界(https://blog.hz601.org/2016/07/03/real-time-messaging-protocol/index.html)

Adobe公司的實時消息傳輸協(xié)議

摘要

此備忘錄描述了 Adobe公司的實時消息傳輸協(xié)議(RTMP)柠掂,此協(xié)議從屬于應(yīng)用層侦香,被設(shè)計用來在適合的傳輸協(xié)議(如TCP)上復(fù)用和打包多媒體傳輸流(如音頻、視頻和互動內(nèi)容)芦鳍。

目錄

1.簡介
1.1.術(shù)語
2.貢獻者
3.定義
4.字節(jié)序,對齊,和時間格式
5.RTMP塊流
5.1.消息格式
5.2.握手
5.2.1.握手序列
5.2.2.C0和S0格式
5.2.3.C1和S1格式
5.2.4.C2和S2格式
5.2.5.握手流程圖
5.3.組塊
5.3.1.塊格式
5.3.1.1.塊的基本頭
5.3.1.2.塊的消息頭
5.3.1.2.1.類型0
5.3.1.2.2.類型1
5.3.1.2.3.類型2
5.3.1.2.4.類型3
5.3.1.2.5.常見的頭字段
5.3.1.3.擴展的時間戳
5.3.2.示例
5.3.2.1.示例1
5.3.2.2.示例2
5.4.協(xié)議控制消息
5.4.1.設(shè)置塊大小 (1)
5.4.2.中斷消息 (2)
5.4.3.應(yīng)答 (3)
5.4.4.應(yīng)答窗口大小 (5)
5.4.5.設(shè)置流帶寬 (6)
6.RTMP消息格式
6.1.RTMP消息格式
6.1.1.消息頭
6.1.2.消息有效數(shù)據(jù)
6.2.用戶控制消息 (4)
7.RTMP命令消息
7.1.消息類型
7.1.1.命令消息 (20, 17)
7.1.2.數(shù)據(jù)消息 (18, 15)
7.1.3.共享對象消息 (19, 16)
7.1.4.音頻消息 (8)
7.1.5.視頻消息 (9)
7.1.6.集合消息 (22)
7.1.7.用戶控制消息事件
7.2.命令類型
7.2.1.網(wǎng)絡(luò)連接命令
7.2.1.1.連接
7.2.1.2.調(diào)用
7.2.1.3.創(chuàng)建流
7.2.2.網(wǎng)絡(luò)流命令
7.2.2.1.播放
7.2.2.2.播放2
7.2.2.3.刪除流
7.2.2.4.接收音頻
7.2.2.5.接收視頻
7.2.2.6.發(fā)布
7.2.2.7.定位
7.2.2.8.暫停
7.3.消息交互示例
7.3.1.發(fā)布錄制的視頻
7.3.2.廣播共享對象消息
7.3.3.從錄制的流發(fā)布元數(shù)據(jù)
8.引用
作者的聯(lián)系方式

簡介

Adobe公司的實時消息傳輸協(xié)議(RTMP)提供了一套全雙工的可靠的多路復(fù)用消息服務(wù)玫恳,類似于TCP協(xié)議[RFC0793]扮超,用來在一對結(jié)點之間并行傳輸帶時間戳的音頻流帖池,視頻流年扩,數(shù)據(jù)流。通常情況下髓介,不同類型的消息會被分配不同的優(yōu)先級限寞,當(dāng)網(wǎng)絡(luò)傳輸能力受限時贷祈,優(yōu)先級用來控制消息在網(wǎng)絡(luò)底層的排隊順序不恭。

當(dāng)前文章描述了實時消息傳輸協(xié)議(RTMP)的語法和實現(xiàn)崩侠。

術(shù)語

當(dāng)前文章中的這些關(guān)鍵字“MUST”“MUST NOT”“REQUIRED”“SHALL”“SHALL NOT”“SHOULD”“SHOULD NOT”“RECOMMENDED”“NOT RECOMMENDED”“MAY”“OPTIONAL”的說明請參照[RFC2119]中對應(yīng)的描述原在。

貢獻者

Rajesh Mallipeddi饭宾,Adobe公司前員工根悼,是這份規(guī)范的原始作者凶异,并且提供了大部分的原始文本。
Mohit Srivastava番挺,Adobe公司員工唠帝,為這份規(guī)范的完善做出了很大貢獻。

定義

有效數(shù)據(jù)
RTMP包中的數(shù)據(jù)玄柏,例如音頻采樣襟衰、壓縮后的視頻數(shù)據(jù)。有效數(shù)據(jù)的格式和說明不在本文中詳述粪摘。
備注:有效數(shù)據(jù)格式的定義請參考FLV定義瀑晒。


一個數(shù)據(jù)包包括固定的包頭和有效數(shù)據(jù)。一些底層協(xié)議可能需要封裝包的定義徘意。

端口
傳輸協(xié)議使用端口來區(qū)分同一個主機上的多個目標(biāo)地址苔悦。TCP/IP協(xié)議根據(jù)正整數(shù)(端口號)來識別端口。OSI傳輸層使用的傳輸選擇器(TSEL)相當(dāng)于端口椎咧。

傳輸?shù)刂?/strong>
一個網(wǎng)絡(luò)地址和端口的組合玖详,用來標(biāo)識傳輸層的一端,例如IP地址和TCP端口勤讽。數(shù)據(jù)包從源地址傳輸?shù)侥康牡刂贰?/p>

消息流
一個信息流的邏輯通信信道蟋座。

消息流ID
每條消息都有一個與之相關(guān)聯(lián)的ID,用來區(qū)分這條消息屬于哪個流脚牍。


消息的一個分片向臀。消息在被發(fā)送到網(wǎng)絡(luò)之前,被分割成更小的部分诸狭。塊可以確保在多個流之間券膀,使用基于時間戳的方式,端到端的交付所有消息驯遇。

塊流
一個邏輯通信信道芹彬,允許塊在一個特定的方向上流動。塊流可以從客戶機傳輸?shù)椒?wù)器叉庐,也可以反向傳輸舒帮。

塊流ID
每個塊都有一個與之相關(guān)聯(lián)的ID,用來區(qū)分塊屬于哪個流。

多路復(fù)用
將獨立的音頻或視頻數(shù)據(jù)組合為連貫的音視頻數(shù)據(jù)流会前,使同時傳輸多個視頻和音頻成為可能。

多路分解
多路復(fù)用的逆向過程匾竿,將混合的音視頻數(shù)據(jù)拆分成獨立的音頻和視頻數(shù)據(jù)瓦宜。

遠程過程調(diào)用(RPC)
允許客戶端或服務(wù)器請求對端調(diào)用程序或子程序。

元數(shù)據(jù)
描述數(shù)據(jù)岭妖。電影的元數(shù)據(jù)包括標(biāo)題临庇、時間、創(chuàng)建日期昵慌、等等假夺。

應(yīng)用實例
當(dāng)客戶端發(fā)送連接請求到服務(wù)器時,會在服務(wù)器端建立一個應(yīng)用實例斋攀。

動作消息格式(AMF)
一種緊湊的二進制格式已卷,用來序列化AS對象。AMF有兩個版本:AMF0淳蔼、AMF3侧蘸。
注: AMF0代表早期的flex對象,AMF3代表flash對象鹉梨;

字節(jié)序,對齊,和時間格式

所有的整形字段使用網(wǎng)絡(luò)字節(jié)序的方式傳輸讳癌,第零字節(jié)位于第一位,第零比特是雙字節(jié)或字段的標(biāo)志位存皂。這種節(jié)字排序方式通常稱為大端晌坤。傳輸順序的描述詳見IP協(xié)議[RFC0791]。除非特別聲明旦袋,本文中的數(shù)字一律為十進制骤菠。
注: 網(wǎng)絡(luò)字節(jié)序為大端排序方式。

除非特別說明猜憎,RTMP協(xié)議中的數(shù)據(jù)都以字節(jié)對齊娩怎。例如,一個16比特數(shù)字可能位于奇數(shù)偏移字節(jié)胰柑。涉及到追加數(shù)據(jù)的截亦,追加字節(jié)應(yīng)該為零。

RTMP的時間戳柬讨,是以毫秒為單位的整型數(shù)崩瓤,使用相對時間。通常踩官,每個流以零作為時間戳的起始却桶,但這不是必需的,只要他們的基準(zhǔn)時間一樣即可。注意颖系,這意味著嗅剖,任何同步傳輸?shù)亩鄠€流(特別是單一主機)的時間戳需要在RTMP協(xié)議外做一些額外處理。

時間戳是一個32位整型數(shù)嘁扼,使用周期為49天17時2分47.296秒信粮。由于,流允許連續(xù)傳輸數(shù)年時間趁啸,RTMP應(yīng)用程序在處理時間戳?xí)r强缘,應(yīng)該使用序列號算法[RFC1982]。例如不傅,應(yīng)用程序假設(shè)所有相鄰的時間戳都在1到2^32毫秒之間旅掂,比如4000000000后面跟著10000,3000000000在4000000000的前面访娶。

時間戳增量是相對于前一個時間戳的無符號整型數(shù)商虐。時間戳增量可以是24位或者32位。

RTMP塊流

本講述了實時消息傳遞協(xié)議塊流(RTMP塊流)震肮。它作為一款高級多媒體流協(xié)議提供了流的多路復(fù)用和打包服務(wù)称龙。RTMP塊流被設(shè)計用來傳輸實時消息協(xié)議(第6章),它可以使用任何協(xié)議來發(fā)送消息流戳晌。每個消息都包含時間戳和有效類型標(biāo)識鲫尊。RTMP塊流和RTMP適用于各種視聽傳播的應(yīng)用程序,包括一對一的沦偎,和一對多的視頻直播疫向、點播服務(wù)、互動會議應(yīng)用程序豪嚎。

當(dāng)使用一個可靠的傳輸協(xié)議如TCP[RFC0793]時搔驼,RTMP塊流提供了一種可以在多個流中,基于時間戳的端到端交付所有消息的方法侈询。RTMP塊流不提供任何優(yōu)先級或類似形式的控制舌涨,但可以使用更高級別的協(xié)議來提供這樣的優(yōu)先級。例如扔字,一個視頻服務(wù)器可以根據(jù)發(fā)送的時間或確認每個消息的時間囊嘉,來決定為一個網(wǎng)絡(luò)差的用戶丟棄視頻信息,以確保音頻信息的及時接收革为。

RTMP塊流不僅包含了自己的協(xié)議控制信息扭粱,同時也提供了一個更高級別的協(xié)議機制,用來嵌入用戶自定義控制信息震檩。

消息格式

消息格式可以被分割成多個塊琢蛤,用來在更高的協(xié)議中支持多路復(fù)用蜓堕。在創(chuàng)建塊消息格式時,應(yīng)該包含以下字段:

時間戳
消息的時間戳博其。這個字段占用4字節(jié)套才。

長度
消息的有效長度。如果消息頭不能被忽略慕淡,它應(yīng)該包括長度霜旧。這個字段在塊頭中占用3字節(jié)。

類型ID
各種類型的協(xié)議控制消息的ID儡率。這些消息使用RTMP塊流協(xié)議和更高級別的協(xié)議來傳輸信息。所有其他類型的ID可以用在高級協(xié)議以清,這對于RTMP塊流來說儿普,是不透明的。事實上掷倔,RTMP塊流中沒有要求使用這些值作為類型眉孩;所有(無協(xié)議的)消息可能是相同的類型,或者應(yīng)用程序使用這個字段來區(qū)分多個連接勒葱,而不是類型浪汪。這個字段在塊頭中占用1字節(jié)。

消息流ID
消息流ID可以是任意值凛虽。當(dāng)同一個塊流被復(fù)用到不同的消息流中時死遭,可以通過消息流ID來區(qū)分它們。另外凯旋,對于RTMP塊流而言呀潭,這是一個不透明值。該字段占用4字節(jié)至非,使用小端序钠署。

握手

RTMP連接從握手開始。它包含三個固定大小的塊荒椭,不像其他的協(xié)議谐鼎,是由頭部大小可變的塊組成的。

客戶端(初始化連接的一端)和服務(wù)端發(fā)送同樣的三個塊趣惠。為了方便描述狸棍,客戶端發(fā)送的三個塊命名為C0,C1信卡,C2隔缀;服務(wù)端發(fā)送的三個塊命名為S0,S1傍菇,S2猾瘸。

握手序列

客戶端通過發(fā)送C0和C1消息來啟動握手過程。客戶端必須接收到S1消息牵触,然后發(fā)送C2消息淮悼。客戶端必須接收到S2消息揽思,然后發(fā)送其他數(shù)據(jù)袜腥。

服務(wù)端必須接收到C0或者C1消息,然后發(fā)送S0和S1消息钉汗。服務(wù)端必須接收到C1消息羹令,然后發(fā)送S2消息。服務(wù)端必須接收到C2消息损痰,然后發(fā)送其他數(shù)據(jù)福侈。

C0和S0格式

C0和S0包由一個字節(jié)組成,下面是C0/S0包內(nèi)的字段:

                              0 1 2 3 4 5 6 7
                             +-+-+-+-+-+-+-+-+
                             |   version     |
                             +-+-+-+-+-+-+-+-+
                              C0 and S0 bits

1-4B 版本

版本(8比特)
在C0包內(nèi)卢未,這個字段代表客戶端請求的RTMP版本號肪凛。在S0包內(nèi),這個字段代表服務(wù)端選擇的RTMP版本號辽社。此文檔使用的版本是3伟墙。版本0-2用在早期的產(chǎn)品中,現(xiàn)在已經(jīng)被棄用滴铅;版本4-31被預(yù)留用于后續(xù)產(chǎn)品戳葵;版本32-255(為了區(qū)分RTMP協(xié)議和文本協(xié)議,文本協(xié)議通常以可打印字符開始)不允許使用汉匙。如果服務(wù)器無法識別客戶端的版本號譬淳,應(yīng)該回復(fù)版本3№锞ぃ客戶端可以選擇降低到版本3邻梆,或者中止握手過程。

C1和S1格式

C1和S1包長度為1536字節(jié)绎秒,包含以下字段:

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        time (4 bytes)                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        zero (4 bytes)                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        random bytes                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         random bytes                          |
     |                            (cont)                             |
     |                             ....                              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                              C1 and S1 bits

1-4B 時間
5-8B 零
9-1536B 其他數(shù)據(jù)

時間(4字節(jié))
本字段包含一個時間戳浦妄,客戶端應(yīng)該使用此字段來標(biāo)識所有流塊的時刻。時間戳取值可以為零或其他任意值见芹。為了同步多個塊流剂娄,客戶端可能希望多個塊流使用相同的時間戳。

零(4字節(jié))
本字段必須為零玄呛。

隨機數(shù)據(jù)(1528字節(jié))
本字段可以包含任意數(shù)據(jù)阅懦。由于握手的雙方需要區(qū)分另一端,此字段填充的數(shù)據(jù)必須足夠隨機(以防止與其他握手端混淆)徘铝。不過沒必要為此使用加密數(shù)據(jù)或動態(tài)數(shù)據(jù)耳胎。

C2和S2格式

C2和S2包長度為1536字節(jié)惯吕,作為C1和S1的回應(yīng),包含以下字段:

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        time (4 bytes)                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                       time2 (4 bytes)                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        random echo                            |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                         random echo                           |
     |                            (cont)                             |
     |                             ....                              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                              C2 and S2 bits

1-4B 時間
5-8B 時間
9-1536B 其他數(shù)據(jù)

時間(4字節(jié))
本字段必須包含對端發(fā)送的時間戳怕午。

時間(4字節(jié))
本字段必須包含時間戳废登,取值為接收對端發(fā)送過來的握手包的時刻。

隨機數(shù)據(jù)(1528字節(jié))
本字段必須包含對端發(fā)送過來的隨機數(shù)據(jù)郁惜。握手的雙方可以使用時間1和時間2字段來估算網(wǎng)絡(luò)連接的帶寬和/或延遲堡距,但是不一定有用。

握手過程示意圖

         +-------------+                           +-------------+
         |    Client   |       TCP/IP Network      |    Server   |
         +-------------+            |              +-------------+
               |                    |                     |
         Uninitialized              |               Uninitialized
               |          C0        |                     |
               |------------------->|         C0          |
               |                    |-------------------->|
               |          C1        |                     |
               |------------------->|         S0          |
               |                    |<--------------------|
               |                    |         S1          |
          Version sent              |<--------------------|
               |          S0        |                     |
               |<-------------------|                     |
               |          S1        |                     |
               |<-------------------|                Version sent
               |                    |         C1          |
               |                    |-------------------->|
               |          C2        |                     |
               |------------------->|         S2          |
               |                    |<--------------------|
            Ack sent                |                  Ack Sent
               |          S2        |                     |
               |<-------------------|                     |
               |                    |         C2          |
               |                    |-------------------->|
          Handshake Done            |               Handshake Done
               |                    |                     |
                   Pictorial Representation of Handshake
                              [譯]握手示意圖

下面是握手示意圖中提到的狀態(tài):

未初始化
協(xié)議版本號在此階段發(fā)送兆蕉∮鸾洌客戶端和服務(wù)器均處于未初始化狀態(tài)』⒃希客戶端發(fā)送攜帶協(xié)議版本號的C0包半醉。如果服務(wù)器支持此版本,回復(fù)S0和S1包劝术。如果服務(wù)器不支持此版本,使用適當(dāng)?shù)膭幼骰貜?fù)呆奕。在RTMP協(xié)議中养晋,此動作是中止連接。
注: 在"C0和S0格式"章節(jié)中提及,如果服務(wù)器不支持客戶端的版本號,可以選擇降到版本3或中止梁钾。

發(fā)送版本
客戶端和服務(wù)器雙方在未初始化狀態(tài)后绳泉,會進入發(fā)送版本狀態(tài)。之后姆泻,客戶端等待S1包零酪,服務(wù)器等待C1包。待接收到數(shù)據(jù)包拇勃,客戶端發(fā)送C2包四苇,服務(wù)器發(fā)送S2包。然后方咆,雙方都進入答復(fù)狀態(tài)月腋。客戶端等待C2的答復(fù)瓣赂,服務(wù)器等待S2的答復(fù)榆骚。

握手完成
客戶端和服務(wù)器交換消息。

組塊

握手完成之后煌集,此連接可以復(fù)用于一到多個塊流妓肢。每個塊流攜帶一個消息流的某種類型的消息。塊通過網(wǎng)絡(luò)進行傳輸苫纤。傳輸過程中碉钠,每個塊必須被完整的發(fā)送后纲缓,才能發(fā)送下一個塊。接收端接收完成之后放钦,根據(jù)塊流ID把塊組裝成完整的消息色徘。

塊允許把高級協(xié)議的大消息分割成更小的消息分片,例如為了防止低優(yōu)先級的大消息(如視頻消息)阻礙高優(yōu)先級的小消息(如音頻和控制消息)操禀。

塊允許以更少的開銷來發(fā)送小消息褂策,減少開銷的方法是壓縮必須攜帶的塊頭的數(shù)據(jù)。

塊的大小是可配置的颓屑。配置的方法詳見5.4.1章節(jié)的設(shè)置塊大小控制消息斤寂。大的塊消息可以減少CPU使用率,但是在帶寬比較小時會導(dǎo)致其他內(nèi)容的延遲揪惦。小的塊消息不利于高碼率流的傳輸遍搞。流的每一個方向都可以配置獨立的塊大小。

塊格式

每一個塊包含了頭和數(shù)據(jù)器腋。塊頭包含了三個部分:

   +--------------+----------------+--------------------+--------------+
   | Basic Header | Message Header | Extended Timestamp |  Chunk Data  |
   +--------------+----------------+--------------------+--------------+
   |                                                    |
   |<------------------- Chunk Header ----------------->|
                               Chunk Format

基本頭(1-3字節(jié))
這個字段包含塊流ID和塊類型溪猿。塊類型決定了編碼過的消息頭的格式。這個字段是一個變長字段纫塌,長度取決于塊流ID诊县。

消息頭(0,3,7,11字節(jié))
這個字段包含被發(fā)送的消息信息(無論是全部,還是部分)。字段長度由塊頭中的塊類型來決定措左。

擴展時間戳(0,4字節(jié))
這個字段是否存在取決于塊消息頭中編碼的時間戳依痊。更多詳情參考5.3.1.3章節(jié)。

塊數(shù)據(jù)(可變大小)
當(dāng)前塊的有效數(shù)據(jù)怎披,上限為配置的最大塊大小胸嘁。

塊的基本頭

塊的基本頭包含塊流ID和塊類型(下面的fmt字段)。塊類型代表了編碼過的消息頭的格式凉逛。此字段根據(jù)塊流ID的不同性宏,長度可能為1,2或3字節(jié)。

在實現(xiàn)協(xié)議時状飞,此字段應(yīng)該使用可以容納ID的最小長度衔沼。

此協(xié)議支持最多65597個流,ID從3到65599昔瞧。0,1,2這三個為保留ID指蚁。當(dāng)塊的基本頭長度為2字節(jié)時,第3-8比特取值為0自晰。當(dāng)長度為3字節(jié)時凝化,第3-8比特取值為1。塊流ID為2時保留作為低級協(xié)議的控制消息和命令消息酬荞。

1字節(jié)長度的基本頭包含了2到63的塊流ID搓劫。

                              0 1 2 3 4 5 6 7
                             +-+-+-+-+-+-+-+-+
                             |fmt|   cs id   |
                             +-+-+-+-+-+-+-+-+
                           Chunk basic header 1

2字節(jié)長度的基本頭包含了64到319的塊流ID瞧哟。塊流ID的計算方法為,第2個字節(jié)加上64枪向。

                      0                   1
                      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |fmt|     0     |   cs id - 64  |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                           Chunk basic header 2

3字節(jié)長度的基本頭包含了64到65599的塊流ID勤揩。塊流ID的計算方法為,第3個字節(jié)乘以256秘蛔,加上第2個字節(jié)陨亡,再加上64。

          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |fmt|     1     |        cs id - 64             |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                       Chunk basic header 3

塊流ID(6比特)
本字段包含了從2到63的塊流ID深员。當(dāng)塊的基本頭長度為2字節(jié)時负蠕,此字段取值為0。當(dāng)塊的基本頭長度為3字節(jié)時倦畅,此字段取值為1遮糖。

類型(2比特)
本字段標(biāo)識了塊消息頭的類型。塊消息頭的4種類型叠赐,會在下一小節(jié)中說明欲账。

塊流ID(8或16比特)
本字段的取值為塊流ID減去64。例如芭概,塊流ID為365的存儲方式為赛不,第3-8比特為1,第9-24比特為301谈山。

64-319之間的塊流ID,既可以使用2字節(jié)頭長度宏怔,也可以使用3頭長度奏路。不過前面曾經(jīng)提到過“在實現(xiàn)協(xié)議時,此字段應(yīng)該使用可以容納ID的最小長度”臊诊,因此應(yīng)該選擇使用2字節(jié)頭長度鸽粉。

塊的消息頭

根據(jù)塊的基本頭中類型字段的取值不同,塊的消息頭有4種類型抓艳。

在實現(xiàn)協(xié)議時触机,此字段應(yīng)該使用可以容納消息頭的最小長度。

類型0

類型為0的消息頭長度為11字節(jié)玷或。塊流必須以這種類型的消息開始儡首,當(dāng)塊流的時間戳回環(huán)時,也必須以這種類型的消息開始偏友。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                   timestamp                   |message length |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |     message length (cont)     |message type id| msg stream id |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |           message stream id (cont)            |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                       Chunk Message Header - Type 0

時間戳(3字節(jié))
類型為0的塊蔬胯,此字段必須為絕對時間戳。如果時間戳大于等于16777215(0xFFFFFF)位他,此字段的取值必須為16777215氛濒,并且與擴展時間戳一起組成32比特的完整時間戳产场。如果時間戳小于16777215,那么此字段代表了完整的時間戳舞竿。

類型1

類型為1的消息頭長度為7字節(jié)京景。不包含消息流ID;當(dāng)前塊和上一個塊使用相同的流ID骗奖。擁有可變大小消息(視頻數(shù)據(jù))的流應(yīng)該首個消息之后确徙,在每個消息的第1個塊使用這種類型。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                timestamp delta                |message length |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |     message length (cont)     |message type id|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                       Chunk Message Header - Type 1
類型2

類型為2的消息頭長度為3字節(jié)重归。不包含消息流ID或消息長度米愿;當(dāng)前塊和上一個塊使用相同的流ID和流長度。擁有固定大小消息(音頻或其他數(shù)據(jù))的流應(yīng)該在首個消息之后鼻吮,在每個消息的第1個塊使用這種類型育苟。

              0                   1                   2
              0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                timestamp delta                |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                       Chunk Message Header - Type 2
類型3

類型為3的塊沒有消息頭。消息頭內(nèi)的相關(guān)字段都不存在椎木。當(dāng)前塊和上一個塊使用相同的流ID违柏,長度和時間間隔。

當(dāng)一個獨立的消息被分割成塊時香椎,從第二個塊開始使用這種類型漱竖。第5.3.2.2章節(jié)的示例2展示了這種情況。

如果流由完全相同大小的消息畜伐,流ID馍惹,間隔時間組成時,應(yīng)該在類型為2的塊之后使用這種類型玛界。第5.3.2.1章節(jié)的示例1展示了這種情況万矾。

如果第一個和第二個消息之間的時間間隔和第一個消息的時間戳相同,那么類型為0的塊后面跟隨類型為3的塊慎框,沒有必要再使用類型為2的塊來標(biāo)識時間間隔良狈。

如果類型為0的塊后面跟隨著類型為3的塊,那么類型為3的塊的時間間隔與類型為1的塊的時間戳相同笨枯。

常見的頭字段

塊消息頭里面的每個字段的描述:

時間間隔(3字節(jié))
類型為1或2的塊里薪丁,本字段代表當(dāng)前塊和上一個塊的時間戳之差。如果時間間隔大于等于16777215(0xFFFFFF)馅精,此字段的取值必須為16777215严嗜,并且與擴展時間戳一起組成32比特的完整時間戳。如果時間戳小于16777215洲敢,那么此字段代表了完整的時間戳阻问。

消息長度(3字節(jié))
類型為0或1的塊里,本字段代表消息的長度沦疾。這個值通常情況下跟塊的有效數(shù)據(jù)長度是不相等的称近。塊的有效數(shù)據(jù)長度是塊大小的最大值第队。

消息類型ID(1字節(jié))
類型為0或1的塊里,本字段代表消息的類型刨秆。

消息流ID(4字節(jié))
類型為0的塊里凳谦,本字段代表消息流的ID。并使用小端方式存儲衡未。通常情況下尸执,相同塊流里面的消息來自于相同的消息流。由于消息頭的壓縮缓醋,可能導(dǎo)致獨立的消息流被混合到相同的塊流如失。無論如何,如果關(guān)閉了一個消息流送粱,又打開了另一個褪贵,那么已經(jīng)存在的塊流不能被用于發(fā)送新的類型為0的塊。

擴展的時間戳

擴展的時間戳字段用來表示時間戳或時間間隔取值大于16777215(0xFFFFFF)的抗俄。也就是說脆丁,類型為0或1或2的塊中,時間戳或時間間隔的取值超出了24比特动雹。本字段與之前的時間字段一起構(gòu)成完整的32比特時間戳或時間間隔槽卫。完整時間值的前一部分(24比特)位于類型為0的塊的時間戳字段,或類型為1或2的時間間隔字段胰蝠,取值為16777215(0xFFFFFF)歼培。類型為3的塊中,擴展時間戳字段與上一個塊中(可能為類型0或1或2)的擴展時間戳相等茸塞。

示例

示例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    |
     +---------+-----------------+-----------------+-------+---------+
               Sample audio messages to be made into chunks

下面的表格展示了由此音頻流產(chǎn)生的塊信息翔横。從第3條消息開始读跷,數(shù)據(jù)傳輸達到最大優(yōu)化梗搅。每條消息的頭部只增加了1字節(jié)長度禾唁。

      +--------+---------+-----+------------+------- ---+------------+
      |        | Chunk   |Chunk|Header Data |No.of Bytes|Total No.of |
      |        |Stream ID|Type |            |  After    |Bytes in the|
      |        |         |     |            |Header     |Chunk       |
      +--------+---------+-----+------------+-----------+------------+
      |Chunk#1 |    3    |  0  | delta: 1000|   32      |    44      |
      |        |         |     | length: 32,|           |            |
      |        |         |     | type: 8,   |           |            |
      |        |         |     | stream ID: |           |            |
      |        |         |     | 12345 (11  |           |            |
      |        |         |     | bytes)     |           |            |
      +--------+---------+-----+------------+-----------+------------+
      |Chunk#2 |    3    |  2  | 20 (3      |   32      |    36      |
      |        |         |     | bytes)     |           |            |
      +--------+---------+-----+----+-------+-----------+------------+
      |Chunk#3 |    3    |  3  | none (0    |   32      |    33      |
      |        |         |     | bytes)     |           |            |
      +--------+---------+-----+------------+-----------+------------+
      |Chunk#4 |    3    |  3  | none (0    |   32      |    33      |
      |        |         |     | bytes)     |           |            |
      +--------+---------+-----+------------+-----------+------------+
              Format of each of the chunks of audio messages

示例2

本示例展示了一條長消息,由于消息的長度超過了塊的最大長度(128字節(jié))无切,此消息在傳輸時將被分割成若干個塊荡短。

   +-----------+-------------------+-----------------+-----------------+
   |           | Message Stream ID | Message Type ID | Time  | Length  |
   +-----------+-------------------+-----------------+-----------------+
   | Msg # 1   |       12346       |    9 (video)    | 1000  |   307   |
   +-----------+-------------------+-----------------+-----------------+
                   Sample Message to be broken to chunks

下面是消息分割后產(chǎn)生的塊:

       +-------+------+-----+-------------+-----------+------------+
       |       |Chunk |Chunk|Header       |No. of     |Total No. of|
       |       |Stream| Type|Data         |Bytes after| bytes in   |
       |       | ID   |     |             | Header    | the chunk  |
       +-------+------+-----+-------------+-----------+------------+
       |Chunk#1|  4   |  0  | delta: 1000 |  128      |   140      |
       |       |      |     | length: 307 |           |            |
       |       |      |     | type: 9,    |           |            |
       |       |      |     | stream ID:  |           |            |
       |       |      |     | 12346 (11   |           |            |
       |       |      |     | bytes)      |           |            |
       +-------+------+-----+-------------+-----------+------------+
       |Chunk#2|  4   |  3  | none (0     |  128      |   129      |
       |       |      |     | bytes)      |           |            |
       +-------+------+-----+-------------+-----------+------------+
       |Chunk#3|  4   |  3  | none (0     |  51       |   52       |
       |       |      |     | bytes)      |           |            |
       +-------+------+-----+-------------+-----------+------------+
                       Format of each of the chunks

第一個塊的頭數(shù)據(jù)顯示了消息的長度為307字節(jié)。

在這兩個示例中哆键,類型為3的塊有兩種使用方式掘托。第一種是說明消息的繼續(xù)。第二種是說明新消息的頭信息可以由前面已經(jīng)存在的消息推導(dǎo)出來籍嘹。

協(xié)議控制消息

RTMP塊流使用消息類型ID 1闪盔、2弯院、3、5泪掀、6作為控制消息听绳。這些消息包含了必要的RTMP塊流協(xié)議信息。

這些協(xié)議控制消息必須使用0作為消息流ID(作為已知的控制流ID)异赫,同時使用2作為塊流ID。協(xié)議控制消息接收立即生效;解析時掰盘,時間戳字段被忽略涛目。

設(shè)置塊大小 (1)

協(xié)議控制消息(1),設(shè)置塊大小靠抑,被用來通知對方新的最大的塊大小量九。

默認最大的塊大小為128字節(jié),客戶端和服務(wù)器可以使用此消息來修改默認的塊大小孕荠。例如娩鹉,假設(shè)客戶端想要發(fā)送的音頻數(shù)據(jù)大小為131字節(jié),而塊大小為128字節(jié)稚伍。在這種情況下弯予,客戶端可以通知服務(wù)器新的塊大小為131字節(jié),然后就可以使用一個塊來發(fā)送完整的音頻數(shù)據(jù)了个曙。

最大的塊大小至少為128字節(jié)锈嫩,塊至少攜帶1個字節(jié)的內(nèi)容。通信的每一個方向(例如從客戶端到服務(wù)器)擁有獨立的塊大小設(shè)置垦搬。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |0|                     chunk size (31 bits)                    |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             Payload for the ‘Set Chunk Size’ protocol message

0
當(dāng)前比特位必須為零呼寸。

chunk size (31 bits): This field holds the new maximum chunk size,
in bytes, which will be used for all of the sender’s subsequent
chunks until further notice. Valid sizes are 1 to 2147483647
(0x7FFFFFFF) inclusive; however, all sizes greater than 16777215
(0xFFFFFF) are equivalent since no chunk is larger than one
message, and no message is larger than 16777215 bytes.
塊大小(31比特)
本字段標(biāo)識了新的最大塊大小,以字節(jié)為單位猴贰,發(fā)送端之后將使用此值作為最大的塊大小对雪。本字段的有效值為1-2147483647(0x7FFFFFFF),由于消息的最大長度為16777215(0xFFFFFF)米绕,而一個塊最多只能攜帶一條消息瑟捣,因此本字段的實際有效值為1-16777215(0xFFFFFF)。

中斷消息 (2)

協(xié)議控制消息(2)栅干,中斷消息迈套,用來通知通信的對方,如果正在等待一條消息的部分塊(已經(jīng)接收了一部分)碱鳞,那么可以丟棄之前已經(jīng)接收到的塊桑李。通信的一方將接收到塊流ID作為當(dāng)前協(xié)議消息的有效數(shù)據(jù)。應(yīng)用程序可以發(fā)送此消息來通知對方,當(dāng)前正在傳輸?shù)南]有必要再處理了贵白。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                       chunk stream id (32 bits)               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             Payload for the ‘Abort Message’ protocol message

塊流ID(32比特)
本字段包含了塊流ID率拒,用來標(biāo)識哪個塊流ID的消息將被丟棄。

應(yīng)答 (3)

客戶端和服務(wù)器在接收到與接收窗口大小相等的數(shù)據(jù)后禁荒,必須發(fā)送答應(yīng)消息給對方俏橘。窗口大小的定義為發(fā)送方在接收到接收方的任何應(yīng)答前,可以發(fā)送的最大數(shù)據(jù)量圈浇。本消息包含了序列號寥掐,序列號為截止目前接收到的數(shù)據(jù)總和,以字節(jié)為單位磷蜀。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        sequence number (4 bytes)              |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            Payload for the ‘Acknowledgement’ protocol message

序列號(32比特)
本字段包含了截止目前接收到的數(shù)據(jù)總和召耘,以字節(jié)為單位。

應(yīng)答窗口大小 (5)

客戶端和服務(wù)器發(fā)送這個消息來通知對方答應(yīng)窗口的大小褐隆。發(fā)送方在發(fā)送了等于窗口大小的數(shù)據(jù)之后污它,等待接收對方的應(yīng)答消息(在接收到答應(yīng)之前停止發(fā)送數(shù)據(jù))。接收方必須發(fā)送應(yīng)答消息庶弃,在會話開始時衫贬,或從上一次發(fā)送應(yīng)答之后接收到了等于窗口大小的數(shù)據(jù)。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                   Acknowledgement Window size (4 bytes)       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      Payload for the ‘Window Acknowledgement Size’ protocol message

設(shè)置流帶寬 (6)

客戶端和服務(wù)器發(fā)送此消息來說明對方的出口帶寬限制歇攻。接收方以此來限制自己的出口帶寬固惯,即限制未被答應(yīng)的消息數(shù)據(jù)大小。接收到此消息的一方缴守,如果窗口大小與上次發(fā)送的不一致葬毫,應(yīng)該回復(fù)答應(yīng)窗口大小的消息。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                   Acknowledgement Window size                 |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |  Limit Type   |
     +-+-+-+-+-+-+-+-+
           Payload for the ‘Set Peer Bandwidth’ protocol message

限制類型的取值為下面之一:

硬限制(0)
應(yīng)該限制出口帶寬為指明的窗口大小屡穗。

軟限制(1)
應(yīng)該限制出口帶寬為指明的窗口大小贴捡,或已經(jīng)生效的小一點的窗口大小。

動態(tài)限制(2)
如果上一次為硬限制村砂,此消息被視為硬限制烂斋,否則忽略此消息。

RTMP消息格式

本章描述了RTMP消息的格式础废,使用網(wǎng)絡(luò)傳輸層在兩個實體端之間做數(shù)據(jù)傳輸汛骂,例如RTMP塊流。由于RTMP協(xié)議基于RTMP塊流色迂,因此可以適配任何傳輸協(xié)議香缺。RTMP塊流和RTMP相結(jié)合手销,可以廣泛的使用于音視頻應(yīng)用歇僧,點對點,點對多的廣播應(yīng)用,點播服務(wù)诈悍,以及交互式會議應(yīng)用祸轮。

RTMP消息格式

服務(wù)器和客戶端通過網(wǎng)絡(luò)發(fā)送RTMP消息來和對方交流。消息可以包含音頻侥钳,視頻适袜,或其他消息。

RTMP消息有兩部分組成舷夺,頭部和有效數(shù)據(jù)苦酱。

消息頭

消息頭部包含以下字段:

消息類型
消息類型,1字節(jié)長度给猾。從1到6的ID被保留用于協(xié)議控制消息疫萤。

長度
消息的有效數(shù)據(jù)大小,3字節(jié)長度敢伸。使用大端方式扯饶。

時間戳
消息的時間戳,4字節(jié)長度池颈。使用大端方式尾序。

消息流ID
消息流標(biāo)識,3字節(jié)長度躯砰。使用大端方式每币。

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     | Message Type  |                Payload length                 |
     |   (1 byte)    |                 (3 bytes)                     |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                       Timestamp                               |
     |                       (4 bytes)                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                Stream ID                      |
     |                (3 bytes)                      |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                              Message Header

消息的有效數(shù)據(jù)

RTMP消息的另一部分是有效數(shù)據(jù),存放的是真正的消息數(shù)據(jù)內(nèi)容琢歇。例如脯爪,一些音頻采樣,或壓縮過的視頻數(shù)據(jù)矿微。有關(guān)數(shù)據(jù)的格式和解釋不在本章節(jié)說明痕慢。

用戶控制消息 (4)

用戶控制消息的類型為4。此消息位于RTMP協(xié)議流層涌矢。RTMP塊流使用消息類型ID 1掖举、2、3娜庇、5塔次、6作為控制消息(見第5.4章)。

用戶控制消息應(yīng)該使用0作為消息流ID名秀,當(dāng)通過RTMP塊流發(fā)送此消息時励负,塊流ID為2。RTMP流中的用戶控制消息在接收時立即生效匕得,消息中的時間戳被忽略继榆。

客戶端或服務(wù)器發(fā)送此消息用來通知對方用戶控制事件巾表。此消息包含事件類型和事件數(shù)據(jù)。

         +------------------------------+------------------------
         |     Event Type (16 bits)     | Event Data
         +------------------------------+-------------------------
              Payload for the ‘User Control’ protocol message

用戶控制消息的前2個字節(jié)數(shù)據(jù)用來標(biāo)識事件類型略吨。事件類型后面是事件數(shù)據(jù)集币。事件數(shù)據(jù)字段是可變的。由于此消息是通過RTMP塊流層發(fā)送的翠忠,塊大小的最大值(第5.4.1章節(jié))應(yīng)該滿足在一個塊里包含此消息鞠苟。

有關(guān)事件類型和事件數(shù)據(jù)格式的說明見第7.1.7章節(jié)。

RTMP命令消息

這部分描述了服務(wù)器和客戶端之間交互使用到的不同類型的消息和命令秽之。

服務(wù)器和客戶端之間交互的消息類型包括:用于發(fā)送音頻數(shù)據(jù)的音頻消息当娱,用于發(fā)送視頻數(shù)據(jù)的視頻消息,用于發(fā)送用戶自定義數(shù)據(jù)考榨、共享對象和命令的數(shù)據(jù)消息趾访。共享對象提供了一種通用的方式來管理多個客戶端和服務(wù)器之間的分布式消息。命令消息使用AMF編碼的命令在客戶端和服務(wù)器之間交互董虱《笮客戶端或服務(wù)器可以通請求遠程過程調(diào)用(RPC),使用命令消息和對方交流愤诱。

消息類型

服務(wù)器和客戶端通過網(wǎng)絡(luò)進行消息交互云头。消息可以是音頻消息、視頻消息淫半、命令消息溃槐、共享對象消息、數(shù)據(jù)消息和用戶自定義消息科吭。

命令消息(20, 17)

服務(wù)器和客戶端之間使用AMF編碼的命令消息交互昏滴。命令消息在AMF0編碼中,類型為20对人;在AMF3編碼中谣殊,類型為17。一些命令消息被用來發(fā)送操作指令牺弄,比如connect, createStream, publish, play, pause姻几。另外一些命令消息被用來通知發(fā)送方請求命令的狀態(tài),比如onstatus, result等势告。一條命令消息包括命令名稱蛇捌、交互ID、包含相關(guān)參數(shù)的命令對象咱台。服務(wù)器和客戶端通過在創(chuàng)建的流中遠程調(diào)用的方式络拌,使用命令消息來進行交互。

數(shù)據(jù)消息 (18, 15)

客戶端或服務(wù)器使用此消息來發(fā)送元數(shù)據(jù)或其他用戶數(shù)據(jù)回溺。元數(shù)據(jù)包含了(音視頻)數(shù)據(jù)的細節(jié)信息春贸,像流的創(chuàng)建時間混萝,時間點,主題等等祥诽。數(shù)據(jù)消息在AMF0編碼中,類型為18瓮恭;在AMF3編碼中雄坪,類型為15。

共享對象消息 (19, 16)

共享對象是Flash對象屯蹦,可以通過多客戶端维哈,實例同步傳輸。在AMF0編碼中登澜,類型為19阔挠;在AMF3編碼中,類型為16脑蠕。每個消息可以包含多個事件购撼。

   +------+------+-------+-----+-----+------+-----+ +-----+------+-----+
   |Header|Shared|Current|Flags|Event|Event |Event|.|Event|Event |Event|
   |      |Object|Version|     |Type |data  |data |.|Type |data  |data |
   |      |Name  |       |     |     |length|     |.|     |length|     |
   +------+------+-------+-----+-----+------+-----+ +-----+------+-----+
          |                                                            |
          |<- - - - - - - - - - - - - - - - - - - - - - - - - - - - - >|
          |             AMF Shared Object Message body                 |
                     The shared object message format

下面是共享消息支持的事件類型:

    +---------------+--------------------------------------------------+
    |    Event      |                   Description                    |
    +---------------+--------------------------------------------------+
    | Use(=1)       | The client sends this event to inform the server |
    |               | about the creation of a named shared object.     |
    +---------------+--------------------------------------------------+
    | Release(=2)   | The client sends this event to the server when   |
    |               | the shared object is deleted on the client side. |
    +---------------+--------------------------------------------------+
    | Request Change| The client sends this event to request that the  |
    | (=3)          | change the value associated with a named         |
    |               | parameter of the shared object.                  |
    +---------------+--------------------------------------------------+
    | Change (=4)   | The server sends this event to notify all        |
    |               | clients, except the client originating the       |
    |               | request, of a change in the value of a named     |
    |               | parameter.                                       |
    +---------------+--------------------------------------------------+
    | Success (=5)  | The server sends this event to the requesting    |
    |               | client in response to RequestChange event if the |
    |               | request is accepted.                             |
    +---------------+--------------------------------------------------+
    | SendMessage   | The client sends this event to the server to     |
    | (=6)          | broadcast a message. On receiving this event,    |
    |               | the server broadcasts a message to all the       |
    |               | clients, including the sender.                   |
    +---------------+--------------------------------------------------+
    | Status (=7)   | The server sends this event to notify clients    |
    |               | about error conditions.                          |
    +---------------+--------------------------------------------------+
    | Clear (=8)    | The server sends this event to the client to     |
    |               | clear a shared object. The server also sends     |
    |               | this event in response to Use event that the     |
    |               | client sends on connect.                         |
    +---------------+--------------------------------------------------+
    | Remove (=9)   | The server sends this event to have the client   |
    |               | delete a slot.                                   |
    +---------------+--------------------------------------------------+
    | Request Remove| The client sends this event to have the client   |
    | (=10)         | delete a slot.                                   |
    +---------------+--------------------------------------------------+
    | Use Success   | The server sends this event to the client on a   |
    | (=11)         | successful connection.                           |
    +---------------+--------------------------------------------------+

音頻消息 (8)

客戶端或服務(wù)器使用此消息來發(fā)送音頻消息。此消息的類型為8谴仙。

視頻消息 (9)

客戶端或服務(wù)器使用此消息來發(fā)送視頻消息迂求。此消息的類型為9。

集合消息 (22)

集合消息是一個獨立消息晃跺,包含了一系列的RTMP消息揩局,格式描述見6.1章。此消息的類型為22掀虎。

集合消息由消息頭和消息內(nèi)容組成凌盯。
消息內(nèi)容由子消息組成,子消息由消息頭,消息數(shù)據(jù),回放指針組成烹玉。

                   +---------+-------------------------+
                   | Header  | Aggregate Message body  |
                   +---------+-------------------------+
                       The Aggregate Message format

      +--------+-------+---------+--------+-------+---------+ - - - -
      |Header 0|Message|Back     |Header 1|Message|Back     |
      |        |Data 0 |Pointer 0|        |Data 1 |Pointer 1|
      +--------+-------+---------+--------+-------+---------+ - - - -
                     The Aggregate Message body format

集合消息的消息流ID覆蓋此消息內(nèi)的子消息流的ID驰怎。

集合消息和第一個子消息的時間戳之間的偏移量,用來將子消息的時間戳處理為流的時間刻度二打。每個子消息的時間戳可以通過添加偏移量來處理為正常的流時間砸西。第一個子消息的時間戳應(yīng)該和集合消息的時間戳相同,因此偏移量應(yīng)該為零址儒。

反向指針包含了以前的消息(包含頭信息)的大小芹枷。集合消息包含此字段,一是為了適配FLV文件格式莲趣,二是為了回放定位鸳慈。

使用集合消息有如下幾個優(yōu)勢:

塊流在一個塊內(nèi)至多可以攜帶一條完整的消息。使用集合消息之后喧伞,不僅可以增加塊大小走芋,同時還減少了發(fā)送的塊數(shù)量绩郎。

集合消息的子消息可以連續(xù)的存儲在內(nèi)存中。當(dāng)系統(tǒng)調(diào)用網(wǎng)絡(luò)發(fā)送數(shù)據(jù)時更高效翁逞。

用戶控制消息事件

客戶端或服務(wù)器通過發(fā)送此消息來通知對方用戶控制事件肋杖。此消息的格式信息詳見第6.2章節(jié)。

用戶控制事件支持如下類型:

流開始事件(0)

    +---------------+--------------------------------------------------+
    |     Event     |                   Description                    |
    +---------------+--------------------------------------------------+
    |Stream Begin   | The server sends this event to notify the client |
    |        (=0)   | that a stream has become functional and can be   |
    |               | used for communication. By default, this event   |
    |               | is sent on ID 0 after the application connect    |
    |               | command is successfully received from the        |
    |               | client. The event data is 4-byte and represents  |
    |               | the stream ID of the stream that became          |
    |               | functional.                                      |
    +---------------+--------------------------------------------------+
    | Stream EOF    | The server sends this event to notify the client |
    |        (=1)   | that the playback of data is over as requested   |
    |               | on this stream. No more data is sent without     |
    |               | issuing additional commands. The client discards |
    |               | the messages received for the stream. The        |
    |               | 4 bytes of event data represent the ID of the    |
    |               | stream on which playback has ended.              |
    +---------------+--------------------------------------------------+
    |  StreamDry    | The server sends this event to notify the client |
    |      (=2)     | that there is no more data on the stream. If the |
    |               | server does not detect any message for a time    |
    |               | period, it can notify the subscribed clients     |
    |               | that the stream is dry. The 4 bytes of event     |
    |               | data represent the stream ID of the dry stream.  |
    +---------------+--------------------------------------------------+
    |  SetBuffer    | The client sends this event to inform the server |
    |  Length (=3)  | of the buffer size (in milliseconds) that is     |
    |               | used to buffer any data coming over a stream.    |
    |               | This event is sent before the server starts      |
    |               | processing the stream. The first 4 bytes of the  |
    |               | event data represent the stream ID and the next  |
    |               | 4 bytes represent the buffer length, in          |
    |               | milliseconds.                                    |
    +---------------+--------------------------------------------------+
    | StreamIs      | The server sends this event to notify the client |
    | Recorded (=4) | that the stream is a recorded stream. The        |
    |               | 4 bytes event data represent the stream ID of    |
    |               | the recorded stream.                             |
    +---------------+--------------------------------------------------+
    |  PingRequest  | The server sends this event to test whether the  |
    |       (=6)    | client is reachable. Event data is a 4-byte      |
    |               | timestamp, representing the local server time    |
    |               | when the server dispatched the command. The      |
    |               | client responds with PingResponse on receiving   |
    |               | MsgPingRequest.                                  |
    +---------------+--------------------------------------------------+
    |  PingResponse | The client sends this event to the server in     |
    |        (=7)   | response to the ping request. The event data is  |
    |               | a 4-byte timestamp, which was received with the  |
    |               | PingRequest request.                             |
    +---------------+--------------------------------------------------+
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挖函,一起剝皮案震驚了整個濱河市状植,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怨喘,老刑警劉巖津畸,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異必怜,居然都是意外死亡肉拓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門梳庆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來暖途,“玉大人,你說我怎么就攤上這事膏执∩ル龋” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵胧后,是天一觀的道長芋浮。 經(jīng)常有香客問我,道長壳快,這世上最難降的妖魔是什么纸巷? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮眶痰,結(jié)果婚禮上瘤旨,老公的妹妹穿的比我還像新娘。我一直安慰自己竖伯,他們只是感情好存哲,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著七婴,像睡著了一般祟偷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上打厘,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天修肠,我揣著相機與錄音,去河邊找鬼户盯。 笑死嵌施,一個胖子當(dāng)著我的面吹牛饲化,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吗伤,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼吃靠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了足淆?” 一聲冷哼從身側(cè)響起巢块,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缸浦,沒想到半個月后夕冲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氮兵,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡裂逐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泣栈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卜高。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖南片,靈堂內(nèi)的尸體忽然破棺而出掺涛,到底是詐尸還是另有隱情,我是刑警寧澤疼进,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布薪缆,位于F島的核電站,受9級特大地震影響伞广,放射性物質(zhì)發(fā)生泄漏拣帽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一嚼锄、第九天 我趴在偏房一處隱蔽的房頂上張望减拭。 院中可真熱鬧,春花似錦区丑、人聲如沸拧粪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽可霎。三九已至,卻和暖如春宴杀,著一層夾襖步出監(jiān)牢的瞬間啥纸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工婴氮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留斯棒,地道東北人盾致。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像荣暮,于是被迫代替她去往敵國和親庭惜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353