RTMP

音視頻文章匯總,本文介紹RTMP望薄。

1.本地部署SRS

1.1安裝srs流媒體服務(wù)器

srs官??https://github.com/ossrs/srs
碼云的源速度快?https://gitee.com/winlinvip/srs.oschina.git
github的源速度慢?https://github.com/ossrs/srs.git
選擇版本release3.0

第一步摩泪,獲取SRS肋联。詳細參考GIT獲取代碼

git clone https://gitee.com/winlinvip/srs.oschina.git
cd srs.oschina
#使?當(dāng)前最新的3.0版本
git checkout -b 3.0 remotes/origin/3.0release
cd trunk

第二步宪卿,編譯SRS畜埋。詳細參考Build

./configure && make

第三步缆瓣,編寫SRS配置?件。詳細參考RTMP分發(fā)

將以下內(nèi)容保存為?件,譬如conf/rtmp.conf,服務(wù)器啟動時指定該配置?件(srs的conf?件夾有該?件)纱新。

# conf/rtmp.conf
listen 1935;
max_connections 1000;
vhost __defaultVhost__ {
}

第四步,啟動SRS展氓。詳細參考RTMP分發(fā)

./objs/srs -c conf/rtmp.conf

部署在虛擬機或云服務(wù)器上均可穆趴,使用ffmpeg或OBC客戶端推流脸爱,ffplay或VLC拉流進行播放


0.gif

2.RTMP原理

Real Time Messaging Protocol) 是一個應(yīng)用層協(xié)??主要用于在Flash player和服務(wù)器之間傳輸視頻,音頻未妹,控制命令等內(nèi)容簿废。協(xié)議的突出優(yōu)點是:低延時。

FFMPEG

推流 +FFPLAY 播放
推流
ffmpeg -re -i /mnt/hgfs/linux/vod/35.mp4 -c copy -f flv rtmp://192.168.100.41/live/35
拉流
ffplay rtmp://192.168.100.41/live/35
FFPLAY
播放
拉流
ffplay rtmp://202.69.69.180:443/webcast/bshdlive-pc

2.1RTMP播放流程

image

2.2推流流程

image

image

image

RTMP是基于TCP的應(yīng)用層協(xié)議络它。TCP的三次握手可實現(xiàn)RTMP 客戶端與RTMP服務(wù)器的指定端口(默認(rèn)端口為1935)建立一個可靠的網(wǎng)絡(luò)連接族檬。這里的的網(wǎng)絡(luò)連接接才是真正的物理連接。
完成了三次握手,客戶端和服務(wù)器端就可以開始傳輸數(shù)據(jù)化戳。


image

2.2.1TCP三次握手修高速公路

image

image

image

圖片.png

經(jīng)過三次握手客戶端與服務(wù)器端1935端口建立了TCP Connection


image

2.2.2RTMP握手

與其叫RTMP握手其實實質(zhì)上起到的是的作用单料。RTMP握手的基本流程


image

RTMP握手主要分為簡單握手和復(fù)雜握手。

簡單握手

image

image

簡單握手中C1 和 S1 從第9個字節(jié)開始都是隨機數(shù)点楼。
S2 是 C1 的復(fù)制扫尖。C2 是 S1 的復(fù)制。
協(xié)議版本號?8bit
C0客戶端版本
S服務(wù)器版本
目前版本為3(0 1 2已經(jīng)廢棄)


圖片.png

C1和S1數(shù)據(jù)包的長度都是1536字節(jié)
圖片.png

