日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1.RTMP描述

RTMP協議是Real Time Message Protocol(實時信息傳輸協議)的縮寫,它是由Adobe公司提出的?種應?層的協議,?來解決多媒體數據傳輸流的多路復?(Multiplexing)和分包(packetizing)的問題。隨著VR技術的發展,視頻直播等領域逐漸活躍起來,RTMP作為業內?泛使?的協議也重新被相關開發者重視起來。

RTMP協議是應?層協議,是要靠底層可靠的傳輸層協議(通常是TCP)來保證信息傳輸的可靠性的。在基于傳輸層協議的鏈接建?完成后,RTMP協議也要客戶端和服務器通過“握?”來建?基于傳輸層鏈接之上的RTMP Connection鏈接,在Connection鏈接上會傳輸?些控制信息,如SetChunkSize,SetACKwindowsize。其中CreateStream命令會創建?個Stream鏈接,?于傳輸具體的?視頻數據和控制這些信息傳輸的命令信息。RTMP協議傳輸時會對數據做??的格式化,這種格式的消息我們稱之為RTMP Message,?實際傳輸的時候為了更好地實現多路復?、分包和信息的公平性發送端會把Message劃分為帶有Message ID的Chunk,每個Chunk可能是?個單獨的Message,也可能是Message的?部分,在接收端會根據chunk中包含的data的?度,message id和message的?度把chunk還原成完整的Message,從?實現信息的收發。

 

2.RTMP握手

RTMP握手也分為簡單握手和復雜握手,可以參考前面文章,有詳細說明。

要建個有效的RTMP Connection鏈接,?先要“握?”:客戶端要向服務器發送C0,C1,C2(按序)三個chunk,服務器向客戶端發送S0,S1,S2(按序)三個chunk,然后才能進?有效的信息傳輸。RTMP協議本身并沒有規定這6個Message的具體傳輸順序,但RTMP協議的實現者需要保證這?點:

(1)客戶端要等收到S1之后才能發送C2。

(2)客戶端要等收到S2之后才能發送其他信息(控制信息和真實?視頻等數據)。

(3)服務端要等到收到C0之后發送S1,涉及到s1對C0的數據拷貝。

(4)服務端必須等到收到C1之后才能發送S2,涉及到S2對C1的數據拷貝。

(5)服務端必須等到收到C2之后才能發送其他信息(控制信息和真實?視頻等數據)。

如果每次發送?個握?chunk的話握?順序會是這樣(簡單握手),如下圖:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

理論上來講只要滿?以上條件,如何安排6個Message的順序都是可以的,但實際實現中為了在保證握?的身份驗證功能的基礎上盡量減少通信的次數,?般的發送順序是這樣的,這?點可以通過wireshark抓ffmpeg推流包進?驗證,如下圖:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

3. RTMP Chunk Stream

Chunk Stream是對傳輸RTMP Chunk的流的邏輯上的抽象,客戶端和服務器之間有關RTMP的信息都在這個流上通信。這個流上的操作也是我們關注RTMP協議的重點。

3.1 Message(消息)

這?的Message(flv的tag需要封裝成Message)是指滿?該協議格式的、可以切分成Chunk發送的消息,消息包含的字段如下:

(1)Timestamp(時間戳):消息的時間戳(但不?定是當前時間,后?會介紹),4個字節表示。

(2)Length(?度):是指Message Payload(消息負載)即?視頻等信息的數據的?度,3個字節表示。

(3)TypeId(類型Id):消息的類型Id,1個字節。

(4)Message Stream ID(消息的流ID):每個消息的唯?標識,劃分成Chunk和還原Chunk為Message的時候都是根據這個ID來辨識是否是同?個消息的Chunk的,4個字節,并且以?端格式存儲。

3.2 Chunking(Message分塊)

RTMP在收發數據的時候并不是以Message為單位的,?是把Message拆分成Chunk發送,?且必須在?個Chunk發送完成之后才能開始發送下?個Chunk(一般不會交替發送)。每個Chunk中帶有Message ID代表屬于哪個Message,接收端也會按照這個id來將chunk組裝成Message

為什么RTMP要將Message拆分成不同的Chunk呢?

