2019年7月2日

[筆記] WebRTC 網路影音-通訊協定篇(protocol of media, video and audio)

Photo by freestocks.org on Unsplash
以下內容完全為整理自 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) 不支援,需使用套件。 不支援,需使用套件。 不支援,需使用套件。

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 使用,封包會像是這樣子:
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 請求去下載。

協定內容

在 HLS 協定中,會將影音轉成兩種檔案:
  • .m3u8:這是一個索引檔,裡面記錄了一段影音,被分割成哪些檔案存放
  • .ts:這是實際的影音檔,而且也是流容器,因此可以一邊播放一邊下載
imgur

傳輸方式

若 client 想要聽這一段聲音,他會先向 server 發送 .m3u8 的檔案請求,如此 Server 會回傳 .m3u8 的檔案,client 則會遵循 HLS 協定去取得 .m3u8 中所定義的 .ts 檔。
imgur
.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 流容器。
imgur

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)。
imgur

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>

參考資源

0 意見:

張貼留言