我是山姆鍋

隨著網際網路媒體串流的流行以及同時觀眾數量不斷增加,要架構出一個支援實況 (live) 媒體串流 (streaming) 的解決方案, 是一件越來越困難的技術挑戰。本文描述一個基於點對點 (peer-to-peer) 的方式進行媒體串流的行動網路架構,以減輕對媒體源 (media origin) 的負擔並減少頻寬的成本。

點對點串流基本概念

一般的串流方式是由客戶端連到快取 (cache) 伺服器,再由快取伺服器連到媒體源伺服器 (origin)。 採用這種架構的好處是可以隨著客戶端數量擴展,但有幾個問題:

  1. 為了支援增加的客戶端,需要增加相對的伺服器。
  2. 頻寬的耗用與客戶端數量成正比成長。

不管是增加伺服器或者頻寬,對提供串流服務都是增加的成本,這還不包括系統管理上隱形成本。
因此,有人提出以客戶端來做為快取伺服器的構想。假設一群客戶端已經在觀看相同的即時視頻,
為什麼不讓這些客戶端彼此分享媒體資料?這就是點對點串流的基本構想。

在觀看同一個媒體源的客戶端形成一個集群 (swarm),屬於同一個集群的客戶端採用對等網路方式架構, 各個客戶端,也可稱作對等點 (peer),同時會從其他客戶端下載媒體資料,也會上載資料給其它客戶端。 通常為了有效地將媒體資料在集群內傳播,集群內的對等點會自組成一個多點傳播樹 (multicast tree)。 每個對等點會有一個上層父節點用來接收媒體資料,並接受不定個數的子節點來轉發資料。

集中式的串流架構

Image credits: Mauro Bieg on Wikipedia

點對點串流類型

同樣採用點對點串流技術,但根據媒體源的不同,可以再分成:

  1. 混合式 (Hybrid) 點對點串流:

    這種架構下,媒體源是由一個伺服器組成的 CDN
    來提供,媒體資料在同一個集群中彼此分享。
    也就是同時用到傳統的的架構與點對點架構的方式。

  2. 完全點對點串流:

    這種架構下,媒體源本身就來自整個網路的客戶端 (應該說是對等點,為了方便兩者會交互使用)。 整個串流網路,每個媒體源形成一個集群。所以,也可以把網路想成由多個集群組成。

本文主要描述的是完全點對點串流架構。

完全點對點串流架構

在完全點對點串流架構,任一個客戶端 (或稱為一個「對等點 (peer)」) 都可能是媒體源節點 (origin node), 全部的對等點共同參與一個結構化覆蓋網路 (Structured overlay
network), 並維護一個分散式雜湊表 (Distributed Hashtable; DHT)。由這個 DHT, 節點可以簡單的鍵值 (key-value) 組織資源的中介資料 (metadata), 這些中介資料中對串流最重要的就是在觀看同樣媒體源的對等點資訊。 觀看同一個媒體源的對等點組成一個集群 (swarm),這個媒體源的資料會在此集群內互相分享以減低媒體源節點的負擔。

基本上,整個點對點架構與 BitTorrent DHT 如出一徹,差別只在於本文所講的架構是應用在點對點實況串流,對於資料的即時性要求很高。

覆蓋網路 (Overlay Network)

此系統的對等點參與一個結構化覆蓋網路 (structured overlay network),形成一個環狀 (ring) 的拓樸 (topology)。 所有對等點共同維護一個分散式雜湊表 (Distributed Hashtable; DHT), 除了網路存取被限制的對等點外,每個對等點都可以提供 DHT 查詢與修改功能。

跟非結構化的覆蓋網路相比,維護一個結構化網路的額外負擔通常比較高。採用 DHT 結構化覆蓋網路的主要理由是:這是目前已經經過驗證可以用在大型系統的設計,且有多個實作可以選擇。

集群 (Swarm)

針對點對點串流架構,同時在下載同一個媒體源的對等點被定義為一個「集群 (swarm)」,其中包括媒體源節點。 整個架構的主要目的就是要減輕媒體源節點的負擔,因此,集群中的對等點會分享彼此所擁有的媒體資料片段。 這樣的做法,可以傳播資料到集群中的各個對等點。但如果單純以廣播方式傳遞資料到所有對等點, 雖然可以達到傳播的目的,卻也造成過多重複的資料被傳遞而浪費頻寬。因為如此,集群內的對等點會自組成 (self-organized) 一個多播樹 (multicast tree)。在這個樹狀結構中,源節點是樹根 (root),其它節點可以有一個父節點以及有限個數的子節點。

由於是串流應用,整個集群只能有一個媒體源節點。

集群內的對等點分享同一媒體源資料。

Image credits: Mauro Bieg on Wikipedia

對等點 (Peer)

「對等點」指參與同一個集群的節點,理論上,一個節點可以參與多個集群,但在實況串流應用,
本文假設一個節點最多只有一個對等點。本文會使用節點或對等點,基本上可以視為相同。

對等點的最重要工作就是參與集群,並與其它對等點組成多播樹,共同分攤媒體資料傳播的工作。

