RTMP協議詳解(轉)

來源:互聯網
上載者:User

標籤:

轉自《RTMP協議詳解(一) (二) (三) 》

Real Time Messaging Protocol(即時訊息傳送協議協議)是Adobe Systems公司為Flash播放器和伺服器之間音頻、視頻和資料轉送開發的私人協議。

具體使用RTMP的AS代碼大概如下:

  var videoInstance:Video = your_video_instance;

  var nc:NetConnection = new NetConnection();

  var connected:Boolean = nc.connect("rtmp://localhost/myapp");

  var ns:NetStream = new NetStream(nc);

  videoInstance.attachVideo(ns);

ns.play("flvName");

Adobe也在官方網站已經提供了RTMP協議的官方文檔說明,為什麼要寫這個系列文章最大的原因只是對前一段工作的一個總結和回顧,最近兩個月,實現了一個RTMP Server的c++版本,把公司的流媒體服務和flash無縫對接起來。希望我的文字能給後來研究這個協議的同學有一定的協助。

RTMP協議是一個基於TCP的高層協議族,當然這個玩意據說還有UDP協議版本的,不過現在還沒有出來,好像Adobe下一版本的FMS會提供支援。下文將要描述的是TCP協議版本的協議。

   RTMP協議的概要理解:

RTMP協議是為了和flash之間交換信令以及媒體資料。為了提高使用效率信令和媒體資料都是使用相同的機制。因為是相同的機制Adobe就整出來了一些比較搞人的概念,當然每個協議第一次接觸都是比較難理解的。

       在RTMP協議中信令和媒體資料都稱之為Message,在網路中傳輸這些Message,為了區分它們肯定是要加一個Message head的,所以RTMP協議也有一個Message head,還有一個問題因為RTMP協議是基於TCP的,由於TCP的包長度是有限制的(一般來說不超過1500個位元組),而RTMP的Message長度是有可能很大的,像一個視訊框架的包可能會有幾十甚至幾千K,這個問題就必然有一個分區的問題,在RTMP協議中對應的說法就是chunk,每一個Message + head都是由一個和多個chunk組成的。到這裡對RTMP協議的概要理解就算完了。

RTMP的位元組序:
       RTMP的位元組序和大多數網路通訊協定一樣是大端序,也有一些欄位是小端序的,不過都有特殊的說明。
RTMP的head組成

         RTMP的head在協議中的表現形式是chunk head,前面已經說到一個Message + head可以分成一個和多個chunk,為了區分這些chunk,肯定是需要一個chunk head的,具體的實現就把Message head的資訊和chunk head的資訊合并在一起以chunk head的形式表現。

        一個完整的chunk的組成如所示

                                                        
    

Chunk basic header:

該欄位包含chunk的stream ID和 type 。chunk的Type決定了訊息頭的編碼方式。該欄位的長度完全依賴於stream ID,該欄位是一個可變長的欄位。

Chunk Msg Header:0, 3 ,7, 11

該欄位包含了將要發送的訊息的資訊(或者是一部分,一個訊息拆成多個chunk的情況下是一部分)該欄位的長度由chunk basic header中的type決定。

Extend Timestamp: 0 ,4 bytes

該欄位發送的時候必須是正常的時間戳記設定成0xffffff時,當正常時間戳記不為0xffffff時,該欄位不發送。當時間戳記比0xffffff小該欄位不發送,當時間戳記比0xffffff大時該欄位必鬚髮送,且正常時間戳記設定成0xffffff。

        Chunk Data
        實際資料(Payload),可以是信令,也可以是媒體資料。