這個在前面的文章也分析過,可以參考前面文章流媒體推拉流實戰之RTMP協議分析(BAT面試官推薦) ,有以下2個原因:

(1)分包能夠減小延時和阻塞,更能適應復雜網絡環境變化。

(2) 通過拆分,數據量較?的Message可以被拆分成較?的“Message”,這樣就可以避免優先級低(數據量大)的消息持續發送阻塞優先級?(數據量低)的數據,?如在視頻的傳輸過程中,會包括視頻幀,?頻幀和RTMP控制信息,如果持續發送?頻數據或者控制數據的話可能就會造成視頻幀的阻塞,然后就會造成看視頻時最煩?的卡頓現象。同時對于數據量較?的Message,可以通過對Chunk Header的字段來壓縮信息,從?減少信息的傳輸量。(具體的壓縮?式會在后?介紹)

Chunk包大小如何設

設置Chunk包大小主要考慮2點,一個是CPU占有率,一個是網絡發送時間和是否阻塞。這兩點是矛盾關系,需要根據實際情況,折中考慮。Chunk的默認??是128字節,在傳輸過程中,通過?個叫做Set Chunk Size的控制信息(?spec 5.4.1 )可以設置Chunk數據量的最?值,在發送端和接受端各?維護?個Chunk Size(srs流媒體服務器默認是60000),可以分別設置這個值改變??這??發送的Chunk的最???

如果考慮CPU占有率減少多一點。那就選擇大一點的Chunk,??點的Chunk減少了計算每個chunk的發送時間,從?減少了CPU的占?率,但是它會占?更多的時間在發送上,尤其是在低帶寬的?絡情況下,很可能會阻塞后?更重要信息的傳輸。

如果考慮網絡發送時間和是否阻塞多一點。那就選擇小一點的Chunk,??點的Chunk可以減少這種阻塞問題,但?的Chunk會引?過多額外的信息(Chunk中的Header),少量多次的傳輸也可能會造成發送的間斷導致不能充分利??帶寬的優勢,因此CPU使用率會更高。

總的來說,Chunk小一點不適合在高比特率的流中傳輸。在實際發送時應對要發送的數據?不同的Chunk Size去嘗試,通過抓包分析等?段得出合適的Chunk??,并且在傳輸過程中可以根據當前的帶寬信息和實際信息的??動態調整Chunk的??,從?盡量提?CPU的利?率減少信息的阻塞機率。折中考慮,弄清這2點,也是調優的關鍵。

3.3 Chunk Format(塊格式)

這個格式分析,在前面文章分析過,可以參看前面文章。流媒體推拉流實戰之RTMP協議分析(BAT面試官推薦)

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

這里有個問題就是,?個流當中可以交錯傳輸多種消息類型的Chunk,那么多個Chunk怎么標記同屬于同?類Message的呢

回答:通過Chunk Stream ID區分的,同?個Chunk Stream ID必然屬于同?個Message

還有個問題就是,Basic Header??的chunk stream ID代表了通道,不同的Message 是否有不同的的chunk Stream ID?

回答:不同的Message的chunk Stream ID是不一樣。RTMP流中視頻和?頻擁有單獨的Chunk Stream ID,?如?頻的cs id=20,視頻的cs id=21。接收端接收到Chunk之后,根據cs id分別將?頻和視頻“拼成成Message消息”。

注意:每?種消息類型的起始chunk 的類型必須是 Type_0 類型的,表明我是?個新的消息的起始。

3.3.1 Basic Header(基本的頭信息)

包含了chunk stream ID(流通道Id)和chunk type(chunk的類型),chunk stream id?般被簡寫為CSID,?來唯?標識?個特定的流通道,chunk type決定了后?Message Header的格式。Basic Header的?度可能是1,2,或3個字節,其中chunk type的?度是固定的(占2位,注意單位是位,bit),Basic Header是變?,其?度取決于CSID的??,在?夠存儲這兩個字段的前提下最好?盡量少的字節從?減少由于引?Header增加的數據量。

RTMP協議最多?持65597個?戶?定義chunk stream ID,范圍為[3,65599] ,ID 0, 1, 2被協議規范直接使?,其中ID值為0, 1分表表示了Basic Header占?2個字節和3個字節:

