RTMP協(xié)議相關(guān)知識

@TOC

1. RTMP協(xié)議簡介

RTMP協(xié)議是一個互聯(lián)網(wǎng)TCP/IP五層體系結(jié)構(gòu)中應(yīng)用層的協(xié)議擂橘。RTMP協(xié)議中基本的數(shù)據(jù)單元稱為消息(Message)滞谢。當(dāng)RTMP協(xié)議在互聯(lián)網(wǎng)中傳輸數(shù)據(jù)的時候吃谣,消息會被拆分成更小的單元,稱為消息塊(Chunk)。RTMP 是目前主流的流媒體傳輸協(xié)議,廣泛用于直播領(lǐng)域存和,可以說市面上絕大多數(shù)的直播產(chǎn)品都采用了這個協(xié)議。
RTMP協(xié)議就像一個用來裝數(shù)據(jù)包的容器衷旅,這些數(shù)據(jù)可以是AMF格式的數(shù)據(jù),也可以是FLV中的視/音頻數(shù)據(jù)捐腿。一個單一的連接可以通過不同的通道傳輸多路網(wǎng)絡(luò)流。這些通道中的包都是按照固定大小的包傳輸?shù)摹?/p>

  • 優(yōu)點
  1. CDN 支持良好柿顶,主流的 CDN 廠商都支持
  2. 協(xié)議簡單茄袖,在各平臺上實現(xiàn)容易
  • 缺點
  1. 基于 TCP ,傳輸成本高嘁锯,在弱網(wǎng)環(huán)境丟包率高的情況下問題顯著
  2. 不支持瀏覽器推送
  3. Adobe 私有協(xié)議宪祥,Adobe 已經(jīng)不再更新

2. RTMP協(xié)議基本概念

2.1 消息相關(guān)概念

RTMP傳輸?shù)臄?shù)據(jù)的基本單元為Message,但是實際上傳輸?shù)淖钚卧荂hunk(消息塊)家乘,因為RTMP協(xié)議為了提升傳輸速度蝗羊,在傳輸數(shù)據(jù)的時候,會把Message拆分開來仁锯,形成更小的塊肘交,這些塊就是Chunk。

2.1.1 消息

消息是RTMP協(xié)議中基本的數(shù)據(jù)單元扑馁。不同種類的消息包含不同的Message Type ID,代表不同的功能凉驻。RTMP協(xié)議中一共規(guī)定了十多種消息類型腻要,分別發(fā)揮著不同的作用。

1-7的消息用于協(xié)議控制涝登,這些消息一般是RTMP協(xié)議自身管理要使用的消息雄家,用戶一般情況下無需操作其中的數(shù)據(jù)
Message Type ID為8,9的消息分別用于傳輸音頻和視頻數(shù)據(jù)
Message Type ID為15-20的消息用于發(fā)送AMF編碼的命令胀滚,負(fù)責(zé)用戶與服務(wù)器之間的交互趟济,比如播放乱投,暫停等等
消息首部(Message Header)有四部分組成:標(biāo)志消息類型的Message Type ID,標(biāo)志消息長度的Payload Length顷编,標(biāo)識時間戳的Timestamp戚炫,標(biāo)識消息所屬媒體流的Stream ID

在這里插入圖片描述

下面針對上圖的消息結(jié)構(gòu)體進(jìn)行簡要分析:

  • Message Type:它是一個消息類型的ID,通過該ID接收方可以判斷接收到的數(shù)據(jù)的類型媳纬,從而做相應(yīng)的處理双肤。Message Type ID在1-7的消息用于協(xié)議控制,這些消息一般是RTMP協(xié)議自身管理要使用的消息钮惠,用戶一般情況下無需操作其中的數(shù)據(jù)茅糜。
  • Message Type ID為8,9的消息分別用于傳輸音頻和視頻數(shù)據(jù)素挽。Message Type ID為15-20的消息用于發(fā)送AMF編碼的命令蔑赘,負(fù)責(zé)用戶與服務(wù)器之間的交互,比如播放预明,暫停等缩赛。
  • Playload Length: 消息負(fù)載的長度,即音視頻相關(guān)信息的的數(shù)據(jù)長度贮庞,4個字節(jié)
  • TimeStamp:時間戳峦筒,3個字節(jié)。
  • Stream ID:消息的唯一標(biāo)識窗慎。拆分消息成Chunk時添加該ID物喷,從而在還原時根據(jù)該ID識別Chunk屬于哪個消息。
  • Message Body:消息體遮斥,承載了音視頻等信息峦失。

