傳輸協(xié)議
RTMP
該協(xié)議是應(yīng)用層協(xié)議,用來解決多媒體數(shù)據(jù)傳輸流的多路復用(Multiplexing)和分包(packetizing)的問題。
三種分支類型:
- RTMP: 工作在TCP協(xié)議(傳輸層協(xié)議)上的明文傳輸巨税,它使用的端口是1935;
- RTMPT:用HTTP包裝后的協(xié)議渺鹦,可以穿越防火墻進行傳輸舀透;
- RTMPS:用HTTP包裝后的協(xié)議,不過與RTMPT不同的是密任,它使用HTTPS安全連接颜启,可以保證傳輸?shù)陌踩?/li>
概念定義
- 載荷(Payload):包含在包中的數(shù)據(jù)
- 包(Packet):數(shù)據(jù)包由固定頭和載荷數(shù)據(jù)組成,一些底層協(xié)議可能需要對被定義包進行封裝
- 端口(Port):TCP/IP端口浪讳,由主機號來區(qū)分多地址
- 傳輸?shù)刂?Transport address):網(wǎng)絡(luò)地址和端口的組合
- 消息流(Message stream):消息流通信的邏輯頻道
- 消息流ID(Message stream ID):每個消息都有一個預(yù)期消息流匹配的id
- 塊(Chunk):消息片段缰盏。消息在被網(wǎng)絡(luò)傳輸前會被分成小的部分,所有的消息會通過多路由時間序端對端傳輸
- 塊流(Chunk stream):通信的邏輯頻道允許塊以某一特定方向傳送淹遵,塊流可以從客戶端傳到服務(wù)端口猜,也可以從服務(wù)端傳回客戶端
- 塊流ID(Chunk stream ID):每個塊流都有一個與之匹配的id
- 多路復用(Multiplexing):分離的音視頻數(shù)據(jù)可以連續(xù)播放的過程,使得音視頻可以同時傳送
- 多路分用(DeMultiplexing):多路復用的逆過程合呐,可以將交錯的音視頻數(shù)據(jù)聚集成原始的音視頻數(shù)據(jù)
- 遠程過程調(diào)用(Remote Procedure Call):允許客戶端或服務(wù)端可以調(diào)用另一端服務(wù)端或客戶端子程序或子進程的請求
- 元數(shù)據(jù)(Metadata):數(shù)據(jù)的描述暮的。電影的元數(shù)據(jù)包括電影標題,時長淌实,上映日期等等冻辩。
- 應(yīng)用實例(Application Instance):客戶端可以連接并發(fā)送連接請求的服務(wù)端實例
- 動作消息格式(Action Message Format):用來序列化AS(ActionScript 動作腳本)實例對象(object graphs)的壓縮的二進制格式,有AMF0和AMF3兩種版本
握手流程
- 流程圖
+---------------+ +---------------+
| Client | TCP/IP Network | Server |
+---------------+ | +---------------+
| | |
Uninitialized | Uninitialized
| C0 | |
| -------------------> | C0 |
| | -------------------> |
| C1 | |
| -------------------> | S0 |
| | <------------------- |
| | S1 |
Version sent | <------------------- |
| S0 | |
| <------------------- | |
| S1 | |
| <------------------- | Version sent
| | C1 |
| | -------------------> |
| C2 | |
| -------------------> | S2 |
| | <------------------- |
Ack sent | Ack sent
| S2 | |
| <------------------- | |
| | C2 |
| | -------------------> |
Handshake Done | Handshake Done
| | |
- 未初始化階段(Uninitialized):協(xié)議版本在這個階段發(fā)送拆祈,客戶端和服務(wù)端都是未初始化的恨闪。客戶端在C0包中發(fā)送協(xié)議版本放坏,如果服務(wù)端支持這個協(xié)議版本咙咽,其將會對應(yīng)發(fā)送S0和S1;如果服務(wù)端不支持淤年,服務(wù)端會采取合適的動作钧敞。在RTMP中,這個動作是中止連接麸粮。
- 版本發(fā)送階段(Version Sent):在未初始化階段之后客戶端和服務(wù)端都處于版本發(fā)送階段溉苛。客戶端處于等待S1包弄诲,服務(wù)端處于等待C1包愚战。在收到相應(yīng)的等待的包后,客戶端發(fā)送C2而服務(wù)端會發(fā)送S2,然后進入確認發(fā)送階段寂玲。
- 確認發(fā)送階段(Ack Sent):客戶端和服務(wù)端響應(yīng)的等待S2和C2
- 握手結(jié)束階段(Handshake Done):客戶端和服務(wù)端交換消息
-
握手消息的意義
- C0 & S0 : 8位整數(shù)段的RTMP版本號塔插。
- C1 & S1 :時間戳+任意數(shù)據(jù)(長度固定),ack拓哟?想许??
- C2 & S2 :時間戳+任意數(shù)據(jù)(長度固定)彰檬,用來檢測網(wǎng)絡(luò)延遲
-
消息流(Message stream)
握手完成后伸刃,即可以傳輸相關(guān)的數(shù)據(jù)- 類型
- Command Message(命令消息,Message Type ID=17或20):表示在客戶端盒服務(wù)器間傳遞的在對端執(zhí)行某些操作的命令消息逢倍,如connect表示連接對端,對端如果同意連接的話會記錄發(fā)送端信息并返回連接成功消息景图,publish表示開始向?qū)Ψ酵屏鹘系瘢邮芏私拥矫詈鬁蕚浜媒邮軐Χ税l(fā)送的流信息,后面會對比較常見的Command Message具體介紹挚币。當信息使用AMF0編碼時亮蒋,Message Type ID=20,AMF3編碼時Message Type ID=17.
- Data Message(數(shù)據(jù)消息妆毕,Message Type ID=15或18):傳遞一些元數(shù)據(jù)(MetaData慎玖,比如視頻名,分辨率等等)或者用戶自定義的一些消息笛粘。當信息使用AMF0編碼時趁怔,Message Type ID=18,AMF3編碼時Message Type ID=15.
- Shared Object Message(共享消息薪前,Message Type ID=16或19):表示一個Flash類型的對象润努,由鍵值對的集合組成,用于多客戶端示括,多實例時使用铺浇。當信息使用AMF0編碼時,Message Type ID=19垛膝,AMF3編碼時Message Type ID=16.
- Audio Message(音頻信息鳍侣,Message Type ID=8):音頻數(shù)據(jù)。
- Video Message(視頻信息吼拥,Message Type ID=9):視頻數(shù)據(jù)倚聚。
- Aggregate Message (聚集信息,Message Type ID=22):多個RTMP子消息的集合
- User Control Message Events(用戶控制消息扔罪,Message Type ID=4):告知對方執(zhí)行該信息中包含的用戶控制事件秉沼,比如Stream Begin事件告知對方流信息開始傳輸。和前面提到的協(xié)議控制信息(Protocol Control Message)不同,這是在RTMP協(xié)議層的唬复,而不是在RTMP chunk流協(xié)議層的矗积,這個很容易弄混。該信息在chunk流中發(fā)送時敞咧,Message Stream ID=0,Chunk Stream Id=2,Message Type Id=4棘捣。
- 類型
塊流(Chunk stream)
RTMP在收發(fā)數(shù)據(jù)的時候并不是以Message為單位的,而是把Message拆分成Chunk發(fā)送休建,而且必須在一個Chunk發(fā)送完成之后才能開始發(fā)送下一個Chunk乍恐。每個Chunk中帶有MessageID代表屬于哪個Message,接受端也會按照這個id來將chunk組裝成Message测砂。
通過拆分茵烈,數(shù)據(jù)量較大的Message可以被拆分成較小的“Message”,這樣就可以避免優(yōu)先級低的消息持續(xù)發(fā)送阻塞優(yōu)先級高的數(shù)據(jù)砌些,比如在視頻的傳輸過程中呜投,會包括視頻幀,音頻幀和RTMP控制信息存璃,如果持續(xù)發(fā)送音頻數(shù)據(jù)或者控制數(shù)據(jù)的話可能就會造成視頻幀的阻塞仑荐,然后就會造成看視頻時最煩人的卡頓現(xiàn)象。同時對于數(shù)據(jù)量較小的Message纵东,可以通過對Chunk Header的字段來壓縮信息粘招,從而減少信息的傳輸量。
DASH(Dynamic Adaptive Streaming over HTTP)
簡單概括來說偎球,就是在服務(wù)器端提前存好同一內(nèi)容的不同碼率洒扎、不同分辨率的多個分片以及相應(yīng)的描述文件MPD,客戶端在播放時即可以根據(jù)自身性能以及網(wǎng)絡(luò)環(huán)境選擇最適宜的版本甜橱。更多詳細的內(nèi)容可以參見MPEG組織出臺的標準逊笆,標準號ISO/IEC 23009-1。
-
MPD 字段意義
Period:一條完整的mpeg dash碼流可能由一個或多個Peroid組成岂傲,每個Period代表一個時間段难裆。比如一個碼流是60s,Peroid1是0-10s镊掖,Peroid2是11-30乃戈,Peroid3是31-60。
AdaptationSet:包含了媒體呈現(xiàn)的形式(視頻/音頻/字幕)亩进,AdaptationSet由一組可供切換的不同碼率的碼流(Representation)組成症虑。
Representation:表示不同碼率的碼流,實際播放的時候归薛,視頻會在一個AdaptationSet中的不同Representaiton 之間切換碼率谍憔,會依次請求該Representaiton下不同Segment序列匪蝙。
Segment:每一個具體的片段。(1,2,4,6,10s …) 习贫。MPD中描述segment URL的形式有多種逛球,如Segment list,Segment template苫昌,Single segment颤绕。
HLS(HTTP Live Streaming)
HTTP Live Streaming(簡稱 HLS)是一個基于 HTTP 的視頻流協(xié)議,由 Apple 公司實現(xiàn)祟身,Mac OS 上的 QuickTime奥务、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS,高版本 Android 也增加了對 HLS 的支持袜硫。一些常見的客戶端如:MPlayerX氯葬、VLC 也都支持 HLS 協(xié)議。
HLS 協(xié)議基于 HTTP婉陷,非常簡單溢谤。一個提供 HLS 的服務(wù)器需要做兩件事:
- 編碼:以 H.263 格式對圖像進行編碼,以 MP3 或者 HE-AAC 對聲音進行編碼憨攒,最終打包到 MPEG-2 TS(Transport Stream)容器之中;
- 分割:把編碼好的 TS 文件等長切分成后綴為 ts 的小文件阀参,并生成一個 .m3u8 的純文本索引文件肝集;
瀏覽器使用的是 m3u8 文件。m3u8 跟音頻列表格式 m3u 很像蛛壳,可以簡單的認為 m3u8 就是包含多個 ts 文件的播放列表杏瞻。播放器按順序逐個播放,全部放完再請求一下 m3u8 文件衙荐,獲得包含最新 ts 文件的播放列表繼續(xù)播捞挥,周而復始。整個直播過程就是依靠一個不斷更新的 m3u8 和一堆小的 ts 文件組成忧吟,m3u8 必須動態(tài)更新砌函,ts 可以走 CDN。
可以看到 HLS 協(xié)議本質(zhì)還是一個個的 HTTP 請求 / 響應(yīng)溜族,所以適應(yīng)性很好讹俊,不會受到防火墻影響。但它也有一個致命的弱點:延遲現(xiàn)象非常明顯煌抒。如果每個 ts 按照 5 秒來切分仍劈,一個 m3u8 放 6 個 ts 索引,那么至少就會帶來 30 秒的延遲寡壮。如果減少每個 ts 的長度贩疙,減少 m3u8 中的索引數(shù)讹弯,延時確實會減少,但會帶來更頻繁的緩沖这溅,對服務(wù)端的請求壓力也會成倍增加组民。所以只能根據(jù)實際情況找到一個折中的點。
RTSP
rtsp的能量在UDP傳輸這塊芍躏,實際上公網(wǎng)環(huán)境下大量的UDP包邪乍,容易被防火墻block住,相對靠譜的模式对竣,是rtsp over http tunnel庇楞,如果需要web端播放rtsp流的話,需要寫插件否纬,而且對瀏覽器也很挑剔吕晌。
rtmp興起的原因是flash。以前網(wǎng)頁要想直播只能flash而不是html5临燃。比如國內(nèi)網(wǎng)頁直播始祖douyutv前身acfun生放送睛驳,那時候要想網(wǎng)頁直播只能flash,所以rtmp是最好選擇膜廊。但乏沸,rtsp其實比rtmp更復雜,rtsp需要兩個連接爪瓜,一個信令一個rtp數(shù)據(jù)蹬跃,更多操心的地方,代碼量其實更大铆铆。rtmp看似復雜蝶缀,其實在流媒體直播里面更科學,比如分chunk薄货,可以讓音頻包不會被大包視頻發(fā)送所阻塞翁都,但是大部分代碼都是一個視頻包一次發(fā)完,所以這個功能沒用上谅猾。雖然rtmp有一些冗余設(shè)計柄慰,但是總規(guī)來說rtmp是目前直播協(xié)議的最廣泛選擇。rtsp的udp不適合外網(wǎng)傳輸赊瞬,所以在外網(wǎng)下先煎,不存在理論的rtsp比rtmp更快。rtmp如何更低延遲巧涧?推送端編碼低延遲:h264編碼是需要設(shè)置為低延遲編碼的薯蝎,如若默認,h264從編碼到解碼本來的延遲就非常非常大谤绳。比如x264占锯,ultrafast zerolatency這些都是實時音視頻會議用的袒哥。服務(wù)器低延遲:等待gop,如果一個服務(wù)器在一個新連接上來后,不發(fā)送緩存gop而是直接等待消略,等待下一個gop開始堡称,這樣就能到達超低延遲∫昭荩客戶端處理:客戶端也需要優(yōu)化低延遲播放却紧。未來可能有協(xié)議替代rtmp,但還需要時間胎撤,畢竟obs只支持rtmp晓殊。可能未來出現(xiàn)的是udp之上的可靠協(xié)議伤提,比如現(xiàn)在已經(jīng)出現(xiàn)的srt巫俺。
RTP and RTCP
RTP協(xié)議是一種基于UDP的傳輸協(xié)議,RTP本身并不能為按順序傳送數(shù)據(jù)包提供可靠的傳送機制肿男,也不提供流量控制或擁塞控制介汹,它依靠RTCP提供這些服務(wù)。
這樣舶沛,對于那些丟失的數(shù)據(jù)包嘹承,不存在由于超時檢測而帶來的延時,同時如庭,對于那些丟棄的包赶撰,也可以由上層根據(jù)其重要性來選擇性的重傳。比如柱彻,對于I幀、P幀餐胀、B幀數(shù)據(jù)哟楷,由于其重要性依次降低,故在網(wǎng)絡(luò)狀況不好的情況下否灾,可以考慮在B幀丟失甚至P幀丟失的情況下不進行重傳卖擅,這樣,在客戶端方面墨技,雖然可能會有短暫的不清晰畫面惩阶,但卻保證了實時性的體驗和要求。
RTP通常使用UDP協(xié)議來實現(xiàn)多媒體的傳輸
-實時傳輸協(xié)議RTP/RTCP
WebRTC
refrence
自適應(yīng)流媒體傳輸(一)——DASH媒體內(nèi)容的生成
我們?yōu)槭裁词褂肈ASH
為什么現(xiàn)在的視頻直播不使用RTSP協(xié)議而是使用RTMP?
前端應(yīng)該了解的RTMP知識
帶你吃透RTMP
為何一直推薦WebRTC扣汪?