RTMP協(xié)議抓包分析拉流過(guò)程

基本概念:

RTMP協(xié)議規(guī)定,播放一個(gè)流媒體有兩個(gè)前提步驟:
第一步,建立一個(gè)網(wǎng)絡(luò)連接(NetConnection)唤蔗。
第二步义锥,建立一個(gè)網(wǎng)絡(luò)流(NetStream)柳沙。
網(wǎng)絡(luò)連接代表服務(wù)器端應(yīng)用程序和客戶端之間基礎(chǔ)的連通關(guān)系,網(wǎng)絡(luò)流代表了發(fā)送多媒體數(shù)據(jù)的通道拌倍。服務(wù)器和客戶端之間只能建立一個(gè)網(wǎng)絡(luò)連接赂鲤,但是基于該連接可以創(chuàng)建很多網(wǎng)絡(luò)流。

播放一個(gè)RTMP協(xié)議的流媒體需要經(jīng)過(guò)四個(gè)階段:

  1. 握手階段
  2. 建立連接階段
  3. 建立流階段
  4. 播放階段
    RTMP連接都是以握手作為開(kāi)始的柱恤,建立連接階段用于建立客戶端與服務(wù)器之間的“網(wǎng)絡(luò)連接”数初。
    建立流階段用于建立客戶端與服務(wù)器之間的“網(wǎng)絡(luò)流”。
    播放階段用于傳輸視音頻數(shù)據(jù)膨更。

下面是使用librtmp執(zhí)行拉流過(guò)程的API調(diào)用流妙真,如下:


image.png

抓包分析:

RTMP定義了較為完善的協(xié)議標(biāo)準(zhǔn),但是每種播放工具的實(shí)現(xiàn)略有差異荚守,下面是我使用VLC播放器拉流時(shí)抓取的報(bào)文珍德,使用wireshark分析過(guò)程整理為下面的圖文。

先看一張總覽圖矗漾,圖中顯示的報(bào)文和時(shí)序包含了握手锈候、建立連接、建立流和播放階段敞贡,如下:


image.png

還有申明下泵琳,以下的流程是根據(jù)實(shí)際抓包情況分析出來(lái)的,由于不同的工具省略了一些不必要的步驟,故不代表標(biāo)準(zhǔn)結(jié)果获列,僅供參考谷市。

握手階段:

由于講解握手過(guò)程的文檔資料比較多,我這里就不重復(fù)描述了击孩,摘圖如下:


image.png

個(gè)人認(rèn)為這張圖是最符合標(biāo)準(zhǔn)時(shí)序的迫悠,細(xì)節(jié)拿捏得非常講究,雖然很多實(shí)現(xiàn)簡(jiǎn)化了流程巩梢。

建立連接階段:

包括以下報(bào)文和步驟:

  1. 客戶端發(fā)起連接請(qǐng)求
  2. 服務(wù)器設(shè)置客戶端的應(yīng)答窗口大小
  3. 服務(wù)器設(shè)置客戶端的發(fā)送帶寬大小
  4. 服務(wù)器設(shè)置客戶端的接收塊大小
  5. 服務(wù)器響應(yīng)連接結(jié)果
  6. 客戶端設(shè)置服務(wù)器的應(yīng)答窗口大小
客戶端發(fā)起連接請(qǐng)求:

協(xié)議截圖如下:


image.png

協(xié)議方向:客戶端 -> 服務(wù)器
塊頭字段:
???? HeaderType: 0
???? CSID: 3
???? 時(shí)間戳:0
???? BodySize: 201
???? TypeID: 0x14
???? Stream ID: 0
負(fù)載格式:AMF0表示创泄,connect 1 object1
???? object1屬性列表:
???? ???? "app": "live"
???? ???? "flashVer": "LNX 9,0,124,2"
???? ???? "tcUrl": "rtmp://127.0.0.1:1935/live"
???? ???? "fpad": false
???? ???? "capabilities": 15,
???? ???? "audioCodes": 4071,
???? ???? "videoCodes": 252,
???? ???? "videoFunction": 1,
???? ???? End Of Object Marker