2.1.2. 消息塊

在網(wǎng)絡(luò)上傳輸數(shù)據(jù)時,消息需要被拆分成較小的數(shù)據(jù)塊术吗,才適合在相應(yīng)的網(wǎng)絡(luò)環(huán)境上傳輸尉辑。RTMP協(xié)議中規(guī)定,消息在網(wǎng)絡(luò)上傳輸時被拆分成消息塊(Chunk)较屿。
消息塊首部(Chunk Header)有三部分組成:

  • 用于標(biāo)識本塊的Chunk Basic Header
  • 用于標(biāo)識本塊負(fù)載所屬消息的Chunk Message Header
  • 以及當(dāng)時間戳溢出時才出現(xiàn)的Extended Timestamp
在這里插入圖片描述

在這里插入圖片描述

通過上圖可以看出隧魄,消息塊在結(jié)構(gòu)上與與消息類似,有Header和Body隘蝎。
下面對圖的每個部分簡要介紹:

  • Basic Header:基本的頭部信息购啄,在頭部信息里面包含了chunk stream ID(流通道Id,用來標(biāo)識指定的通道)和chunk type(chunk的類型)嘱么。
  • Message Header:消息的頭部信息狮含,包含了要發(fā)送的實際信息(可能是完整的,也可能是一部分)的描述信息。Message Header的格式和長度取決于Basic Header的chunk type几迄。
  • Extended TimeStamp:擴展時間戳蔚龙。
  • Chunk Data:塊數(shù)據(jù)。

注意: RTMP在傳輸數(shù)據(jù)的時候映胁,發(fā)送端會把需要傳輸?shù)拿襟w數(shù)據(jù)封裝成消息木羹,然后把消息拆分成消息塊,再一個一個進(jìn)行傳輸屿愚。接收端收到消息塊后汇跨,根據(jù)Message Stream ID重新將消息塊進(jìn)行組裝、組合成消息妆距,再解除該消息的封裝處理就可以還原出媒體數(shù)據(jù)穷遂。由此可以看出,RTMP收發(fā)數(shù)據(jù)是以Chunk為單位娱据,而不是以Message為單位蚪黑。需要注意的是,RTMP發(fā)送Chunk必須是一個一個發(fā)送中剩,后面的Chunk必須等前面的Chunk發(fā)送完成忌穿。

2.1.3. 消息分塊

在消息被分割成幾個消息塊的過程中,消息負(fù)載部分(Message Body)被分割成大小固定的數(shù)據(jù)塊(默認(rèn)是128字節(jié)结啼,最后一個數(shù)據(jù)塊可以小于該固定長度)掠剑,并在其首部加上消息塊首部(Chunk Header),就組成了相應(yīng)的消息塊郊愧。消息分塊過程如圖5所示朴译,一個大小為307字節(jié)的消息被分割成128字節(jié)的消息塊(除了最后一個)。

RTMP傳輸媒體數(shù)據(jù)的過程中属铁,發(fā)送端首先把媒體數(shù)據(jù)封裝成消息眠寿,然后把消息分割成消息塊,最后將分割后的消息塊通過TCP協(xié)議發(fā)送出去焦蘑。接收端在通過TCP協(xié)議收到數(shù)據(jù)后盯拱,首先把消息塊重新組合成消息,然后通過對消息進(jìn)行解封裝處理就可以恢復(fù)出媒體數(shù)據(jù)例嘱。

