PJCHENder 未整理筆記

[Media] 影音傳輸-傳輸方式與通訊協定

2019-06-27

[Media] 影音傳輸-傳輸方式與通訊協定

@(JavaScript)[JavaScript, WebAPIs, WebRTC, media]

以下內容完全為整理自 30天之即時網路影音開發攻略(小白本) by 我是小馬克 @ iThome 的筆記,無原創內容。

影音資料的傳輸

方法一:將檔案直接透過網路丟給對方

imgur

  • 透過 AirDrop 直接把檔案丟到別人的電腦
  • 先上傳到雲端空間,產生連結後給他人下載
  • 缺點:全部下載完才能開始聽或看影片

方法二:以串流的方式傳送給對方

imgur

  • 將資料切成一段一段傳出去,使用者可以一邊下載一邊觀看
  • 不會花費使用者的儲存空間,串流的檔案會儲存在使用者的緩衝記憶體中,播完後即捨棄
  • 傳統的影音檔由表頭和表身組成,通常需要在所有資料都傳輸完成後,才可以根據表頭知道這個影音的編碼為何,解碼完後才可以開始觀看。
  • 串流的影音則需要先透過伺服器轉成「流容器」,流容器的一個檔案中包含多塊的表頭和表身,每次傳輸的資料都同時包含了表頭和表身,因此可以一邊傳送檔案一邊觀看影音。

imgur

方法三:即時影音傳輸(直播、視訊通話)

基本的原理和串流傳輸相同,但同時需要使用「推流傳輸協議」,例如 RTMP(Real Time Messaging Protocol —即時訊息協定),影音錄製這端會一小段一小段的上傳,使用者也是一小段一小段的取得。

imgur

常見的網路傳輸協定(Communications Protocol)

imgur

**通訊協定(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) @ 筆記

imgur

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 使用,封包會像是這樣子:

1
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,也就是由多個輸入裝置(麥克風、攝影機)所組成

imgur

因為 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:這是實際的影音檔,而且也是流容器,因此可以一邊播放一邊下載

imgur

傳輸方式

若 client 想要聽這一段聲音,他會先向 server 發送 .m3u8 的檔案請求,如此 Server 會回傳 .m3u8 的檔案,client 則會遵循 HLS 協定去取得 .m3u8 中所定義的 .ts 檔。

imgur

.m3u8 檔案的內容會像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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、聲音編碼為 AACMP3

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 流容器。

imgur

HTTP 流式傳輸

在 HTTP 流式傳輸的情況下,當 client 發送 HTTP 請求後,server 會先回傳許多的 TCP 小封包,當判斷是最後一包時,就會回傳 HTTP response,裡面包含有 TCP 中最後一段資料。這種做法會在 HTTP 的 response header 中加上,如此 HTTP response 就會變成一段一段:

1
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.26XVPX。目前主要由 Youtube 和 Facebook 使用。

DASH 會產生副檔名為 .mpd 的索引檔,裡面記錄了這段影音一共由哪些小檔案所組成,client 則根據這個檔案來得知要抓取哪些檔案。DASH 可以將原本的影音檔切成多段 .ts.mp4 的流容器,並且支援動態碼率,因此可以根據使用者的狀態提供不同解析度的影音(例如 1080p, 720p)。

imgur

mpd 索引檔

這是一份類似 XML 的檔案,裡面會包含這些資訊:

  • Period:一部影音可以有多個 Period,用來表示不同的場景或曲目,或用來穿插廣告,這中間描述該 Period 的時間。
  • AdaptationSet:用來說明這個媒體流的資訊。
  • ContentComponent:說明此媒體留屬於影片(video)或聲音(audio
  • Representation:用來表示不同的螢幕大小或碼率,DASH 可以根據使用的狀態抓取不同解析度的影音,例如,1080p720p
  • SegmentBase:實際的檔案

.mpd 的內容會像這樣

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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>

參考資源

掃描二維條碼,分享此文章