服務(wù)器設(shè)置客戶端的應(yīng)答窗口大小:

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 2
???? 時(shí)間戳:0
???? BodySize: 4
???? TypeID: 0x05
???? Stream ID: 0
負(fù)載格式:4字節(jié)整型表示括蝠,如5000000

服務(wù)器設(shè)置客戶端的發(fā)送帶寬大芯弦帧:

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 2
???? 時(shí)間戳:0
???? BodySize: 5
???? TypeID: 0x06
???? Stream ID: 0
負(fù)載格式:5字節(jié)整型表示,前4字節(jié)為帶寬忌警,后1字節(jié)為標(biāo)志搁拙,如5000000, 2(動(dòng)態(tài)調(diào)整)

服務(wù)器設(shè)置客戶端的接收塊大小:

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 2
???? 時(shí)間戳:0
???? BodySize: 4
???? TypeID: 0x01
???? Stream ID: 0
負(fù)載格式:4字節(jié)整型表示法绵,如4096

服務(wù)器響應(yīng)連接結(jié)果:

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 3
???? 時(shí)間戳:0
???? BodySize: 190
???? TypeID: 0x14
???? Stream ID: 0
負(fù)載格式:AMF0表示感混,_result 1 object1 object2
???? object1屬性列表:
???? ???? "fmsVer": "FMS/3,0,1,123"
???? ???? "capabilities": 31,
???? ???? End Of Object Marker
???? object2屬性列表:
???? ???? "level": "status"
???? ???? "code": "NetConnection.Connect.Success",
???? ???? "description": "Connection succeeded.",
???? ???? "objectEncoding": 0
???? ???? End Of Object Marker

客戶端設(shè)置服務(wù)器的應(yīng)答窗口大小:

協(xié)議截圖如下:


image.png

協(xié)議方向:客戶端 -> 服務(wù)器
塊頭字段:
???? HeaderType: 0
???? CSID: 2
???? 時(shí)間戳:0
???? BodySize: 4
???? TypeID: 0x05
???? Stream ID: 0
負(fù)載格式:4字節(jié)整型表示礼烈,如5000000

建立流階段:

包括以下報(bào)文和步驟:

  1. 客戶端發(fā)起創(chuàng)建流請(qǐng)求
  2. 服務(wù)器響應(yīng)創(chuàng)建流結(jié)果
客戶端發(fā)起創(chuàng)建流請(qǐng)求:

協(xié)議截圖如下:


image.png

協(xié)議方向:客戶端 -> 服務(wù)器
塊頭字段:
???? HeaderType: 1
???? CSID: 3
???? 時(shí)間戳:0
???? BodySize: 25
???? TypeID: 0x14
負(fù)載格式:AMF0表示弧满,createStream 2 object(Null)

服務(wù)器響應(yīng)創(chuàng)建流結(jié)果:

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 3
???? 時(shí)間戳:0
???? BodySize: 29
???? TypeID: 0x14
???? Stream ID: 0
負(fù)載格式:AMF0表示,_result 2 object(Null) Number(1)

播放階段:

包括以下報(bào)文和步驟:

  1. 客戶端發(fā)起播放節(jié)目請(qǐng)求
  2. 客戶端通知服務(wù)器設(shè)置緩沖區(qū)大小
  3. 服務(wù)器通知客戶端啟動(dòng)流
  4. 服務(wù)器通知客戶端流進(jìn)入播放狀態(tài)
  5. 服務(wù)器向客戶端發(fā)送媒體元數(shù)據(jù)
  6. 服務(wù)器向客戶端發(fā)送媒體數(shù)據(jù)
客戶端發(fā)起播放節(jié)目請(qǐng)求:

協(xié)議截圖如下:


image.png