(1)當Basic Header為1個字節時,CSID占6位,6位最多可以表示64個數,因此這種情況下CSID在 [0,63] 之間,其中?戶可?定義的范圍為 [3,63] ,實際是可以?2開始?。1個字節的Basic Header如下圖:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

(2)ID值0:代表Basic Header占?2個字節,CSID在 [64,319] 之間。

當Basic Header為2個字節時,結構如下圖,CSID占只占8位,第?個字節除chunk type占?的bit都置為0,第?個字節?來表示CSID-64,8位可以表示 [0, 255] 共256個數,ID的計算?法為(第?個字節+64),范圍為 [64,319]

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

(3)ID值1:代表Basic Header占?3個字節,CSID在 [64,65599] 之間。

當Basic Header為3個字節時,結構如下圖,以在此字段?3字節版本編碼。ID的計算?法為(第三字節*256+第?字節+64)(Basic Header是采??端存儲的?式),范圍為 [64,65599]。可以看到2個字節和3個字節的Basic Header所能表示的CSID是有交集的 [64,319],但實際實現時還是應該秉著最少字節的原則使?2個字節的表示?式來表示 [64,319] 的CSID。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

(4)ID值2:代表該chunk是控制信息和?些命令信息,后?會有詳細的介紹。

 

3.3.2 Message Header(消息的頭信息)

包含了要發送的實際信息(可能是完整的,也可能是?部分)的描述信息。Message Header的格式和?度取決于Basic Header的chunk type,共有4種不同的格式,這在前面的文章也有詳細的分析過,流媒體推拉流實戰之RTMP協議分析(BAT面試官推薦)。由上?所提到的Basic Header中的fmt字段控制。其中第?種格式可以表示其他三種表示的所有數據,但由于其他三種格式是基于對之前chunk的差量化的表示,因此可以更簡潔地表示相同的數據,實際使?的時候還是應該采?盡量少的字節表示相同意義的數據。以下按照字節數從多到少的順序分別介紹這4種格式的Message Header。

Type=0: 占?11個字節

type=0時Message Header占?11個字節,其他三種能表示的數據它都能表示,但在chunk stream的開始的第?個chunk和頭信息中的時間戳后退(即值與上?個chunk相?減?,通常在回退播放的時候會出現這種情況)的時候必須采?這種格式。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

(1)timestamp(時間戳):占?3個字節,因此它最多能表示到16777215=0xFFFFFF=2^24-1, 當它的值超過這個最?值時,這三個字節都置為1,這樣實際的timestamp會轉存到Extended Timestamp字段中,接收端在判斷timestamp字段24個位都為1時就會去Extended timestamp中解析實際的時間戳。

(2)字段message length和message length(cont)(消息數據的?度),占?3個字節,表示實際發送的消息的數據如?頻幀、視頻幀等數據的?度,單位是字節。注意這?是Message的?度,也就是chunk屬于的Message的總數據?度,?不是chunk本身Data的數據的?度。

(3)message type id(消息的類型id):占?1個字節,表示實際發送的數據的類型,如8代表?頻數據、9代表視頻數據。

(4)msg stream id(消息的流id):占?4個字節,表示該chunk所在的流的ID,和Basic Header的CSID?樣,它采??端存儲的?式。

 

Type = 1:占?7個字節

type=1時Message Header占?7個字節,省去了表示msg stream id的4個字節,表示此chunk和上?次發的chunk所在的流相同,如果在發送端只和對端有?個流鏈接的時候可以盡量去采取這種格式。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

(1)timestamp delta:占?3個字節,注意這?和type=0時不同,存儲的是和上?個chunk的時間差。類似上?提到的timestamp,當它的值超過3個字節所能表示的最?值時,三個字節都置為1,實際的時間戳差值就會轉存到Extended Timestamp字段中,接受端在判斷timestamp delta字段24個位都為1時就會去Extended timestamp中解析時機的與上次時間戳的差值。

 

Type = 2:占?3個字節

type=2時Message Header占?3個字節,相對于type=1格式?省去了表示消息?度的3個字節和表示消息類型的1個字節,表示此chunk和上?次發送的chunk所在的流、消息的?度和消息的類型都相同。余下的這三個字節表示timestamp delta,使?同type=1。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

Type = 3:占?0字節