分散式雜湊表 (DHT)

在整個架構中,DHT 扮演註冊表 (registry) 的角色,用來登記以及查詢屬於同一個集群的對等點的位址資訊。 這樣簡單的資料要求對於系統的安全性有直接的貢獻。

每個節點加入網路後,會試圖將自己加入 DHT 中,但如果其它節點無法與它溝通,便會被排除在外。所以, 不是所有節點都可以回覆資料查詢的要求,但所以節點都可以查詢 DHT 來找到其它對等點的位址。

對等點透過 DHT 找到一些同一個集群的對等點後,便可以直接與這些對等點溝通來進一步取的串流媒體的中介資料。

客戶端架構

客戶端可以大略分成兩個元件 (components):

  1. 客戶端核心: 作為主要核心 (core) 負責與其它客戶端的溝通與媒體串流工作;
  2. 客戶端前端: 作為前端負責使用者介面 (UI) 以及媒體裝置存取的管道。

雖然在同一個客戶端,但前端跟核心比較適合將它們看作客戶端 - 服務端的架構, 彼此會在不同的執行緒 (thread) 上執行。這兩個元件中間由一個橋接 (bridge) 模組介接, 這個橋接模組的實作則跟平台如何支援呼叫 C++ 程式庫有關。

客戶端核心

「客戶端核心」元件,顧名思義,主要負責整個網路的串流機制。實作上,基於移植性 (跨平台) 的需要,採用 C++ 開發。 這個元件也是組成對等網路 (overlay network) 的基礎,採用客製化過的 BitTorrent DHT 形成一個覆蓋網路。 藉由 DHT,客戶端可以找到在觀看同一個媒體源的其它客戶端,這些觀看同一個媒體源的客戶端彼此可以分享媒體資料片段。

實作上,此元件可以使用 libtorrent 這個開源程式庫來實作 DHT 以及集群的功能。雖然以 C++ 開發, 此元件仍需支援 C 語言的應用程式介面 (API)。

客戶端前端

「客戶端前端」元件負責使用者介面與媒體裝置的整合工作。

媒體裝置整合主要的工作有:

  • 影音回放 (playback):

    在使用者圖形介面上回放從核心元件收到的媒體資料,並確保視頻跟音頻的時間同步。

  • 影音擷取 (media capture)。

    擔任媒體源節點的客戶端需要即時擷取影音資料,並傳播給訂閱的接收端 (subscribers)。

客戶端平台

針對多平台的支援,軟體開發常採用的戰略便是開發跨平台可重用的程式碼。 對於預計支援的客戶端平台,底下簡介各個平台與客戶端核心元件 (以 C++ 開發) 的整合方式。

桌上環境 (Desktop; PC)

三大桌上環境分別為:Windows, OS X 以及 Linux。

Windows

大部份 Windows 的程式語言都支援與 C++ 程式庫做靜態或動態連結。

OS X

支援 Objective C++ 可以直接呼叫 C++ 的程式碼。

Linux

大部份 Linux 平台的程式語言都支援與 C++ 程式庫做靜態或動態連結。

行動裝置 (Mobile Devices)

目前主要的行動裝置平台不外乎:Android 跟 ios 兩大陣營。

Android

Android 平台主要以 Java 作為應用開發的程式語言,Android 支援 NDK 可以用來編譯 C++ 程式。 Java 應用則透過 JNI 來呼叫 C++ 程式庫。

ios

ios 主要開發語言 Objective C (未來將由 Swift 接替)。 跟 OS X 一樣,可以使用 Objective C++ 來支援 C++ 程式庫。

串流通訊協定的考量

同樣都需要透過網路傳播,選擇串流協定,還是要先了解 (實況)媒體資料跟一般資料的不同。

  1. 媒體串流資料是有即時性 (realtime) 要求,太舊的資料收到也沒有用了。
  2. 媒體資料允許部分資料遺失,雖然會造成短暫破格或延遲。

除非使用的通訊協定本身容許封包遺失,不然假如使用 TCP 這種可靠性傳輸協定,上述的特性其實用處不大。 以上純粹就理論說明,現實是:HTTP Live Streaming (HLS) 是目前行動裝置支援度最廣的串流協定。 由於 HLS 的協定設計,使得它在支援 HTML5 Video 的瀏覽器環境中的實現也是可行。所以採用類似 HLS 的協定設計在實作與部署上有它優點。HLS 並不是唯一以 HTTP
為基礎的串流協定,不過另外該關注的是基於 HTTP 的一個串流協定標準 MPEG-DASH

但點對點的出發點是要節省頻寬,採用 HLS 會遭遇 NAT 阻擋封包的問題。從這個觀點,以 UDP 為基礎的通訊協定 反而是比較適當的。以 UDP 為基礎的串流協定標準中,傳輸串流資料以 RTP 配合 RTCP 的組合較常使用。 在實際串流開始前,參與者需經過一個建立議程 (session establishment) 的階段來協商 (negotiate) 關於影音的格式、bitrate 等。
即使採用 UDP 為基礎的協定來以點對點方式傳輸串流資料,建立議程的協定通常還是需要第三方的協助,其中一個原因跟 NAT/Firewall 有關。