協(xié)議方向:客戶端 -> 服務(wù)器
塊頭字段:
???? HeaderType: 0
???? CSID: 8
???? 時(shí)間戳:0
???? BodySize: 30
???? TypeID: 0x14
???? Stream ID: 1
負(fù)載格式:AMF0表示此熬,play 4 Object(Null) String節(jié)目ID("a") Number開(kāi)始時(shí)間(-2000)

客戶端通知服務(wù)器設(shè)置緩沖區(qū)大型ノ亍:

協(xié)議截圖如下:


image.png

協(xié)議方向:客戶端 -> 服務(wù)器
塊頭字段:
???? HeaderType: 1
???? CSID: 2
???? 時(shí)間戳:1
???? BodySize: 10
???? TypeID: 0x04
負(fù)載格式:Event Type,2字節(jié)的類型(3) 4字節(jié)的流ID(1) 4字節(jié)的MS時(shí)間單位(3000)

服務(wù)器通知客戶端啟動(dòng)流:

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 2
???? 時(shí)間戳:0
???? BodySize: 6
???? TypeID: 0x04
負(fù)載格式:Event Type犀忱,2字節(jié)的類型(0) 4字節(jié)的流ID(1)

服務(wù)器通知客戶端流進(jìn)入播放狀態(tài):

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 5
???? 時(shí)間戳:0
???? BodySize: 96
???? TypeID: 0x14
???? Stream ID: 1
負(fù)載格式:AMF0表示募谎,onStatus 0 Object1(Null) object2
???? object2屬性列表:
???? ???? "level": "status"
???? ???? "code": "NetStream.Play.Start",
???? ???? "description": "Start live",
???? ???? End Of Object Marker

服務(wù)器向客戶端發(fā)送媒體元數(shù)據(jù):

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 5
???? 時(shí)間戳:0
???? BodySize: 387
???? TypeID: 0x12
???? Stream ID: 1
負(fù)載格式:AMF0表示,onMetaData object
???? object屬性列表:
???? ???? "Server": "NGINX RTMP"
???? ???? "width": 480,
???? ???? "height": 270,
???? ???? "displayWidth": 480,
???? ???? "displayHeight": 270,
???? ???? "duration": 0,
???? ???? "framerate": 16,
???? ???? "fps": 16,
???? ???? "videodatarate": 193,
???? ???? "videocodeid": 7,
???? ???? "audiodatarate": 52,
???? ???? "audiocodeid": 10,
???? ???? "profile": "",
???? ???? "level": "",
???? ???? End Of Object Marker

服務(wù)器向客戶端發(fā)送媒體數(shù)據(jù):

協(xié)議截圖如下:


image.png

協(xié)議方向:服務(wù)器 -> 客戶端
塊頭字段:
???? HeaderType: 0
???? CSID: 6
???? 時(shí)間戳:0
???? BodySize: 209
???? TypeID: 0x08
???? Stream ID: 1
負(fù)載格式:格式頭阴汇,媒體數(shù)據(jù)

流程時(shí)序:

結(jié)合以上分析数冬,總結(jié)時(shí)序圖如下:


拉流時(shí)序.png

另外,關(guān)于HeaderType和CSID的運(yùn)用搀庶,先歸納使用情況:
0x14(connect) HeaderType: 0 CSID: 3
0x05(Ack Window Size) HeaderType: 0 CSID: 2
0x06(BrandWidth) HeaderType: 0 CSID: 2
0x01(ChunkSize) HeaderType: 0 CSID: 2
0x14(connect _result) HeaderType: 0 CSID: 3
0x14(createStream) HeaderType: 1 CSID: 3
0x14(createStream _result) HeaderType: 0 CSID: 3
0x14(play) HeaderType: 0 CSID: 8
0x04(SetBufferMS) HeaderType: 1 CSID: 2
0x04(Stream Begin) HeaderType: 0 CSID: 2
0x14(play onStatus) HeaderType: 0 CSID: 5
0x12(onMetaData) HeaderType: 0 CSID: 5
0x08(audioData) HeaderType: 0 CSID: 6
0x09(videoData) HeaderType: 0 CSID: 7