03( 00 (C1 開始 00 00 00 09 00 7c 02 f7 78 55 1e ce ab 8e)
S1 片段 00 90 65 30 0d 0e 0a 0d 64 84 1c ad 1e 7f 0c
C2和S2數(shù)據(jù)包長度都是1536字節(jié)掠廓,基本就是S1和C1的副本换怖。 ??


image

S2片段
圖片.png

image

復(fù)雜握手

相對于簡單握手和復(fù)雜握手主要是增加了更嚴(yán)格的驗證。
主要是將簡單握手中的1528Bytes隨機數(shù)的部分平均分成兩部分,一部分764Bytes存儲,public key(公共密鑰)蟀瞧,另一部分764Bytes存儲digest(密文,32字節(jié))沉颂。
另外復(fù)雜握手有一個明顯的特征就是:Version部分不為0
服務(wù)器端可根據(jù)這個來判斷是否簡單握手或復(fù)雜握手。


image

2.2.3Connect連接

這里也叫連接悦污,連接的是什么呢铸屉?必須明白RTMP中一個很重要的概念A(yù)pplication Instance。
不同的Application Instance 可根據(jù)功能等進行區(qū)分,比如直播可以用live來表示,點播回放可以用vod來表示切端。

rtmp://192.168.100.41/live/36
其中l(wèi)ive就是Application(Instance sport), music播放該流時connect 的地址就是
rtmp://192.168.100.41/live/36
image
圖片.png
image

2.2.4createStream(創(chuàng)建流)-創(chuàng)建邏輯通道

image

createStream命令用于創(chuàng)建邏輯通道彻坛,邏輯通道用于傳輸視頻、音頻、metadata小压。
在服務(wù)器的響應(yīng)報文中會返回Stream ID,用于唯一的標(biāo)示該Stream线梗。注意Message ID和Stream ID的區(qū)別。
The command structure from the client to the server is as follows:


image

The command structure from server to client is as follows:


image

image

圖片.png

圖片.png

2.2.5play(播放)

image

圖片.png

客戶端發(fā)送play命令來播放指定流怠益。開始傳輸數(shù)據(jù)仪搔。
如果發(fā)送play命令后想立即播放,需要清空play隊列中的其它流蜻牢,并將reset置為true烤咧。

2.2.6delete刪除流

image

The command structure from the client to the server is as follows:


image

刪除指定Stream ID 的流。服務(wù)器 不用對?條命令發(fā)?響應(yīng)報文抢呆。

2.3RTMP層次

RTMP層次(數(shù)據(jù)發(fā)送角度)


image

RTMP層次(數(shù)據(jù)接收角度)


圖片.png

RTMP層次(協(xié)議角度)


圖片.png

2.3.1Message和Chunk

Message RTMP 中一個重要的概念就是消息煮嫌。


圖片.png
image

2.3.2消息分類

消息主要分為三類:協(xié)議控制消息、數(shù)據(jù)消息抱虐、命令消息 等昌阿。
協(xié)議控制消息Message Type ID = 1 2 3 5 6 和 Message Type ID = 4 兩大類主要用于協(xié)議內(nèi)的控制消息,此部分后續(xù)將詳細分析恳邀。
數(shù)據(jù)消息
Message Type ID = 8 9 18
8: Audio ??數(shù)據(jù)
9: Video ??數(shù)據(jù)
18: Metadata 包括音視頻編碼懦冰、視頻寬高等信息。
命令消息
Command Message (20, 17)
此類型消息主?有 NetConnection 和 NetStream 兩個類谣沸,兩個類分別有多個函數(shù)刷钢,該消息的調(diào)用,可理解為遠程函數(shù)調(diào)用乳附。

stream ID

Message StreamID是音視頻流的唯一ID, 一路流如果既有音頻包又有視頻包内地,那么音頻包的StreamID和他視頻包的StreamID相同。
Chunk網(wǎng)絡(luò)中實際發(fā)送的內(nèi)容赋除。

message chunk
圖片.png

cs id即是 Chunk Stream ID


image

Chunk Stream ID

Each chunk that is created has a unique ID associated with it called chunk stream ID阱缓。(5.3.Chunking);
因為一個流當(dāng)中可以交錯傳輸多種消息類型的Chunk ??
那么多個Chunk怎么標(biāo)記同屬于同一類Message的呢?
答案是:Chunk Stream ID 區(qū)分的同一個Chunk Stream ID必然屬于同一個Message。
RTMP流中視頻和音頻擁有單獨的Chunk Stream ID贤重,比如音頻的cs id=20茬祷,視頻的cs id=21 。接收端接收到Chunk之后根據(jù)cs id分別將音頻和視頻拼成消息并蝗。

Message & Chunk

Message切割成一個或多個Chunk,然后在網(wǎng)絡(luò)上進行發(fā)送祭犯。當(dāng)發(fā)送時,一個chunk發(fā)送完畢后才可以發(fā)送下一個
chunk滚停。


image

拆分的時候的Chunk Size是128字節(jié)沃粗,以Message大小為300字節(jié)舉例進行拆分。300 = 128 + 128 + 44


image

發(fā)送端

首先將數(shù)據(jù)加工成消息(中間物),然后再將消息分割成Chunk(加上Chunk Header)键畴,然后將Chunk通過網(wǎng)絡(luò)發(fā)送出去最盅。

接收端

接收端將接收到的Chunk組裝成消息突雪。


圖片.png

RTMP協(xié)議角度

圖片.png

RTMP Chunk Header

RTMP Chunk Header的長度不是固定的,分為12 Bytes、8 Bytes涡贱、4 Bytes咏删、1 Byte四種,?由RTMP Chunk Header前2位決定。


image

一場直播如果不中斷的話问词,是不是只有一個流督函,也就是Message Stream ID一直到直播結(jié)束都是唯一的,Message 里面的Message Stream Id和Chunk里面的Chunk Stream Id屬于兩個不同的東西激挪,因為Chunk Stream Id用來區(qū)分音頻和視頻流

image

為什么Chunk Header會存在不同的長度

一般情況下msg stream id是不會變的辰狡,所以針對視頻或音頻,除了第一個RTMP Chunk Header是 12Byte的,后續(xù)即可采用8Bytes的垄分。 因為msg stream id占4個Bytes可省去宛篇。
如果消息的長度(message length)和類型(msg type id, 如視頻為9或音頻為8)又相同,即可將這兩部分也省去,RTMP Chunk Header采用4Bytes類型的薄湿。
如果當(dāng)前Chunk與之前的Chunk相比, msg stream id 相同,msg type id相同,message length相同,而且?都屬于同一個消息叫倍,由同一個Message切割成),這類Chunk的時間戳(timestamp)也是相同的,故后續(xù)的也可以省去,RTMP Chunk Header采用1 Byte類型的嘿般。
當(dāng)Chunk Size足夠大時(一般不這么干),此時所有的 Message都只能相應(yīng)切割成一個Chunk,該Chunk僅msg stream id相同段标。此時基本上除了第一個Chunk的Header是12Bytes外涯冠,其它所有Chunk的Header是8Bytes炉奴。