0字節!!!好吧,它表示這個chunk的Message Header和上?個是完全相同的,?然就不?再傳輸?遍了。當它跟在Type=0的chunk后?時,表示和前?個chunk的時間戳都是相同。什么時候連時間戳都相同呢?就是?個Message拆分成了多個chunk這個chunk和上?個chunk同屬于?個Message。?當它跟在Type=1或者Type=2的chunk后?時,表示和前?個chunk的時間戳的差是相同的。?如第?個chunk的Type=0,timestamp=100,第?個chunk的Type=2,timestamp delta=20,表示時間戳為100+20=120,第三個chunk的Type=3,表示timestamp delta=20,時間戳為120+20=140

 

4種type對?

4種類型對比,在前面文章也有講解,也可以參考前面文章。流媒體推拉流實戰之RTMP協議分析(BAT面試官推薦)

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 


超詳細RTMP協議詳解(資深流媒體架構師推薦)

 


超詳細RTMP協議詳解(資深流媒體架構師推薦)

 


超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

3.3.3 Extended Timestamp(擴展時間戳)

上?我們提到在chunk中會有時間戳timestamp和時間戳差timestamp delta,并且它們不會同時存在,只有這兩者之??于3個字節能表示的最?數值0xFFFFFF=16777215時,才會?這個字段來表示真正的時間戳,否則這個字段為0。擴展時間戳占4個字節,能表示的最?數值就是0xFFFFFFFF=4294967295。當擴展時間戳啟?時timestamp字段或者timestamp delta要全置為0xFFFFFF,表示應該去擴展時間戳字段來提取真正的時間戳或者時間戳差。

注意:擴展時間戳存儲的是完整值,?不是減去時間戳或者時間戳差的值。

3.3.4 Chunk Data(塊數據)

?戶層?上真正想要發送的與協議?關的數據,?度在(0,chunkSize]之間。

3.3.5 chunk表示例1

這個例?顯示了?個簡單的?頻信息流。這個例?演示了信息的冗余。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

看懂下面這段分析,就可以了解到,Message是怎樣做到變長。

(1)第?個Message的chunk的Chunk Type為0,因為它沒有前?可參考的chunk,timestamp為1000,表示時間戳。type為0的header占?11個字節,假定chunkstreamId為3<127,因此BasicHeader占?1個字節,再加上Data的32個字節,因此第?個chunk共44=11+1+32個字節

(2)第?個chunk和第?個chunk的CSIDTypeId,Data的?度都相同,因此采?Chunk Type=2,timestamp delta=1020-1000=20,因此第?個chunk占?36=3+1+32個字節。

(3)第三個chunk和第?個chunk的CSID,TypeId,Data的?度和時間戳差都相同,因此采?Chunk Type=3省去全部Message Header的信息,占?33=1+32個字節

(4)第四個chunk和第三個chunk情況相同,也占?33=1+32個字節

最后實際發送的chunk如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

3.3.6 Chunk數據量過大

如果一個Message消息因為太?,以?于?法適??個128字節的chunk,從?被分解成多個chunk。

(1)注意到Data的Length=307>128,因此這個Message要切分成?個chunk發送,第?個chunk的Type=0,Timestamp=1000,承擔128個字節的Data,因此共占?140=11+1+128個字節

(2)第?個chunk也要發送128個字節,其他字段也同第?個chunk,因此采?Chunk Type=3,此時時間戳也為1000,共占?129=1+128個字節

(3)第三個chunk要發送的Data的?度為307-128-128=51個字節,還是采?Type=3,共占?1+51=52個字節。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

最后實際發送的chunk如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

從兩個例?中注意到,Type = 3的chunk可以?在兩種不同的?式中。第?種指定消息的繼續第?種是指定?個新的消息的開始,它的頭可以來?于現有的狀態數據。

 

3.4 協議控制消息(Protocol Control Message)

在RTMP的chunk流會??些特殊的值來代表協議的控制消息,它們的Message Stream ID必須為0(代表控制流信息),CSID必須為2Message Type ID可以為1,2,3,5,6,具體代表的消息會在下?依次說明。控制消息的接收端會忽略掉chunk中的時間戳,收到后?即?效。

Set Message Type ID=1