所以,採用 HLS 這種廣泛的協定,還是為了節省頻寬採用以 UDP 為基礎的協定,這是一個兩難的問題。 其中一個決定關鍵在於:有多少客戶端可以扮演超級對等點 (super peer)?超級對等點是擁有公開 IP 位址且 沒有 NAT/Firewall 阻擋 (或者已經開通) 的客戶端。如果系統中預計沒有多少超級節點,則唯有採用 UDP 為基礎 的協定才對點對點串流有所幫助;另一方面,如果有足夠多的超級節點,採用 HLS 則可以支援更多的平台跟裝置。

媒體格式相容性問題

串流架構支援在不同種類的裝置間進行點對點媒體串流,由於採實況串流,如果接收端不支援媒體源採用的編碼 (codecs) 的話,整個串流將無法運作。對於非實況串流,媒體資料可以動 (on-the-fly) 或預先做好轉碼 (transcoding)。

基於使用行動裝置做轉碼不實際這個前提,本文假設系統採用最通用的視訊跟音訊編碼。 行動裝置支援度最廣的視訊編碼:H.264 ,音訊編碼:AAC 或 MP3。

媒體編碼專利問題

本文無法對專利等法律問題深入探討,但目前已知 H.264 的使用受到專利權的保護。 對軟體開發商而言,通常會採用這個基本的假設:使用裝置 / 系統內建的支援來進行編碼 / 解碼不需要另外授權。
前提當然是假設裝置或系統廠商已經取得必要授權。對於打算使用第三方程式庫來處理 H.264 編碼的廠商, 專利權依然是個潛在問題。

安全性考量

用戶身份驗證

本文假設用戶身份由另一個子系統負責。

DHT 的安全性

整個架構的運作需要使用 DHT 所提供重要中介資料,因此 DHT 的安全性對於系統運作相當重要。 在設計上,DHT 只存放集群的成員位址資訊,並不能存放任意資料。所以,安全重點在於節點
要加入覆蓋網路時,需進行認證動作。簡單的認證機制可以基於共享秘鑰 (shared key) 的方式達成。

媒體資料保密

加入同一個集群的對等點需獲得解開串流媒體資料的金鑰,每個集群使用不同的金鑰來進行對稱式加解密。 媒體資料加密的原因是為了避免暴露資料給未授權的接收端,因為是實況串流, 採用簡單的對稱式加解密而不使用完整的 DRM 機制。

NAT/Firewall 問題

覆蓋網路,對等點間邏輯上好像可以互相溝通沒有阻礙,但現實是對等點可以各自位在不同 NAT 或防火牆後面, 尤其對行動網路,情況更是如此。由於這些設備會阻礙對等點間的通訊,也因此會影響覆蓋網路的有效性。

此架構設計假設行動裝置之間非常有可能位在防火牆這類裝置後,假設採用 HTTP Live Streaming (HLS) 協定, 因為 HLS 是基於 HTTP,而 HTTP 又以 TCP 為基礎。在行動裝置間使用 NAT 穿透 (hole punching) TCP 的技巧難度太高, 成功率又太低,解決方法只能朝以桌上型客戶端作為代理節點 (proxy) 的方向思考。

另一個思考方向則是採用 UDP 為基礎的串流協定,這種協定的 NAT 穿透技巧成功率有時可達 7 成以上。 對於桌上型客戶端,或者固網的客戶端,有機會可以透過 UPnP 來嘗試開通 NAT。

網路業者阻擋 P2P 流量的對策

撇開使用 P2P 軟體的道德層面,在商業考量上,網路業者不會樂意看到太高的點對點流量。 雖然說完全阻擋的可能性不大,但限制流量跟網速都是可能的反制措施。 不管如何,在實際部署一個行動點對點串流系統,這點也應該納入設計考量。例如,要盡量做到分散媒體資料來源,以避免少數對等點成為瓶頸。

結語

雖然使用點對點串流技術可以節省頻寬跟伺服器費用,但支援的裝置種類以及網路環境的複雜所衍生的開發與維護成本也需要納入整理考量。 即使主要目的在支援行動網路的點對點媒體串流,建議桌上型客戶端也列入發展重點。這些桌上型客戶端是扮演超級對等點的重要候選。 另外,為了符合各個平台使用者介面習慣,使用者介面建議盡可能使用該平台原生的 UI 元件。

參考資料

BitTorrent DHT: https://en.wikipedia.org/wiki/Mainline_DHT

libtorrent: http://libtorrent.org/

HTTP Live Streaming:
https://en.wikipedia.org/wiki/HTTP_Live_Streaming

MPEG-DASH:
https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP

RTP: https://en.wikipedia.org/wiki/Real-time_Transport_Protocol

RTCP: https://en.wikipedia.org/wiki/RTP_Control_Protocol

H.264: https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC

AAC: https://en.wikipedia.org/wiki/Advanced_Audio_Coding

DRM: https://en.wikipedia.org/wiki/Digital_rights_management