Chunk basic header:
   chunk basic head的長度為1~3個位元組,具體長度主要是依賴chunk stream ID的長度,所謂chunk stream ID是flash server用來管理串連的用戶端的信令互動的標識,在red5的文檔中稱之為channel ID,協議最大支援65597個streamID 從3~65599。ID 0,1,2為協議保留,0代表ID是64~319(第二個byte + 64);1代表chunk stream ID為64~65599((第三個byte)* 256 + 第二個byte + 64)(小端表示);2代表該訊息為低層的協議(在RTMP協議中控制信令的chunk stream ID都是2)。3~63的chunk stream ID就是該byte的值。沒有附加的欄位來標識chunk stream streamID。在這裡要指出的是雖然RTMP的chunk stream ID理論是可以達到65599,但是目前使用的chunk stream ID很少,2~7都是約定的,8是用來傳輸publish play等命令,其他的chunk stream ID目前好像沒有使用,至少我不知道用來幹嘛的。
      所以目前chunk basic head的長度一般為1個位元組。這一個位元組由兩部分組成
                           +++++++++++++++++++
                            +fmt    + cs id               +
                            +++++++++++++++++++
      fmt佔兩個bit用來標識緊跟其後的chunk Msg Header的長度,cs id佔六個bit。
      兩位的fmt取值為 0~3,分別代表的意義如下:
      case 0:chunk Msg Header長度為11;
      case 1:chunk Msg Header長度為7;
      case 2:chunk Msg Header長度為3;
      case 3:chunk Msg Header長度為0;
      所以 只有一個位元組的chunk basic header取值為 chunk basic header = (fmt << 6) | (cs id).

Chunk Msg Header:

Chunk Msg Header的長度是可變的,Chunk Msg Header可變的原因是為了壓縮傳輸的位元組數,把一些相同類型的chunk的head去掉一些位元組,換句話說就是四種類型的包頭都可以通過一定的規則還原成11個位元組,這個壓縮和還原在RTMP協議中稱之為複用/解複用。

那我們以11個位元組的完整包頭來解釋Chunk Msg Header,

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+        timestamp    +    message length + message type id +    message stream id +

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Timestamp:3bytes

對於type 0的chunk,絕對時間戳記在這裡表示,如果時間戳記值大於等於0xffffff(16777215),該值必須是0xffffff,且時間戳記擴充欄位必鬚髮送,其他情況沒有要求。

message length:3bytes

Message的長度,注意這裡的長度並不是跟隨chunk head其後的chunk data(Payload)的長度,而是前文提到的一條信令或者一幀視頻資料或音頻資料的長度。前文提到過信令或者媒體資料都稱之為Message,一條Message可以分為一條或者多條chunk。

message type id:1byte

Message的類型ID,具體的值將在後文專門來討論。

message stream id:4bytes

message stream id的位元組序是小端序,這個欄位是為瞭解複用而設計的,RTMP文檔上說的相當的模糊,

message stream ID可以使任意值,不同的訊息流程複用成相同的chunk stream,基於它們的ID能夠解複用。於chunk stream 是相關的,這個欄位是一個不透明的值沒有整明白什麼意思,我的理解就是用來標識和伺服器串連的flash端的序號。

長度是7 bytes 的chunk head,該類型不包含stream ID,該chunk的streamID和前一個chunk的stream ID是相同的,變長的訊息,例如視頻流格式,在第一個新的chunk以後使用這種類型,注意其中時間戳記部分是相對時間,為何上一個絕對時間之間的差值 :

++++++++++++++++++++++++++++++++++++++++++++++++++++++

+     timestamp    delta    +    message length + message type id +   

++++++++++++++++++++++++++++++++++++++++++++++++++++++

        3 bytes的chunk head,該類型既不包含stream ID 也不包含訊息長度,這種類型用於stream ID和前一個chunk相同,且有固定長度的資訊,例如音頻流格式,在第一個新的chunk以後使用該類型。:

                           ++++++++++++++++++++

                           +     timestamp    delta    + 

                           ++++++++++++++++++++

        0 bytes的chunk head,這種類型的chunk從前一個chunk得到值資訊,當一個單個訊息拆成多個chunk時,這些chunk除了第一個以外,其他的都應該使用這種類型,

chunk的長度:

chunk的長度初始長度固定為128個位元組,但是這個值並不是不可變的,在用戶端和服務端建立串連以後,用戶端和服務端都可以通過發送信令的方式來通知對端修改chunk的長度,理論上來說可以修改chunk的最長長度為65536。這裡chunk的長度是指chunk的資料部分的長度,即chunk data(payload)的長度,如果一條Message的資料長度超過了chunk的長度,就必須把Message分割成多條chunk,即如果一條視頻類型Message長度為2000個byte,chunk長度為1500,則該Message將會分割成兩條chunk,第一條的chunk data長度為1500,第二條的chunk data長度為500。當然這兩條chunk的chunk head肯定是不同的,其中第二條chunk的chunk head就是0位元組的。

 

RTMP協議詳解(轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.