設置chunk中Data字段所能承載的最?字節數,默認為128Bytes,通信過程中可以通過發送該消息來設置chunk Size的??(不得?于128Bytes),?且通信雙?會各?維護?個chunkSize,兩端的chunkSize是獨?

?如當A想向B發送?個200Bytes的Message,但默認的chunkSize是128Bytes,因此就要將該消息拆分為Data分別為128Bytes和72Bytes的兩個chunk發送。如果此時先發送?個設置chunkSize為256Bytes的消息,再發送Data為200Bytes的chunk,本地不再劃分Message,B接收到Set Chunk Size的協議控制消息時會調整的接受的chunk的Data的??,也不?再將兩個chunk組成為?個Message,所以根據實際的情況,設置客戶端和服務端的Chunk Size值。

在實際寫代碼的時候?般會把chunk size設置的很?,有的會設置為4096,FFMPEG推流的時候設置的是 60*1000,這樣設置的好處是避免了頻繁的拆包組包,占?過多的CPU。網絡不佳時,但發送可能會耗時。

以下為代表Set Chunk Size消息的chunk的Data:

其中第?位必須為0,chunk Size占31個位,最?可代表2147483647=0x7FFFFFFF=2^31-1,但實際上所有?于16777215=0xFFFFFF的值都?不上因為chunk size不能?于Message的?度,表示Message的?度字段是?3個字節表示最?只能為0xFFFFFF

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

Abort Message (ID=2)

Abort Message(Message Type ID=2):當?個Message被切分為多個chunk,接受端只接收到了部分chunk時發送該控制消息表示發送端不再傳輸同Message的chunk,接受端接收到這個消息后要丟棄這些不完整的chunk。Data數據中只需要?個CSID,表示丟棄該CSID的所有已接收到的chunk。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

Acknowledgement (ID=3)和Window Acknowledgement Size (ID=5)

Window Acknowledgement Size?于設置窗?確認??,Acknowledgement是窗?確認消息。會話開始時,雙?都要先對端發送Window Acknowledgement Size,?于指明期望獲得確認的??。當?端收到內容??超過Window Acknowledgement Size,就要向對?發送Acknowledgement。詳細流程如下:

(1)會話開始計算收到byte個數的時間點是收到Window Acknowledgement Size消息開始。

(2)byte size不包括tcp包頭,應該是chunk的??,即從tcp 的recv函數中獲得的內容??。

(3)雙?都要向對?發送Window Acknowledgement Size和Acknowledgement。

(4)發送端發送完Window Acknowledgement Size消息后,沒有收到Acknowledgement不再發送進?步的消息——這樣會容易引起錯誤,導致再也發送不出消息了。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

對于拉流端,?般在收到av_createStream后,接著play,然后發送Acknowledgement 以讓服務器繼續發送數據。用于相互確認發送窗口大小。

 

Set Peer Bandwidth (ID=6)

Set Peer Bandwidth(Message Type ID=6):限制對端的輸出帶寬。接受端接收到該消息后會通過設置消息中的Window ACK Size來限制已發送但未接受到反饋的消息的??來限制發送端的發送帶寬。如果消息中的Window ACK Size與上?次發送給發送端的size不同的,要回饋?個WindowAcknowledgement Size的控制消息。同樣,也是要相互確定大小。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

詳細流程如下:
(1)Hard(Limit Type=0):接收端應該將Window Ack Size設置消息中的值

(2)Soft(Limit Type=1):接收端可以將Window Ack Size設為消息中的值,也可以保存原來的值(前提是原來的Size?與該控制消息中的Window Ack Size)

(3)Dynamic(Limit Type=2):如果上次的Set Peer Bandwidth消息中的Limit Type為0,本次也按Hard處理,否則忽略本消息,不去設置Window Ack Size。

 

4. 不同類型的RTMP Message

(1)Command Message(命令消息,Message Type ID=17或20):表示在客戶端和服務器間傳遞,在對端執?某些操作的命令消息,如connect表示連接對端,對端如果同意連接的話會記錄發送端信息并返回連接成功消息,publish表示開始向對?推流,接收端接到命令后,準備接收對端發送的流信息,后?會對?較常?的Command Message具體介紹。當信息使?AMF0編碼時,Message Type ID=20,AMF3編碼時Message Type ID=17。