總結(jié):
關(guān)于HeaderType的運(yùn)用拐纱,有以下規(guī)則:
createStream使用1號(hào)HeaderType,借用3號(hào)CSID之前的StreamID哥倔。
SetBufferMS使用1號(hào)HeaderType秸架。
audioData和videoData視情況使用0、1咆蒿、2东抹、3號(hào)HeaderType蚂子。
關(guān)于CSID的運(yùn)用,有以下規(guī)則:

  1. 0x01~0x06命令用2號(hào)CSID缭黔。
  2. 大部分0x14命令用3號(hào)CSID食茎,但有例外,如play用8號(hào)CSID馏谨,play onStatus用5號(hào)CSID董瞻。
  3. 0x12媒體元數(shù)據(jù)用5號(hào)CSID。
  4. 0x08音頻數(shù)據(jù)用6號(hào)CSID田巴。
  5. 0x09視頻數(shù)據(jù)用7號(hào)CSID。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挟秤,一起剝皮案震驚了整個(gè)濱河市壹哺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌艘刚,老刑警劉巖管宵,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異攀甚,居然都是意外死亡箩朴,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門秋度,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)炸庞,“玉大人,你說(shuō)我怎么就攤上這事荚斯〔壕樱” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵事期,是天一觀的道長(zhǎng)滥壕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)兽泣,這世上最難降的妖魔是什么绎橘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮唠倦,結(jié)果婚禮上称鳞,老公的妹妹穿的比我還像新娘。我一直安慰自己稠鼻,他們只是感情好胡岔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著枷餐,像睡著了一般靶瘸。 火紅的嫁衣襯著肌膚如雪苫亦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天怨咪,我揣著相機(jī)與錄音屋剑,去河邊找鬼。 笑死诗眨,一個(gè)胖子當(dāng)著我的面吹牛唉匾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匠楚,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼巍膘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了芋簿?” 一聲冷哼從身側(cè)響起峡懈,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎与斤,沒(méi)想到半個(gè)月后肪康,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撩穿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年磷支,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片食寡。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雾狈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抵皱,到底是詐尸還是另有隱情箍邮,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布叨叙,位于F島的核電站锭弊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏擂错。R本人自食惡果不足惜味滞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望钮呀。 院中可真熱鬧剑鞍,春花似錦、人聲如沸爽醋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蚂四。三九已至光戈,卻和暖如春哪痰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背久妆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工晌杰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筷弦。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓肋演,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親烂琴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爹殊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • RTMP協(xié)議是Real Time Message Protocol(實(shí)時(shí)信息傳輸協(xié)議)的縮寫(xiě),它是由Adobe公司...
    iOS小肖閱讀 3,471評(píng)論 0 4
  • RTMP協(xié)議是Real Time Message Protocol(實(shí)時(shí)信息傳輸協(xié)議)的縮寫(xiě)奸绷,它是由Adobe公司...
    日月當(dāng)頭閱讀 39,549評(píng)論 6 67
  • 本文轉(zhuǎn)自:http://www.reibang.com/p/b2144f9bbe28 RTMP協(xié)議是Real T...
    pandazhong閱讀 359評(píng)論 0 0
  • 一梗夸、RTMP 協(xié)議簡(jiǎn)介 RTMP(Real-Time Messaging Protocol),譯為:實(shí)時(shí)消息傳輸協(xié)...
    村口大白楊閱讀 896評(píng)論 0 1
  • RTMP協(xié)議是Real Time Message Protocol(實(shí)時(shí)信息傳輸協(xié)議)的縮寫(xiě)健盒,它是由Adobe公司...
    我是李小胖閱讀 1,261評(píng)論 0 0