在這里插入圖片描述

2.2. RTMP中的邏輯結(jié)構(gòu)

RTMP協(xié)議規(guī)定狡逢,播放一個流媒體有兩個前提步驟

第一步,建立一個網(wǎng)絡(luò)連接(NetConnection)
第二步拼卵,建立一個網(wǎng)絡(luò)流(NetStream)奢浑。

其中,網(wǎng)絡(luò)連接代表服務(wù)器端應(yīng)用程序和客戶端之間基礎(chǔ)的連通關(guān)系间学。網(wǎng)絡(luò)流代表了發(fā)送多媒體數(shù)據(jù)的通道。服務(wù)器和客戶端之間只能建立一個網(wǎng)絡(luò)連接,但是基于該連接可以創(chuàng)建很多網(wǎng)絡(luò)流低葫。他們的關(guān)系如圖所示:

在這里插入圖片描述

2.5.

2.6.

2.7.

3. RTMP協(xié)議流程

總的流程圖如下:


在這里插入圖片描述

3.1. 連接流程

播放一個RTMP協(xié)議的流媒體需要經(jīng)過以下幾個步驟:

  • 握手
  • 建立連接
  • 建立流
  • 播放

RTMP連接都是以握手作為開始的详羡。建立連接階段用于建立客戶端與服務(wù)器之間的“網(wǎng)絡(luò)連接”;建立流階段用于建立客戶端與服務(wù)器之間的“網(wǎng)絡(luò)流”嘿悬;播放階段用于傳輸視音頻數(shù)據(jù)实柠。

下面來詳細(xì)分析一下這幾個過程都做了一些什么東東

3.1.1.握手

在rtmp連接建立后,服務(wù)端與客戶端需要通過3次交換報文完成握手,握手其他的協(xié)議不同,是由三個靜態(tài)大小的塊,而不是可變大小的塊組成的,客戶端與服務(wù)器發(fā)送相同的三個chunk,客戶端發(fā)送c0,c1,c2,服務(wù)端發(fā)送s0,s1,s2。

  • 發(fā)送規(guī)則

握手開始于客戶端發(fā)送 C0善涨,C1 塊窒盐。
在發(fā)送 C2 之前客戶端必須等待接收 S1 。
在發(fā)送任何數(shù)據(jù)之前客戶端必須等待接收 S2钢拧。
服務(wù)端在發(fā)送 S0 和 S1 之前必須等待接收 C0蟹漓,也可以等待接收 C1。
服務(wù)端在發(fā)送 S2 之前必須等待接收 C1源内。
服務(wù)端在發(fā)送任何數(shù)據(jù)之前必須等待接收 C2葡粒。

  • 數(shù)據(jù)格式

C0與S0

C0和S0的長度是一個字節(jié),在 S0 中這個字段表示服務(wù)器選擇的 RTMP 版本膜钓。rtmp1.0規(guī)范所定義的版本是 3嗽交;0-2 是早期產(chǎn)品所用的,已被丟棄颂斜;4-31保留在未來使用夫壁;32-255 不允許使用(為了區(qū)分其他以某一字符開始的文本協(xié)議)。如果服務(wù)無法識別客戶端請求的版本沃疮,應(yīng)該返回 3 盒让。客戶端可以選擇減到版本 3 或選擇取消握手忿磅。

C1與S1

C1 和 S1 有 1536 字節(jié)長糯彬,由下列字段組成:
時間:4 字節(jié) 本字段包含時間戳。該時間戳應(yīng)該是發(fā)送這個數(shù)據(jù)塊的端點的后續(xù)塊的時間起始點葱她×冒牵可以是 0,* 或其他的 任何值吨些。為了同步多個流搓谆,端點可能發(fā)送其塊流的當(dāng)前值。
零:4 字節(jié) 本字段必須是全零豪墅。
隨機數(shù)據(jù):1528 字節(jié)泉手。 本字段可以包含任何值。 因為每個端點必須用自己初始化的握手和對端初始化的握 手來區(qū)分身份偶器,所以這個數(shù)據(jù)應(yīng)有充分的隨機性斩萌。但是并不需要加密安全的隨機值缝裤,或者動態(tài)值