(2)Data Message(數據消息,Message Type ID=15或18):傳遞?些元數據(MetaData,?如視頻名,分辨率等等)或者?戶?定義的?些消息。當信息使?AMF0編碼時,Message Type ID=18,AMF3編碼時Message Type ID=15

(3)Shared Object Message(共享消息,Message Type ID=16或19):表示?個Flash類型的對象,由鍵值對的集合組成,?于多客戶端,多實例時使?。當信息使?AMF0編碼時,Message Type ID=19,AMF3編碼時Message Type ID=16。

(4)Audio Message(?頻信息,Message Type ID=8):?頻數據。

(5)Video Message(視頻信息,Message Type ID=9):視頻數據。

(6)Aggregate Message (聚集信息,Message Type ID=22):多個RTMP?消息的集合。

(7)User Control Message Events(?戶控制消息,Message Type ID=4):告知對?執?該信息中包含的?戶控制事件,?如Stream Begin事件告知對?流信息開始傳輸。和前?提到的協議控制信息(Protocol Control Message)不同,這是在RTMP協議層(更上層),?不是在RTMP chunk流協議層的,這個很容易弄混。該信息在chunk流中發送時,Message Stream ID=0,Chunk Stream Id=2,Message Type Id=4。

以下詳細介紹這幾種情況。

4.1 Command Message(命令消息,Message Type ID=17 或20)

實際使?時使?了ID=20,發送端發送時會帶有命令的名字如connect,TransactionID表示此次命令的標識,Command Object表示相關參數。接受端收到命令后,會返回以下三種消息中的?種:

(1)_result消息表示接受該命令,對端可以繼續往下執?流程。

(2)_error消息代表拒絕該命令要執?的操作。

(3)method name消息代表要在之前命令的發送端執?的函數名稱

注意:這三種回應的消息都要帶有收到的命令消息中的Transaction Id,表示本次的回應作?于哪個命令。可以認為發送命令消息的對象有兩種,?種是NetConnection,表示雙端的上層連接?種是NetStream,表示流信息的傳輸通道,控制流信息的狀態,如Play播放流,Pause暫停

4.1.1 NetConnection Commands(連接層的命令)

?來管理雙端之間的連接狀態,同時也提供了異步遠程?法調?(RPC)在對端執?某?法,以下是常?的連接層的命令:

connect:?于客戶端向服務器發送連接請求,握?之后先發送?個connect 命令消息,這些信息是以AMF格式發送的,消息的結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

第三個字段中的Command Object中會涉及到很多鍵值對,使?時可以參考協議的官??檔。

消息的回應有兩種,_result表示接受連接_error表示連接失敗

以下是連接命令對象中使?的名稱-值對的描述:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

Call:?于在對端執?某函數,即常說的RPC:遠程進程調?,消息的結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

如果消息中的TransactionID不為0的話,對端需要對該命令做出響應,響應的消息結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

Create Stream創建傳遞具體信息的通道,從?可以在這個流中傳遞具體信息,傳輸信息單元為Chunk。當發送完createStream消息之后,解析服務器返回的消息會得到?個stream ID, 這個ID也就是以后和服務器通信的 message stream ID, ?般返回的是1,不固定。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

4.1.2 NetStream Commands(流連接上的命令)

Netstream建?在NetConnection之上,通過NetConnection的createStream命令創建,?于傳輸具體的?頻、視頻等信息。在傳輸層協議之上只能連接?個NetConnection,但?個NetConnection可以建?多個NetStream來建?不同的流通道傳輸數據(一定要記住,這在wireshark上可以得到)。

以下會列出?些常?的NetStream Commands,服務端收到命令后會通過onStatus的命令響應客戶端,表示當前NetStream的狀態。

onStatus命令的消息結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

play(播放):由客戶端向服務器發起請求從服務器端接受數據(如果傳輸的信息是視頻的話就是請求開始播流),可以多次調?,這樣本地就會形成?組數據流的接收者。注意其中有?個reset字段,表示是覆蓋之前的播流(設為true)還是重新開始?路播放(設為false)。

play命令的結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