image

image

image

圖片.png

12Bytes Chunk Header舉例

RTMP Header(12 Bytes)
一般只有rtmp流剛開始的metadata、絕對時間戳的視頻或音頻是12Bytes蛇更。


image

image

有些控制消息也是12Bytes,比如connect瞻赶。


image

8Bytes Chunk Header舉例

image

image

4Bytes Chunk Header舉例

image

image

1Bytes Chunk Header舉例

image

RTMP傳輸基本流程

image

發(fā)送端
Step 1:
把數(shù)據(jù)封裝成消息(Message)。
Step 2:
把消息分割成消息塊(Chunk, 網(wǎng)絡(luò)中實際傳輸?shù)膬?nèi)容)派任。
Step 3:
將分割后的消息塊(Chunk)砸逊,通過TCP協(xié)議發(fā)出去。
接收端
Step 1:
在TCP協(xié)議收到數(shù)據(jù)后,先將消息塊重新組合成消息(Message)掌逛。
Step 2:
通過對消息進行解封裝處理就可以恢復(fù)出數(shù)據(jù)师逸。

RTMP為什么要將Message劃分為Chunk?

在互聯(lián)網(wǎng)中傳輸數(shù)據(jù)時,消息(Message)會被拆分成更小的單元,稱為消息塊(Chunk)豆混。
大的Message被切割成利于網(wǎng)絡(luò)上傳輸?shù)男hunk,切成小塊篓像,可防止大的數(shù)據(jù)塊(如視頻數(shù)據(jù))阻塞小的數(shù)據(jù)塊(如音頻數(shù)據(jù)或控制信號)。

image

如果一幀1080P I幀數(shù)據(jù)量為244KBytes,假設(shè)帶寬為10Mbit/s,傳輸一幀的耗時為:2441024 8/(1010241024) = 0.190625秒 =190毫秒
假如要實時傳輸25幀的I幀文件皿伺,即允許每幀傳輸最大耗時為40毫秒员辩,需要帶寬47.65625Mbit,這還沒包括傳輸中的ACK數(shù)據(jù)。
在RTMP中鸵鸥,消息(Message)主要分為兩大類:控制消息和數(shù)據(jù)消息奠滑。數(shù)據(jù)消息中由包括Video消息和Audio消息等。

消息都是怎么進行管理的?

通路只有一條(RTMP是單通路),到底誰先走呢宋税,誰后走呢摊崭?
答案是:分優(yōu)先級,優(yōu)先級高的先行杰赛。優(yōu)先級低的不能阻塞優(yōu)先級高的爽室。


image

RTMP Chunk Stream層級沒有優(yōu)先級的劃分,是在高層次Message stream提供優(yōu)先級的劃分。
不同類型的消息會被分配不同的優(yōu)先級淆攻,當(dāng)網(wǎng)絡(luò)傳輸能力受限時阔墩,優(yōu)先級用來控制消息在網(wǎng)絡(luò)底層的排隊順序。

比如當(dāng)客戶端網(wǎng)絡(luò)不佳時瓶珊,流媒體服務(wù)器可能會選擇丟棄視頻信息啸箫,以保證音頻消息可以及時送達客戶端。