C2與S2

C2 和 S2 消息有 1536 字節(jié)長。只是 S1 和 C1 的回復(fù)颊郎。本消息由下列字段組成憋飞。
時間:4 字節(jié) 本字段必須包含對等段發(fā)送的時間(對 C2 來說是 S1,對 S2 來說是 C1)姆吭。
時間 2:4 字節(jié) 本字段必須包含先前發(fā)送的并被對端讀取的包的時間戳榛做。
隨機回復(fù):1528 字節(jié) 本字段必須包含對端發(fā)送的隨機數(shù)據(jù)字段(對 C2 來說是 S1,對 S2 來說是 C1) 内狸。 每個對等端可以用時間和時間 2 字段中的時間戳來快速地估計帶寬和延遲检眯。 但這樣做可 能并不實用。
RTMP握手的這個過程就是完成了兩件事:1. 校驗客戶端和服務(wù)器端RTMP協(xié)議版本號昆淡,2. 是發(fā)了一堆數(shù)據(jù)锰瘸,猜想應(yīng)該是測試一下網(wǎng)絡(luò)狀況,看看有沒有傳錯或者不能傳的情況瘪撇。

  • 流程圖如下


    在這里插入圖片描述

3.1.2. 建立網(wǎng)絡(luò)連接

  • 流程圖如下:


    在這里插入圖片描述

下面對建立網(wǎng)絡(luò)連接的流程簡單介紹

  1. 客戶端發(fā)送命令消息中的“連接”(connect)到服務(wù)器获茬,請求與一個服務(wù)應(yīng)用實例建立連接。
  2. 服務(wù)器接收到連接命令消息后倔既,發(fā)送確認(rèn)窗口大小(Window Acknowledgement Size)協(xié)議消息到客戶端恕曲,同時連接到連接命令中提到的應(yīng)用程序。
  3. 服務(wù)器發(fā)送設(shè)置帶寬()協(xié)議消息到客戶端渤涌。
  4. 客戶端處理設(shè)置帶寬協(xié)議消息后佩谣,發(fā)送確認(rèn)窗口大小(Window Acknowledgement Size)協(xié)議消息到服務(wù)器端。
  5. 服務(wù)器發(fā)送用戶控制消息中的“流開始”(Stream Begin)消息到客戶端实蓬。
  6. 服務(wù)器發(fā)送命令消息中的“結(jié)果”(_result)茸俭,通知客戶端連接的狀態(tài)。

注意

這里面的connect 命令消息安皱,命令里面包含什么東西调鬓,協(xié)議中沒有說,真實通信中要指定一些編解碼的信息酌伊,這些信息是以AMF格式發(fā)送的, 其中audioCodecs和videoCodecs這兩個指定音視頻編碼信息的不能少的腾窝。

Window Acknowledgement Size 是設(shè)置接收端消息窗口大小,一般是2500000字節(jié)居砖,即告訴客戶端你在收到我設(shè)置的窗口大小的這么多數(shù)據(jù)之后給我返回一個ACK消息虹脯,告訴我你收到了這么多消息。在實際做推流的時候推流端要接收很少的服務(wù)器數(shù)據(jù)奏候,遠(yuǎn)遠(yuǎn)到達(dá)不了窗口大小循集,所以基本不用考慮這點。而對于服務(wù)器返回的ACK消息一般也不做處理蔗草,我們默認(rèn)服務(wù)器都已經(jīng)收到了這么多消息咒彤。
服務(wù)器返回的_result命令類型消息的payload length一般不會大于128字節(jié)疆柔,但是在最新的nginx-rtmp中返回的消息長度會大于128字節(jié),所以一定要做好收包镶柱,組包的工作婆硬。