play2(播放):和上?的play命令不同的是,play2命令可以將當前正在播放的流切換到同樣數據但不同?特率的流上,服務器端會維護多種?特率的?件來供客戶端使?play2命令來切換。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

deleteStream(刪除流):?于客戶端告知服務器端本地的某個流對象已被刪除,不需要再傳輸此路流。

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

receiveAudio(接收?頻)通知服務器端客戶端是否要發送?頻。

receiveAudio命令結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

receiveVideo(接收視頻)通知服務器端該客戶端是否要發送視頻

receiveVideo命令結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

publish(推送數據):由客戶端向服務器發起請求推流到服務器

publish命令結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

seek(定位流的位置)定位到視頻或?頻的某個位置,以毫秒為單位。

seek命令的結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

pause(暫停):客戶端告知服務端停?或恢復播放。

如果Pause為true即表示客戶端請求暫停的話,服務端暫停對應的流會返回NetStream.Pause.Notify的onStatus命令來告知客戶端當前流處于暫停的狀態當Pause為false時,服務端會返回NetStream.Unpause.Notify的命令來告知客戶端當前流恢復。如果服務端對該命令響應失敗,返回_error信息。

pause命令的結構如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

5. 代表流程

推流流程

推流流程,在前面的文章已經有了很深入的介紹。流媒體推拉流實戰之RTMP協議分析(BAT面試官推薦)

現貼下流程。如下圖:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

拉流播放流程如下:

超詳細RTMP協議詳解(資深流媒體架構師推薦)

 

6. 新?學習建議

如果讀者仔細讀完了上?講的RTMP協議,想必會覺得RTMP協議?常繁瑣,事實也確實是這樣,RTMP協議中充斥著很多冗余的字段,?如三次握?中的時間戳的校對,還有?些特殊的命令,如FCPublish、UnFCPublish等,但在實際實現中為了保證更?兼容性通常還是要處理這些看似多余的命令。加上Adobe對RTMP協議的實現細節有些并沒有按照協議來或者協議中,沒有寫清楚??搞了?套實現,其他應?開發時還要兼容Adobe錯誤的實現,從?使的RTMP也?直為開發者所詬病。但不管怎樣,RTMP確實提供了?種能夠全?并且實現簡單的協議來保證流信息的傳輸,這??暫時還沒有?種更完善更簡潔的協議能夠取代它在視頻流開發中的地位。新??開始接觸RTMP的時候肯定會覺得頭?,這也是RTMP協議不簡潔的后果。建議讀者在學習時先過?遍協議理解?概的概念和流程,然后對照wireshark抓的包,和協議進??對,這樣將理論和實踐結合,應該會理解的更快?點。

7.源碼參考

源碼主要來源如下開源庫:

(1). librtmp

(2). ffmpeg rtmppkt.h

(3). srs

