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

本人全部文章、回答都與版權保護平臺有合做,著做權歸職場亮哥全部,未經受權,轉載必究!

相關文章
相關標籤/搜索