rtmp 封包及消息

1 握手

     adobe修改了握手部分的協議,可是沒有公開。根據rtmp specification 1.0裏面的握手過程,flash player是播不了h264編碼的視頻。修正後的握手協議能夠參照:http://blog.csdn.net/winlinvip/article/details/7714493html

 

2 rtmp 包格式

     rtmp 使用塊(chunk)的概念來發送數據,默認的塊大小是128(不包括頭部數據大小),若是要發送的數據超過了設定的塊大小,就要分爲多塊進行發送。rtmp chunk的整體格式以下所示,rtmp
chunk頭部信息包括三部分:基本頭,消息頭,擴展時間戳。網絡

+----------------+--------------------+-------------------------+----------------+ide

| Basic Header | Message Header | Extended Timestamp |  Chunk Data  |編碼

+----------------+--------------------+-------------------------+----------------+spa

|                                                                                   |.net

|<------------------- Chunk Header ------------------------->|code

 

2.1 rtmp chunk basic header

     rtmp 塊的基本頭包手兩個信息:塊格式(chunk format) 和 塊流ID(chuck stream id)orm

  0  1 2  3   4  5  6  7視頻

+-+-+-+-+-+-+-+-+server

| fmt |   cs id           |

+-+-+-+-+-+-+-+-+

     fmt: rtmp塊頭的格式,有4種類型

     cs_id:

cs_id 塊流ID 基本頭的長度(字節)
>=2 cs_id 1
0 【第二字節的值】 + 64 2
1 【第三字節的值】*256+【第二字節的值】+64 3

 

2.2 rtmp message header

     rtmp 消息頭通常包括:時間戳(3Bytes),消息長度(3Bytes),消息類型(1Byte),消息流Id(4Bytes)。

可是並不老是會包含這些信息。可是能夠根據塊基本頭的fmt,來判斷消息頭中包含了哪些信息(如表格所示)。

 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)                                    |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+     

 

fmt timestamp message length message type id msg stream id 消息頭長度
0 Y Y Y Y 11
1 Y Y Y x 7
2 Y x x x 3
3 x x x x 0

          注意:a.發包的原則是同一個塊流ID,第一個包通常使用fmt0,而後再根據狀況選擇使用fmt1,fmt2,fmt3.

                    b.timestamp,只有當是fmt0時,才表示一個絕對時間戳,其它格式都是一個時間差值,即相對於上一個包的時間增量。

                    c.對於fmt1,fmt2,fmt3;缺失的信息,使用最近收到的的同一個塊流id的fmt0格式的包。

                   d.因此有信息使用大端編碼,除了消息流id是使用小端編碼。

 

2.3 extended timestamp

     擴展時間戳,4字節,當timestamp > 0xffffff,使用擴展時間戳,不然不使用

 

2.4 example

     a. 發送alaw音頻包,編碼器的打包大小爲320字節,時間間隔爲40ms,假設塊大小設定爲1000,幾個音頻包的時間戳依次爲1000、1040、1080、1120.....,則可能的發送格式以下所示:

rtmp packet format timestamp message length packet size
#1 fmt0 1000 320 320+1+11
#2 fmt2 40 x 320+1+3
#3 fmt3 x x 320+1
#4 fmt3 x x 320+1

注:上例咱們也能夠每一個包都用fmt0來發送,這樣的話,每一個包都要指定準確的時間戳和長度。

     b. 發送視頻包,時間間隔爲40ms,假設塊大小設定爲1000,幾個視頻包的時間戳依次爲1000、1040.....,大小依次爲2500,1600,....則可能的發送格式以下所示:

