Photo by freestocks.org on Unsplash |
以下內容完全為整理自 30天之即時網路影音開發攻略(小白本) by 我是小馬克 @ iThome 的筆記,無原創內容。
影音資料的傳輸
方法一:將檔案直接透過網路丟給對方
- 透過 AirDrop 直接把檔案丟到別人的電腦
- 先上傳到雲端空間,產生連結後給他人下載
- 缺點:全部下載完才能開始聽或看影片
方法二:以串流的方式傳送給對方
- 將資料切成一段一段傳出去,使用者可以一邊下載一邊觀看
- 不會花費使用者的儲存空間,串流的檔案會儲存在使用者的緩衝記憶體中,播完後即捨棄
- 傳統的影音檔由表頭和表身組成,通常需要在所有資料都傳輸完成後,才可以根據表頭知道這個影音的編碼為何,解碼完後才可以開始觀看。
- 串流的影音則需要先透過伺服器轉成「流容器」,流容器的一個檔案中包含多塊的表頭和表身,每次傳輸的資料都同時包含了表頭和表身,因此可以一邊傳送檔案一邊觀看影音。
方法三:即時影音傳輸(直播、視訊通話)
基本的原理和串流傳輸相同,但同時需要使用「推流傳輸協議」,例如 RTMP(Real Time Messaging Protocol —即時訊息協定),影音錄製這端會一小段一小段的上傳,使用者也是一小段一小段的取得。
常見的網路傳輸協定(Communications Protocol)
**通訊協定(Communications Protocol)**簡單來說就是溝通的雙方約好要「如何進行溝通」的規定。
特點整理
協議 | 傳輸層選擇 | 聲音編碼 | 影像編碼 | 延遲性 |
---|---|---|---|---|
RTSP | RTP、TCP、UDP | RTP 可支援的都行 | RTP 可支援的東行 | 低 |
RTMP | TCP | AAC、MP3 | H.26X 系列 | 低 |
HLS | TCP (因為它是用 HTTP ) | AAC、MP3 | H.26X 系列 | 高 |
HTTP-FLV | TCP (因為它是用 HTTP ) | AAC、MP3 | H.26X 系列 | 低 |
MEPG-DASH | TCP (因為它是用 HTTP ) | 沒啥限制,不過 AAC 用比較多 | H.26X、VPX 系列 | 高 |
支援度
協議 | 支援度 web html5 | 支援度 ios | 支援度 mac | 支援度 android |
---|---|---|---|---|
RTSP | 不支援,需使用套件。 | 不支援,需使用套件。 | 不支援,需使用套件。 | 不支援,需使用套件。 |
RTMP | html5 不支援,需使用套件。 | 不支援,需使用套件。 | 不支援,需使用套件。 | 不支援,需使用套件。 |
HLS | 支援 | 支援 | 支援 | 支援 |
HTTP-FLV | 支援 (flv.js) | 不支援,需使用套件。 | 不支援,需使用套件。 | 不支援,需使用套件。 |
MPEG-DASH | 支援 (dash.js) | 不支援,需使用套件。 | 不支援,需使用套件。 | 不支援,需使用套件。 |
30-18 之影音傳輸協議總整理 by 我是小馬克 @ iThome
TCP/IP 通訊協定
TCP/IP 是一組協定套組,主要是為了讓電腦可以在網路上進行端點和端點間的溝通,TCP/IP 總共可以分成四個層級,每個層級又有各自的協定來完成某些事情。更詳細的說明可以參考 [[網際網路] TCP/IP 階層模型基礎](/Users/pjchen/Projects/Notes/source/_posts/Internet-MIS-IS/[Internet] TCP_IP 階層模型基礎.md) @ 筆記
TCP/UDP 協定:一般檔案傳輸
屬於傳輸層的協定,更詳細的說明可以參考 [[網際網路] TCP/IP 階層模型基礎](/Users/pjchen/Projects/Notes/source/_posts/Internet-MIS-IS/[Internet] TCP_IP 階層模型基礎.md) @ 筆記
RTP/RTCP 協定:傳輸串流媒體
因為在 UDP 協定中只定義了來源端和目的端的 port,但是並沒有定義需要使用的解碼方式,因此出現了即時傳輸協定(RTP, Real-time Transport Protocol)。
RTP 和 TCP/UDP 協定一樣屬於傳輸層,其重點在於端點到端點間的串流媒體傳輸,定義了傳輸串流媒體的封包標準(參數標準),它本身就可以算是一種流容器,但只適用於無損編碼,目前廣泛用於網路電視和網路會議。
RTP 通常是搭配 TCP/UDP 使用,封包會像是這樣子:
RTP 表頭 + UDP/TCP 表頭 + 表身(就是資料)
詳細的封包組成在這 30-12之 RTP/RTCP 傳輸協議 @ iThome by 我是小馬克
因此會有(目前 RTP 多是搭配 UDP 使用):
- RTP over UDP:效率較好但品質較差
- RTP over TCP:效率較差但品質較好
其中在 RTP 的標頭中會包含:
bit | field | describe |
---|---|---|
2 | V (Version) | 用來說明使用的 RTP 版本 (default 為 2)。 |
1 | P (Padding) | 為 1 的話,就會在最後面的 payload 後面加填充位置。 |
1 | X (Extension) | 為 1 的話,就代表存在 header 的擴展。 |
4 | CC (CSRC count) | 用來記錄 CSRC 的數量。(csrc 後面會說)。 |
1 | M (Marker) | 配置文件定義。 |
7 | PT (payload type) | 就是說明你要傳輸的語音視頻的編碼是啥 (ex. H.264, PCM)。 |
16 | Sequence Number | 每發送一個封包就 + 1 ,接受端可以用它來判斷封包順序。 |
32 | Timestamp | 時間戳,用來記錄採樣第一個 bit 資料(音視頻)的時間。 |
32 | SSRC (Synchronization source) | 記錄封包的發送方,它只是隨機的從 md5 隨機演算法中選取,然後在同一個視頻會議中,不會有相同的 ssrc 值。 |
(0~15) X 32 | CSRC (Contributing source) | 記錄這所有參於方的來源之 ssrc。 |
- 同步來源(SSRC, Synchronization source):也就是建立媒體的來源,即使同一個 IP 位址但不同的輸入裝置(例如麥克風),仍然會有不同的 SSRC 值
- CSRC (Contributing source):存放了組成這個 RTP 流的所有 SSRC,也就是由多個輸入裝置(麥克風、攝影機)所組成
因為 RTP 本身並不保證串流中間有沒有封包遺失,而只是負責傳送,因此為了確保 RTP 的**服務品質(Qos, Quality of Service)**而有了 RTCP (RTP Control Protocol)。
其中的標頭如下:
bit | field | describe |
---|---|---|
2 | Version | RTP 的版本號,預設為 2 。 |
3 | P (padding) | 在最後的位置增加空間,大部份都是給加密使用的地方。 |
8 | RC | 接受方報告的數量。 |
16 | Packet Type | 用來判斷這個封包是那一種 RTCP 類型。 |
Packet Type 又可以分為:
code | type | describe |
---|---|---|
200 | SR(Sender Report) | 發送方的報告 |
201 | RR(Receiver Report) | 接受方的報告 |
202 | SDES(Source Description Items) | 來源端 |
203 | BYE | 結束 |
204 | APP(Application) | 特定應用 |
在 RTCP 協議中:
- 「接收方」每收到一個 RTP 封包時就會產生 RR 報告(包含 SSRC 和流失率)
- 「發送方」每傳出一個 RTP 封包時則會發出 SR 讓接收方知道發送方的資訊。
- 標頭中的 SDES(Source Description Items) 則會給出會議參與者的描述,包含參與者的規範名稱(CNAME, Canonical NAME),也就是機器的別名,與會者只需要使用別名就可以找到發送者。
RTSP 協定:操作串流媒體
**即時串流協定(RTSP, Real Time Streaming Protocol)是設計來讓客戶端(Client)與伺服器端(Server)針對串流媒體進行溝通,以此控制串流媒體伺服器的協定,像是快轉或暫停影片,在 RTSP 中定義了控制串流媒體的方法和參數,當伺服器接收到這些動作後,就會以此傳輸影片給使用者。目前很多東西仍不支援這種協定,它多用在隨選視訊(VOD, video on demand)**和視訊會議。
RTSP 用於伺服器和客戶端間的溝通實例可以回到原本的文章 30-13之 RTSP 傳輸協議 觀看。
RTSP 只處理串流的控制,並不會去管用什麼方式傳輸,但一般來說會使用 RTP over UDP 或 UDP 來傳輸。
RTMP 協定:Adobe 專為 flash 設計
**即時訊息協定(RTMP, Real-Time Messaging Protocol)**是 Adobe 所開發,設計來讓 Flash 與媒體串流伺服器進行溝通。
HLS 協定:透過 HTTP 傳輸串流媒體
HLS (HTTP Live Streaming) 由蘋果公司提出,在此之前大部分的媒體串流傳輸都是由 Adobe 的 RTMP 所掌控,其最重要的功能是讓 client 和 server 可以透過 HTTP 進行媒體串流的傳輸,在這個協定中會將媒體切成許多的小檔案,client 則透過一個一個發 http 請求去下載。
HTTP Live Streaming Overview @ Apple Developer
協定內容
在 HLS 協定中,會將影音轉成兩種檔案:
- .m3u8:這是一個索引檔,裡面記錄了一段影音,被分割成哪些檔案存放
- .ts:這是實際的影音檔,而且也是流容器,因此可以一邊播放一邊下載
傳輸方式
若 client 想要聽這一段聲音,他會先向 server 發送 .m3u8 的檔案請求,如此 Server 會回傳 .m3u8 的檔案,client 則會遵循 HLS 協定去取得 .m3u8 中所定義的 .ts 檔。
.m3u8 檔案的內容會像這樣:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:5
#ID3-EQUIV-TDTG:2016-11-26T02:40:23
#EXT-X-MEDIA-SEQUENCE:376
#EXT-X-TWITCH-ELAPSED-SYSTEM-SECS:1511.137
#EXT-X-TWITCH-ELAPSED-SECS:1508.980
#EXT-X-TWITCH-TOTAL-SECS:1535.137
#EXTINF:4.000,
index-0000000377-6zCW.ts
#EXTINF:4.000,
index-0000000378-vHZS.ts
#EXTINF:4.000,
index-0000000379-Gkgv.ts
#EXTINF:4.000,
index-0000000380-PNoG.ts
#EXTINF:4.000,
index-0000000381-h58g.ts
#EXTINF:4.000,
index-0000000382-W88t.ts
其中比較重要的是 EXTINF 的部分,這裡表示總共有 6 支 .ts 檔,每個 .ts 檔有 4 秒,因此這部影音一共有 24 秒。
HLS 的缺點:延遲問題
HLS 有比較嚴重的延遲問題,如果是點播已存在的影音檔案沒有太大的問題,但若是即時通訊與直播的話,直撥主講話後可能要 10 秒後聽眾才聽得到,但相對的畫面不會卡頓。
調整片段的數量與長度
每個 .ts 檔的長度是可以調整的,如果把每個片段都切成很小的長度,如此延遲的時間會少非常多,但伺服器的負擔卻會加重,非常不建議使用。因此要做直播或很在意延遲的話,應直接放棄 HLS。
支援的編碼格式:H.264, AAC, MP3
HLS 支援影像編碼為 H.264、聲音編碼為 AAC 和 MP3。
HTTP-FLV 協定:減少 HLS 延遲的情況
由於 HLS 有比較嚴重的延遲問題,HTTP-FLV 則試著用 HTTP 完成低延遲的媒體串流傳輸,它在 HTML5 的支援度佳,且延遲性較 HLS 優,是目前直播主流用的通訊協定。透過 HTTP-FLV 協定,直播主這端會用任何形式(例如 RMTP)將影音傳送到 server,server 會將此影音轉成 FLV 容器,而 client 則透過 HTTP 來請求這個影音,server 則使用「HTTP 流式傳輸」的方式將影音一段一段丟給 client。
目前支援的影像編碼包含 H.264、聲音編碼包含 AAC, MP3,使用的則是 .flv 流容器。
HTTP 流式傳輸
在 HTTP 流式傳輸的情況下,當 client 發送 HTTP 請求後,server 會先回傳許多的 TCP 小封包,當判斷是最後一包時,就會回傳 HTTP response,裡面包含有 TCP 中最後一段資料。這種做法會在 HTTP 的 response header 中加上,如此 HTTP response 就會變成一段一段:
Transfer-Encoding: chunked
Node.js 的 http 本身如果不執行 res.end() 這一段,它就會自動的幫你在 response header 中加 chunked。
MPEG-DASH 協定:HLS 的替代版
keywords: .mpd, .ts, .mp4
由於 HLS 是由蘋果所主導,並不算國際通用協定,一切必須聽從蘋果的指示,因此在許多大廠的合作下即產生了「動態自適應流(DASH, Dynamic Adaptive Streaming over HTTP)」。它的作法和概念與 HLS 幾乎一樣,都是將影音切成許多小檔後,請 client 發 http 一個一個下載,它支持任何的編碼格式,例如, H.26X 或 VPX。目前主要由 Youtube 和 Facebook 使用。
DASH 會產生副檔名為 .mpd 的索引檔,裡面記錄了這段影音一共由哪些小檔案所組成,client 則根據這個檔案來得知要抓取哪些檔案。DASH 可以將原本的影音檔切成多段 .ts 或 .mp4 的流容器,並且支援動態碼率,因此可以根據使用者的狀態提供不同解析度的影音(例如 1080p, 720p)。
mpd 索引檔
這是一份類似 XML 的檔案,裡面會包含這些資訊:
- Period:一部影音可以有多個 Period,用來表示不同的場景或曲目,或用來穿插廣告,這中間描述該 Period 的時間。
- AdaptationSet:用來說明這個媒體流的資訊。
- ContentComponent:說明此媒體留屬於影片(video)或聲音(audio)
- Representation:用來表示不同的螢幕大小或碼率,DASH 可以根據使用的狀態抓取不同解析度的影音,例如,1080p 或 720p
- SegmentBase:實際的檔案
.mpd 的內容會像這樣
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" mediaPresentationDuration="PT0H3M1.63S" minBufferTime="PT1.5S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static"> <Period duration="PT0H3M1.63S" start="PT0S"> <AdaptationSet> <ContentComponent contentType="video" id="1" /> <Representation bandwidth="4190760" codecs="avc1.640028" height="1080" id="1" mimeType="video/mp4" width="1920"> <BaseURL>car-20120827-89.mp4</BaseURL> <SegmentBase indexRange="674-1149"> <Initialization range="0-673" /> </SegmentBase> </Representation> </AdaptationSet> <AdaptationSet> <ContentComponent contentType="audio" id="2" /> <Representation bandwidth="127236" codecs="mp4a.40.2" id="6" mimeType="audio/mp4" numChannels="2" sampleRate="44100"> <BaseURL>car-20120827-8c.mp4</BaseURL> <SegmentBase indexRange="592-851"> <Initialization range="0-591" /> </SegmentBase> </Representation> </AdaptationSet> </Period> </MPD>
參考資源
- 30 天之即時網路影音開發攻略(小白本) by 我是小馬克 @ iThome
- 30-10之通訊協議的基本常識:說明 TCP/IP 通訊協定
- 30-11之 TCP 與 UDP 協議:說明 UDP 和 TCP 中的建立連線(三次交握)和斷線(四次揮手)
- 30-12之 RTP/RTCP 傳輸協議:說明為什麼需要 RTP/RTCP 即其封包內容
- 30-13之 RTSP 傳輸協議:透過 RTSP 傳輸協議來控制串流媒體的動作。
- 30-14之 RTMP 傳輸協議:RTMP 為 Adobe 設計來透過 flash 與伺服器進行溝通的方式。
- 30-15之 HLS 傳輸協議:HLS 協議會使用 .m3u8 的索引和 .ts 的檔案傳輸,適合影音串流播放,但延遲性高,不適合用於直播。
- 30-16之 HTTP-FLV 傳輸協議:透過 HTTP-FLV 傳輸協定來減少 HLS 在傳輸時的延遲問題,適合用於影音串流直播。
- 30-17之 MPEG-DASH 傳輸協議:算是 HLS 的國際標準版,但仍沒有 HLS 這麼普及。
- 30-18 之影音傳輸協議總整理
0 意見:
張貼留言