image

RTMP Chunk Stream層級允許在Message stream層次伞芹,將大消息切割成小消息忘苛,這樣可以避免大的低優(yōu)先級的消息(如視頻消息)阻塞小的高優(yōu)先級的消息(如音頻消息或控制消息)。

RTMP消息優(yōu)先等級

image

image

Protocol Control Messages屬于RTMP Chunk Stream層級的控制消息唱较,用于該協(xié)議的內(nèi)部控制扎唾。


image

User Control Message 是RTMP streaming layer(即Message stream層次)的消息。

協(xié)議先行
協(xié)議控制消息 Protocol Control Messages 和用戶控制消息User Control Messages 應(yīng)該包含消息流 ID 0(控制流)和塊流ID 2,并且有最高的發(fā)送優(yōu)先級南缓。
數(shù)據(jù)次之
數(shù)據(jù)消息(視頻信息胸遇、音頻消息)比控制信息的優(yōu)先級低。另外,一般情況下,音頻消息比視頻數(shù)優(yōu)先級高汉形。

2.4RTMP協(xié)議-時間戳

基本介紹

  • RTMP中時間戳的單位為毫秒(ms)
  • 時間戳為相對于某個時間點的相對值
  • 時間戳的長度為32bit

Timestamp: Four-byte field that contains a timestamp of the message.
The 4 bytes are packed in the big endian order.
?RTMP Message的時間戳4個字節(jié)
?大端存儲

Chunk時間戳

Chunk Format


image

用wireshark轉(zhuǎn)包分析發(fā)現(xiàn),rtmp流的chunk視頻流 或(音頻流)除第一個視頻時間戳為絕對時間戳外,后續(xù)的時間戳均為timestamp delta,即當(dāng)前時間戳與上一個時間戳的差值澎羞。
比如幀率為25幀每秒的視頻流,timestamp delta基本上都為40ms涌穆。
通常情況下Chunk的時間戳(包括絕對時間戳和 Timestamp delta)是3個字節(jié)仇箱。
但時間戳值超過0xFFFFFF時,啟用Extended Timestamp(4個字節(jié)來表示時間戳)
通常情況下-----3字節(jié)


image

三字節(jié)的timestamp可能為絕對timestamp或timestamp delta蚌讼。
timestamp delta (3 bytes): For a type 1 or type 2 chunk, the difference between the previous chunk’s timestamp and the current chunk’s timestamp is sent here.

If the delta is greater than or equal to 16777215 (hexadecimal 0xFFFFFF), this field MUST be 16777215, indicating the
presence of the Extended Timestamp field to encode the full 32 bit delta.
Otherwise, this field SHOULD be the actual delta.
timestamp delta的值超過16777215(即16進制的 0xFFFFFF)時,這時候這三個字節(jié)必須置為0xFFFFFF以此來標(biāo)示Extended Timestamp(4字節(jié))將會存在,?由Extended Timestamp來表示時間戳。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岔冀,一起剝皮案震驚了整個濱河市凯旭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌使套,老刑警劉巖罐呼,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異童漩,居然都是意外死亡弄贿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門矫膨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來差凹,“玉大人期奔,你說我怎么就攤上這事∥D颍” “怎么了呐萌?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谊娇。 經(jīng)常有香客問我肺孤,道長,這世上最難降的妖魔是什么济欢? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任赠堵,我火速辦了婚禮,結(jié)果婚禮上法褥,老公的妹妹穿的比我還像新娘茫叭。我一直安慰自己,他們只是感情好半等,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布揍愁。 她就那樣靜靜地躺著,像睡著了一般杀饵。 火紅的嫁衣襯著肌膚如雪莽囤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天切距,我揣著相機與錄音朽缎,去河邊找鬼。 笑死蔚舀,一個胖子當(dāng)著我的面吹牛饵沧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赌躺,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼羡儿!你這毒婦竟也來了礼患?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤掠归,失蹤者是張志新(化名)和其女友劉穎缅叠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虏冻,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡肤粱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了厨相。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片领曼。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸥鹉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庶骄,到底是詐尸還是另有隱情毁渗,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布单刁,位于F島的核電站灸异,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏羔飞。R本人自食惡果不足惜肺樟,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逻淌。 院中可真熱鬧儡嘶,春花似錦、人聲如沸恍风。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朋贬。三九已至凯楔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锦募,已是汗流浹背摆屯。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糠亩,地道東北人虐骑。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像赎线,于是被迫代替她去往敵國和親廷没。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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