rtmp packet format timestamp message length packet size
#1 fmt0 1000 2500 1000+1+11
#2 fmt3 x x 1000+1
#3 fmt3 x x 500+1
#4 fmt0 1040 1500 1000+1+11
#5 fmt3 x x 600+1

          注:上例中若是每幀的音頻間隔是相等,第二幀的第一個包(#4),咱們也能夠用fmt1來發送,將消息頭中的timestamp指定爲時間差。並指定幀長。

3 rtmp control message

     rtmp中各種消息的區分是經過消息頭中的消息類型id(message type id)來區分。控制消息(control message)包括設置塊大小(1),停止消息(2),應答消息(3),設定窗口應答大小(5),設置對方帶寬(6),用戶控制消息(4)。

     控制消息發送時,消息流id(message stream id)必須爲0,塊Id必須爲2.

3.1 set chunk size(消息類型:1)

     設置塊大小,默認塊大小爲128字節。直接在包頭部後面跟4字節的要設定的塊大小。

 

3.2 abort message(消息類型:2)

     用於停止消息。接在包頭部後面跟4字節的要停止的塊流大小。

3.3 Acknowledge(消息類型:3)

     應答消息,用於接收端(flash player)報告,總共接收到的字節數。直接在包頭部後面跟4字節的收到的字節數。

 

3.4 window acknowledgement size(消息類型:5)

     指定應答的間隔,即距離上一次應答後收到的字節數。

 

3. 5 set peer bandwidth(消息類型:6)

     用於限定對方發送帶寬

 

4 rtmp command message (命令消息)

     命令消息包括音頻消息(8),視頻消息(9),集成控制(22),共享對象消息(19【amf0】,16【amf3】),數據消息(18【amf0】,15【amf3】),命令(遠程調用)消息(20【amf0】,17【amf3】)。之後會針對性講解三類主要的消息(遠程調用 ,音頻,視頻消息)。

4.1 command message (命令/遠程調用消息)

     遠程調用消息,這類消息在我看來就是flash player的一個遠程方法調用。故稱之爲遠程調用消息。flash 的實現的兩個基本類:NetConnection和NetStream,分別負責建立鏈接和進行網絡流的點播控制。遠程調用消息主要是這兩個類的公有方法在服務端的遠程調用。這兩個類的具體介紹參見adobe的官網。其中有詳細的介紹有哪些公有方法,以及相關的參數和可能的返回值。全部的參數和返回值都是經過AMF0或AMF3來表示。

http://livedocs.adobe.com/flash/9.0_cn/ActionScriptLangRefV3/flash/net/NetConnection.html

http://livedocs.adobe.com/flash/9.0_cn/ActionScriptLangRefV3/flash/net/NetStream.html

4.1.1 NetConnection.connect

    鏈接請求:

 

     返回鏈接失敗:

 

鏈接可用的返回值以下表所示,詳見:http://livedocs.adobe.com/flash/9.0_cn/ActionScriptLangRefV3/flash/events/NetStatusEvent.html#info

"NetConnection.Connect.Failed" "error" 鏈接嘗試失敗。
"NetConnection.Connect.Success" "status" 鏈接嘗試成功。
"NetConnection.Connect.Rejected" "error" 鏈接嘗試沒有訪問應用程序的權限。
"NetConnection.Connect.InvalidApp" "error" 鏈接時指定的應用程序名無效。

4.1.2 NetConnection.close (略)

4.1.3 NetStream.receiveVideo

     告知對方是否須要視頻數據。由boolean類型的參數指定是否須要視頻數據。該命令無需返回(應答)。

 

4.1.4 NetStream.receiveAudio

     告知對方是否須要音頻數據。由boolean類型的參數指定是否須要音頻數據。該命令無需返回(應答)。格式相似NetStream.receiveVideo。

4.1.5 NetStream.play

     告知對方須要點播的文件。請求格式見下圖:

 

     返回消息:

 

     可用的返回值見下表:

"NetStream.Play.Start" "status" 播放已開始。
"NetStream.Play.Failed" "error" 出於此表中列出的緣由以外的某一緣由(例如訂閱者沒有讀取權限),播放發生了錯誤。
"NetStream.Play.StreamNotFound" "error" 沒法找到傳遞給 play() 方法的 FLV。
"NetStream.Play.Reset" "status" 由播放列表重置致使。
"NetStream.Play.InsufficientBW" "warning" 僅限 Flash Media Server。 客戶端沒有足夠的帶寬,沒法以正常速度播放數據。

     在正式播放以前,必須發送stream begin(event type爲0)的用戶控制消息告知flash player爲播放作好準備。

4.2 Video message

     視頻消息,消息id爲9。h264基本的封裝格式以下所示(關於flv的格式詳見adobe flash video file format specification version 10.1):

| rtmp header | FLV video tag header | nalu size | nalu data(不包含start code)  |

若是nalu的大小超出了設定的chunk大小,就要進行分塊發送。分塊的方式見2.4例子

4.3 Audio message

     音頻消息,消息id爲8。基本的封裝格式以下所示(關於flv的格式詳見adobe flash video file format specification version 10.1):

 

| rtmp header | FLV audio tag header | audio data  |

4.4 User control message

     用戶控制消息。可用的用戶控制事件包括:stream begin(0),stream EOF(1),stream dry(2),SetBufferLength(3),StreamIsRecorded(4),PingRequest(6),PingResponse(7)

5. 基本的服務端播放流程:

     基本的播放流程:收到鏈接請求-》應答鏈接成功-》收到播放請求-》檢測點播的流是否存在-》發送stream begin消息-》發送paly.start消息—-》連續發送音視數據-》。。。-》直接收到關閉鏈接請求或播放到文件末尾。

     【client】   |                                                                                                   |   【server】

                         |-----------1: connect------------------------------------------------>|

                         |<-----2: NetConnection.Connect.Success ------------|

                         |---------3: play------------------------------------------------------->|                        

                         |<-------4: stream begin -------------------------------------------|

                         |<-------5: NetStream.Play.Start---------------------------|

                         |<-------6: SetChunksize-------------------------------------------|

                         |<--------------video message-------------------------------------|

                         |<-------------audio message-------------------------------------|

                         |                         ...                                                                      |

相關文章
相關標籤/搜索