csid是?定義的,主要不使?保留的0,1即可,?如ffmpeg的rtmppkt.h。對于chunk size的設置,ffmpeg保持和服務器?致。

 /*** channels used to for RTMP packets with different purposes (i.e. da ta, network
  * control, remote procedure calls, etc.)   */
 enum RTMPChannel { 
   RTMP_NETWORK_CHANNEL = 2, ///< channel for network-related mess ages (bandwidth report, ping, etc) 
   RTMP_SYSTEM_CHANNEL, ///< channel for sending server contr ol messages 
   RTMP_AUDIO_CHANNEL, ///< channel for audio data 
   RTMP_VIDEO_CHANNEL = 6, ///< channel for video data 
   RTMP_SOURCE_CHANNEL = 8, ///< channel for a/v invokes  };

librtmp

RTMP_Write適合將FLV?件幀進?發送,RTMP_Read適合?來dump RTMP碼流。

srs源碼

srs_kernel_flv.hpp

message type相關。

// 5. Protocol Control Messages 
// RTMP reserves message type IDs 1-7 for protocol control messages. // These messages contain information needed by the RTM Chunk Stream // protocol or RTMP itself. Protocol messages with IDs 1 & 2 are 
5 // reserved for usage with RTM Chunk Stream protocol. Protocol messa ges
6 // with IDs 3-6 are reserved for usage of RTMP. Protocol message wit h ID 
7 // 7 is used between edge server and origin server. 
8 #define RTMP_MSG_SetChunkSize 0x01 
9 #define RTMP_MSG_AbortMessage 0x02 
10 #define RTMP_MSG_Acknowledgement 0x03 
11 #define RTMP_MSG_UserControlMessage 0x04 
12 #define RTMP_MSG_WindowAcknowledgementSize 0x05 
13 #define RTMP_MSG_SetPeerBandwidth 0x06 
14 #define RTMP_MSG_EdgeAndOriginServerCommand 0x07 
15 // 3. Types of messages 
16 // The server and the client send messages over the network to 
17 // communicate with each other. The messages can be of any type whic h 
18 // includes audio messages, video messages, command messages, shared 
19 // object messages, data messages, and user control messages. 
20 // 3.1. Command message 
21 // Command messages carry the AMF-encoded commands between the clien t 
22 // and the server. These messages have been assigned message type va lue 
23 // of 20 for AMF0 encoding and message type value of 17 for AMF3 
24 // encoding. These messages are sent to perform some operations like 
25 // connect, createStream, publish, play, pause on the peer. Command 
26 // messages like onstatus, result etc. are used to inform the sender 
27 // about the status of the requested commands. A command message 28 // consists of command name, transaction ID, and command object that 29 // contains related parameters. A client or a server can request Rem

srs_rtmp_stack.hpp

 // The amf0 command message, command name macros
 #define RTMP_AMF0_COMMAND_CONNECT "connect"
 #define RTMP_AMF0_COMMAND_CREATE_STREAM "createStream"
 #define RTMP_AMF0_COMMAND_CLOSE_STREAM "closeStream"
#define RTMP_AMF0_COMMAND_PLAY "play"
 #define RTMP_AMF0_COMMAND_PAUSE "pause"
#define RTMP_AMF0_COMMAND_ON_BW_DONE "onBWDone"
#define RTMP_AMF0_COMMAND_ON_STATUS "onStatus"
#define RTMP_AMF0_COMMAND_RESULT "_result"
#define RTMP_AMF0_COMMAND_ERROR "_error"
 #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream"
 #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish"
#define RTMP_AMF0_COMMAND_UNPUBLISH "FCUnpublish"
 #define RTMP_AMF0_COMMAND_PUBLISH "publish"
 #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess"
 // The signature for packets to client.
 #define RTMP_SIG_FMS_VER "3,5,3,888"
 #define RTMP_SIG_AMF0_VER 0
 #define RTMP_SIG_CLIENT_ID "ASAICiss"
 // The onStatus consts.#define StatusLevel "level"
 #define StatusCode "code"
 #define StatusDescription "description"
 #define StatusDetails "details"
#define StatusClientId "clientid"
// The status value 
 #define StatusLevelStatus "status" 
// The status error 
#define StatusLevelError "error" 
// The code value  #define StatusCodeConnectSuccess "NetConnection.Conne ct.Success" 
 #define StatusCodeConnectRejected "NetConnection.Conne ct.Rejected" 
 #define StatusCodeStreamReset "NetStream.Play.Rese t" 
 #define StatusCodeStreamStart "NetStream.Play.Star t" 
#define StatusCodeStreamPause "NetStream.Pause.Not ify" 
#define StatusCodeStreamUnpause "NetStream.Unpause.N otify" 
#define StatusCodePublishStart "NetStream.Publish.S tart" 
 #define StatusCodeDataStart "NetStream.Data.Star t" 
 #define StatusCodeUnpublishSuccess "NetStream.Unpublis h.Success"

重點參考一些比較好用源碼和有關RTMP的知識。

https://github.com/zkzszd/NativeCodec.git

https://github.com/Cooliodtryl/upstream-h.264-es-file-as-rtmp-.git

https://github.com/ireader/media-server

https://github.com/medooze/media-server

直播推流實現RTMP協議的?些注意事項: https://www.cnblogs.com/lidabo/p/7232594.html

RTMP 協議規范(中?版) :https://www.cnblogs.com/Kingfans/p/7083100.html

本篇文章就分享到這里,歡迎關注,點贊,收藏,轉發,評論區討論 。

更多技術知識,歡迎關注 微信公眾號 “記錄世界 from antonio”

分享到:
標簽:協議 RTMP
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定