3.1.3. 建立網(wǎng)絡(luò)流

  • 建立網(wǎng)絡(luò)流過程簡述
    創(chuàng)建完網(wǎng)絡(luò)連接之后就可以創(chuàng)建網(wǎng)絡(luò)流了

過程如下

  1. 客戶端發(fā)送命令消息中releaseStream命令到服務(wù)器端
  2. 客戶端發(fā)送命令消息中FCPublish命令到服務(wù)器端
  3. 客戶端發(fā)送命令消息中的“創(chuàng)建流”(createStream)命令到服務(wù)器端。
  4. 服務(wù)器端接收到“創(chuàng)建流”命令后奸例,發(fā)送命令消息中的“結(jié)果”(_result),通知客戶端流的狀態(tài)向楼。

注意:解析服務(wù)器返回的消息會得到一個stream ID, 這個ID也就是以后和服務(wù)器通信的 message stream ID, 一般返回的是1查吊,不固定。

  • 流程圖如下:


    在這里插入圖片描述

3.1.4. 播放流

圖如下:


在這里插入圖片描述
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末湖蜕,一起剝皮案震驚了整個濱河市逻卖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昭抒,老刑警劉巖评也,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異灭返,居然都是意外死亡盗迟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門熙含,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罚缕,“玉大人,你說我怎么就攤上這事怎静∮实” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵蚓聘,是天一觀的道長腌乡。 經(jīng)常有香客問我,道長夜牡,這世上最難降的妖魔是什么与纽? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮氯材,結(jié)果婚禮上渣锦,老公的妹妹穿的比我還像新娘。我一直安慰自己氢哮,他們只是感情好袋毙,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冗尤,像睡著了一般听盖。 火紅的嫁衣襯著肌膚如雪胀溺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天皆看,我揣著相機與錄音仓坞,去河邊找鬼。 笑死腰吟,一個胖子當(dāng)著我的面吹牛无埃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毛雇,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼嫉称,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了灵疮?” 一聲冷哼從身側(cè)響起织阅,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎震捣,沒想到半個月后荔棉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蒿赢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年润樱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羡棵。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡祥国,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晾腔,到底是詐尸還是另有隱情舌稀,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布灼擂,位于F島的核電站壁查,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏剔应。R本人自食惡果不足惜睡腿,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望峻贮。 院中可真熱鬧席怪,春花似錦、人聲如沸纤控。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽船万。三九已至刻撒,卻和暖如春骨田,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背声怔。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工态贤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人醋火。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓悠汽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親芥驳。 傳聞我的和親對象是個殘疾皇子介粘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

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

  • RTMP協(xié)議是Real Time Message Protocol(實時信息傳輸協(xié)議)的縮寫,它是由Adobe公司...
    iOS小肖閱讀 3,479評論 0 4
  • 實時消息協(xié)議---流的分塊 版權(quán)聲明: 版權(quán)(c)2009 Adobe系統(tǒng)有限公司晚树。全權(quán)所有。 摘要: 本備忘錄描...
    一個人zy閱讀 1,891評論 0 9
  • 版本記錄 前言 大家都知道很多視頻應(yīng)用的app中都是使用RTMP格式的協(xié)議雅采,這個是國際上共同使用的協(xié)議爵憎,我自己雖然...
    刀客傳奇閱讀 12,236評論 5 15
  • 個人翻譯,轉(zhuǎn)載請注明出處婚瓜,謝謝宝鼓! Adobe's Real Time Messaging Protocol 摘要 ...
    SniperPan閱讀 2,723評論 1 17
  • RTMP傳輸基本流程 發(fā)送端 Step 1: 把數(shù)據(jù)封裝成消息(Message)。 Step 2: 把消息分割成消...
    FlyingPenguin閱讀 2,841評論 0 19