WebRTC 使用的編解碼器

WebRTC API 使構建網站和應用程式成為可能,這些網站和應用程式允許使用者使用音訊和/或影片以及可選資料和其他資訊進行即時通訊。要進行通訊,兩臺裝置需要就每個音軌的相互理解的編解碼器達成一致,以便它們能夠成功地進行通訊並呈現共享的媒體。本指南迴顧了瀏覽器必須實現的編解碼器,以及某些或所有瀏覽器支援用於 WebRTC 的其他編解碼器。

無容器媒體

WebRTC 使用裸 MediaStreamTrack 物件來表示從一個對等方共享到另一個對等方的每個音軌,沒有容器甚至與音軌相關的 MediaStream。WebRTC 規範沒有規定這些音軌中可以包含哪些編解碼器。但是,RFC 7742 指定所有與 WebRTC 相容的瀏覽器必須支援 VP8H.264 的受限基線配置檔案用於影片,以及 RFC 7874 指定瀏覽器必須至少支援 Opus 編解碼器以及 G.711 的 PCMA 和 PCMU 格式。

這兩個 RFC 還列出了每個編解碼器必須支援的選項,以及特定的使用者舒適功能,例如回聲消除。本指南迴顧了瀏覽器必須實現的編解碼器,以及某些或所有瀏覽器支援用於 WebRTC 的其他編解碼器。

雖然壓縮在處理 Web 上的媒體時始終是必需的,但在進行視訊會議時它尤為重要,以確保參與者能夠在沒有延遲或中斷的情況下進行通訊。其次是需要保持影片和音訊同步,以便動作和任何輔助資訊(例如幻燈片或投影)與相應的音訊同時呈現。

通用編解碼器要求

在檢視特定編解碼器的功能和要求之前,任何與 WebRTC 一起使用的編解碼器配置都必須滿足以下幾個總體要求。

除非 SDP 明確指示,否則接收 WebRTC 影片流的網頁瀏覽器必須能夠處理以至少 320 畫素寬、240 畫素高的解析度以 20 FPS 的速度播放影片。建議影片的編碼幀速率和大小不低於此,因為這實際上是 WebRTC 通常預期處理的下限。

SDP 支援一種與編解碼器無關的方式來指定首選的影片解析度 (RFC 6236。這是透過傳送一個 a=imageattr SDP 屬性來完成的,以指示可接受的最大解析度。但是,傳送方不需要支援此機制,因此你必須做好接收與你請求的不同的解析度的媒體的準備。除了這個簡單的最大解析度請求之外,特定的編解碼器可能提供其他方法來請求特定的媒體配置。

支援的影片編解碼器

WebRTC 建立了一組基線編解碼器,所有符合標準的瀏覽器都必須支援這些編解碼器。某些瀏覽器可能會選擇也允許其他編解碼器。

以下是任何完全符合 WebRTC 標準的瀏覽器中必需的影片編解碼器,以及必需的配置檔案以及實際滿足要求的瀏覽器。

必需的影片編解碼器
編解碼器名稱 配置檔案 瀏覽器相容性
VP8 Chrome、Edge、Firefox、Safari (12.1+)
AVC / H.264 受限基線 (CB)

Chrome (52+)、Edge、Firefox、Safari

Firefox for Android 68 及更高版本不再支援 AVC (H.264)。這是由於 Google Play 商店要求的更改,這些更改阻止 Firefox 下載和安裝處理 WebRTC 連線中的 H.264 所需的 OpenH264 編解碼器。有關詳細資訊,請參閱 SUMO 上的這篇文章

有關每個編解碼器與 WebRTC 相關的注意事項的詳細資訊,請參閱以下子部分,方法是點選每個編解碼器名稱上的連結。

有關 WebRTC 必須支援的影片編解碼器和配置的完整詳細資訊,請參閱 RFC 7742:WebRTC 影片處理和編解碼器要求。值得注意的是,RFC 涵蓋了各種與影片相關的要求,包括顏色空間(sRGB 是首選的,但不是必需的,預設顏色空間)、對網路攝像頭處理功能的建議(自動對焦、自動白平衡、自動光照級別)等等。

注意:這些要求適用於網頁瀏覽器和其他完全符合 WebRTC 標準的產品。能夠與 WebRTC 進行一定程度通訊的非 WebRTC 產品可能支援也可能不支援這些編解碼器,儘管規範文件鼓勵它們支援。

除了必需的編解碼器之外,某些瀏覽器還支援其他編解碼器。這些編解碼器列在下面的表格中。

其他影片編解碼器
編解碼器名稱 配置檔案 瀏覽器相容性
VP9 Chrome (48+)、Firefox

VP8

VP8,我們在 總體介紹 中對它進行了介紹,在 Web 上使用的主要 影片編解碼器指南 中,在使用 VP8 對 WebRTC 連線上的影片音軌進行編碼或解碼時,必須遵循一些特定要求。

除非另有指示,否則 VP8 將使用方形畫素(即,畫素的 縱橫比 為 1:1)。

其他說明

使用 RTP 共享 VP8 的網路負載格式(例如在使用 WebRTC 時)在 RFC 7741:VP8 影片的 RTP 負載格式 中進行了描述。

AVC / H.264

在所有完全符合標準的 WebRTC 實現中,都需要支援 AVC 的受限基線 (CB) 配置檔案。CB 是主配置檔案的一個子集,專門為低複雜度、低延遲應用程式(如移動影片和視訊會議)以及影片處理能力較低的平臺而設計。

我們的 AVC 概述 及其功能可以在主要影片編解碼器指南中找到。

特殊引數支援要求

AVC 提供了各種引數來控制可選值。為了提高 WebRTC 媒體共享在多個平臺和瀏覽器之間的可靠性,要求支援 AVC 的 WebRTC 端點以特定方式處理某些引數。有時這意味著必須(或必須不)支援某個引數。有時這意味著要求某個引數的特定值,或允許特定的一組值。有時這些要求更加複雜。

有用的但不是必需的引數

WebRTC 端點不需要支援這些引數,使用這些引數也不是必需的。使用這些引數可以以各種方式改善使用者體驗,但不是必須的。事實上,其中一些引數使用起來相當複雜。

max-br

如果指定並由軟體支援,則 max-br 引數指定 VCL 的最大影片位元率(單位為 1,000 bps)和 NAL 的最大影片位元率(單位為 1,200 bps)。你可以在 RFC 6184 的第 47 頁 上找到有關此引數的詳細資訊。

max-cpb

如果指定並由軟體支援,則 max-cpb 指定最大編碼影像緩衝區大小。這是一個相當複雜的引數,其單位大小可能不同。有關詳細資訊,請參閱 RFC 6184 的第 45 頁

max-dpb

如果指定並支援,則 max-dpb 指示最大解碼影像緩衝區大小,以 8/3 個宏塊為單位。有關更多詳細資訊,請參閱 RFC 6184 的第 46 頁

max-fs

如果指定並由軟體支援,則 max-fs 指定單個影片幀的最大大小,以宏塊數為單位。

max-mbps

如果指定並由軟體支援,則該值是一個整數,指定每秒處理宏塊的最大速率(以每秒宏塊數為單位)。

max-smbps

如果指定並由軟體支援,則該值指定一個整數,表示每秒處理靜態宏塊的最大速率(以每秒靜態宏塊數為單位,假設所有宏塊都是靜態宏塊)。

具有特定要求的引數

這些引數可能需要也可能不需要,但在使用時有一些特殊要求。

packetization-mode

所有端點都必須支援模式 1(非交錯模式)。對其他分組模式的支援是可選的,引數本身也不需要指定。

sprop-parameter-sets

AVC 的序列和影像資訊可以在帶內或帶外發送。當 AVC 與 WebRTC 一起使用時,此資訊必須在帶內進行訊號傳輸;因此,sprop-parameter-sets 引數不能包含在 SDP 中。

必須指定的引數

在 WebRTC 連線中使用 AVC 時,必須指定這些引數。

profile-level-id

所有 WebRTC 實現都需要在它們的 SDP 中指定和解釋此引數,以標識編解碼器使用的子配置檔案。設定的具體值沒有定義;重要的是引數本身的使用。這一點值得注意,因為在 RFC 6184(“H.264 影片的 RTP 負載格式”)中,profile-level-id 實際上是可選的。

其他要求

為了支援在縱向和橫向之間切換,可以使用兩種方法。第一種是 RTP 協議的影片方向 (CVO) 報頭擴充套件。但是,如果 SDP 中沒有將其作為支援的訊號,則建議瀏覽器支援顯示方向 SEI 訊息,儘管不是必需的。

除非另有指示,否則畫素縱橫比為 1:1,表示畫素為正方形。

其他說明

WebRTC 中用於 AVC 的負載格式在 RFC 6184:H.264 影片的 RTP 負載格式 中描述。WebRTC 的 AVC 實現需要支援特殊的“填充負載”和“全幀凍結”SEI 訊息;這些用於無縫支援多個輸入流之間的切換。

支援的音訊編解碼器

下表列出了 RFC 7874 規定所有與 WebRTC 相容的瀏覽器必須支援的音訊編解碼器。

強制音訊編解碼器
編解碼器名稱 瀏覽器相容性
Opus Chrome、Edge、Firefox、Safari
G.711 PCM (A-law) Chrome、Firefox、Safari
G.711 PCM (µ-law) Chrome、Firefox、Safari

有關上面列出的每個編解碼器存在的任何 WebRTC 特定注意事項的更多詳細資訊,請參見下文。

需要注意的是,RFC 7874 不僅定義了與 WebRTC 相容的瀏覽器必須支援的音訊編解碼器列表;它還為回聲消除、噪聲抑制和音訊電平等特殊音訊功能提供了建議和要求。

注意: 上面的列表指示了所有與 WebRTC 相容的端點必須實現的最低要求的編解碼器集。給定的瀏覽器也可能支援其他編解碼器;但是,如果您在沒有仔細確保您的使用者可能選擇的瀏覽器都支援的情況下使用其他編解碼器,則可能會存在跨平臺和跨裝置相容性問題。

除了強制音訊編解碼器之外,一些瀏覽器還支援其他編解碼器。這些列在下表中。

其他音訊編解碼器
編解碼器名稱 瀏覽器相容性
G.722 Chrome、Firefox、Safari
iLBC Chrome、Safari
iSAC Chrome、Safari

Internet 低位元率編解碼器 (iLBC) 是一種由 Global IP Solutions 開發,現在由 Google 開發的開源窄帶編解碼器,專門用於流式傳輸語音音訊。Google 和一些其他瀏覽器開發人員已將其用於 WebRTC。

網際網路語音音訊編解碼器 (iSAC) 是由 Global IP Solutions 開發,現在由 Google 擁有的另一種編解碼器,它已將其開源。它被 Google Talk、QQ 和其他即時訊息客戶端使用,專門用於封裝在 RTP 流中的語音傳輸。

舒適噪聲 (CN) 是一種人造背景噪聲,用於填充傳輸中的間隙,而不是使用純靜音。這有助於避免在語音啟用和類似功能導致流臨時停止傳送資料時可能發生的刺耳效果——一種稱為不連續傳輸 (DTX) 的功能。在 RFC 3389 中,提供了一種在靜音期間使用適當填充的方法。

舒適噪聲與 G.711 一起使用,並且可能與其他沒有內建 CN 功能的編解碼器一起使用。例如,Opus 有自己的 CN 功能;因此,不建議將 RFC 3389 CN 與 Opus 編解碼器一起使用。

音訊傳送方永遠不需要使用不連續傳輸或舒適噪聲。

Opus

Opus 格式由 RFC 6716 定義,是 WebRTC 中音訊的主要格式。Opus 的 RTP 負載格式可以在 RFC 7587 中找到。您可以在我們的 相應部分 中找到有關 Opus 及其功能,以及其他 API 如何支援 Opus 的更多一般資訊,以及我們的 網路上使用的音訊編解碼器指南

語音和通用音訊模式都應得到支援。Opus 的可擴充套件性和靈活性在處理可能具有不同複雜程度的音訊時非常有用。它支援帶內立體聲訊號,允許支援立體聲而不使解複用過程複雜化。

WebRTC 支援 Opus 支援的整個位元率範圍(6 kbps 到 510 kbps),並且允許動態更改位元率。更高的位元率通常會提高質量。

位元率建議

假設 20 毫秒的幀大小,下表顯示了各種媒體形式的推薦位元率。

媒體型別 推薦位元率範圍
窄帶語音 (NB) 8 到 12 kbps
寬頻語音 (WB) 16 到 20 kbps
全頻語音 (FB) 28 到 40 kbps
全頻單聲道音樂 (FB 單聲道) 48 到 64 kbps
全頻立體聲音樂 (FB 立體聲) 64 到 128 kbps

位元率可以隨時調整。為了避免網路擁塞,平均音訊位元率不應超過可用網路頻寬(減去任何其他已知或預計的額外頻寬需求)。

G.711

G.711 定義了脈衝編碼調製 (PCM) 音訊的格式,作為一系列以 8,000 Hz 的取樣率採集的 8 位整數樣本,產生 64 kbps 的位元率。允許 µ-lawA-law 編碼。

G.711 由 ITU 定義,其負載格式在 RFC 3551 第 4.5.14 節 中定義。

WebRTC 要求 G.711 使用標準 64 kbps 速率的 8 位樣本,即使 G.711 支援其他一些變體。WebRTC 不強制使用 G.711.0(無失真壓縮)、G.711.1(寬頻功能)或 G.711 標準的任何其他擴充套件。

由於其低取樣率和樣本大小,G.711 音訊質量通常被認為按現代標準很差,即使它與固定電話的聲音大致相同。它通常用作最低公分母,以確保瀏覽器無論平臺和瀏覽器如何都能建立音訊連線,或者一般用作備用選項。

指定和配置編解碼器

獲取支援的編解碼器

由於給定的瀏覽器和平臺在潛在編解碼器中的可用性可能不同,並且可能對給定的編解碼器支援多個配置檔案或級別,因此配置 RTCPeerConnection 的編解碼器的第一步是獲取可用編解碼器列表。為此,您首先必須建立一個用於獲取列表的連線。

您可以用幾種方法做到這一點。最有效的方法是使用靜態方法 RTCRtpSender.getCapabilities()(或用於接收器的等效方法 RTCRtpReceiver.getCapabilities()),將媒體型別指定為輸入引數。例如,要確定對影片支援的編解碼器,您可以執行以下操作

js
codecList = RTCRtpSender.getCapabilities("video").codecs;

現在 codecList 是一個包含 codec 物件的陣列,每個物件都描述了一種編解碼器配置。列表中還會包含對 重傳 (RTX)、冗餘編碼 (RED) 和 前向糾錯 (FEC) 的條目。

如果連線正在啟動,您可以使用 icegatheringstatechange 事件來監視 ICE 候選收集完成,然後獲取列表。

js
let codecList = null;

peerConnection.addEventListener("icegatheringstatechange", (event) => {
  if (peerConnection.iceGatheringState === "complete") {
    const senders = peerConnection.getSenders();

    senders.forEach((sender) => {
      if (sender.track.kind === "video") {
        codecList = sender.getParameters().codecs;
        return;
      }
    });
  }

  codecList = null;
});

icegatheringstatechange 的事件處理程式已建立;在其中,我們檢視 ICE 收集狀態是否為 complete,這表示不會收集更多候選。呼叫方法 RTCPeerConnection.getSenders() 以獲取連線使用的所有 RTCRtpSender 物件的列表。

有了它,我們遍歷傳送者列表,尋找第一個 MediaStreamTrackkind 指示其資料為影片媒體的傳送者。然後,我們呼叫該傳送者的 getParameters() 方法,將 codecList 設定為返回物件中的 codecs 屬性,然後返回到呼叫者。

如果找不到影片軌道,我們將 codecList 設定為 null

然後,在返回時,codecList 既可以是 null(表示未找到任何影片軌道),也可以是 RTCCodecStats 物件的陣列,每個物件都描述了一種允許的編解碼器配置。在這些物件中特別重要的是:payloadType 屬性,它是一個唯一的標識所描述配置的位元組值。

注意: 此處顯示的兩種用於獲取編解碼器列表的方法在其編解碼器列表中使用不同的輸出型別。在使用結果時請注意這一點。

自定義編解碼器列表

獲得可用編解碼器列表後,您可以對其進行修改,然後將修改後的列表傳送到 RTCRtpTransceiver.setCodecPreferences() 以重新排列編解碼器列表。這會更改編解碼器優先順序的順序,讓您可以告訴 WebRTC 優先考慮其他所有編解碼器。

js
function changeVideoCodec(mimeType) {
  const transceivers = peerConnection.getTransceivers();

  transceivers.forEach((transceiver) => {
    const kind = transceiver.sender.track.kind;
    let sendCodecs = RTCRtpSender.getCapabilities(kind).codecs;
    let recvCodecs = RTCRtpReceiver.getCapabilities(kind).codecs;

    if (kind === "video") {
      sendCodecs = preferCodec(mimeType);
      recvCodecs = preferCodec(mimeType);
      transceiver.setCodecPreferences([...sendCodecs, ...recvCodecs]);
    }
  });

  peerConnection.onnegotiationneeded();
}

在此示例中,函式 changeVideoCodec() 以您要使用的編解碼器的 MIME 型別作為輸入。程式碼首先獲取所有 RTCPeerConnection 的轉發器的列表。

然後,對於每個轉發器,我們從 RTCRtpSender 的軌道的 kind 中獲取轉發器所代表的媒體型別。我們還使用 RTCRtpSenderRTCRtpReceivergetCapabilities() 靜態方法獲取瀏覽器支援的所有用於傳送和接收影片的編解碼器列表。

如果媒體是影片,我們針對傳送方和接收方的編解碼器列表都呼叫名為 preferCodec() 的方法;此方法以我們想要的方式重新排列編解碼器列表(見下文)。

最後,我們呼叫 RTCRtpTransceiversetCodecPreferences() 方法以指定允許使用給定的傳送和接收編解碼器,並按照新重新排列的順序進行。

對於 RTCPeerConnection 上的每個收發器,都會執行此操作;一旦所有收發器都更新完畢,我們就會呼叫 onnegotiationneeded 事件處理程式,它將建立一個新的提議,更新本地描述,將提議傳送到遠端對等方,等等,從而觸發連線的重新協商。

上面的程式碼呼叫的 preferCodec() 函式看起來像這樣,用於將指定的編解碼器移動到列表的頂部(以便在協商期間優先考慮)。

js
function preferCodec(codecs, mimeType) {
  let otherCodecs = [];
  let sortedCodecs = [];
  let count = codecs.length;

  codecs.forEach((codec) => {
    if (codec.mimeType === mimeType) {
      sortedCodecs.push(codec);
    } else {
      otherCodecs.push(codec);
    }
  });

  return sortedCodecs.concat(otherCodecs);
}

此程式碼只是將編解碼器列表拆分為兩個陣列:一個包含 MIME 型別與 mimeType 引數指定的 MIME 型別匹配的編解碼器,另一個包含所有其他編解碼器。一旦列表被拆分,它們就會被連線在一起,以匹配給定 mimeType 的條目開頭,然後是所有其他編解碼器。然後將重新排列的列表返回給呼叫者。

預設編解碼器

除非另有說明,否則每個瀏覽器實現 WebRTC 時請求的預設編解碼器(或更準確地說是首選編解碼器)如以下表格所示。

主要 Web 瀏覽器中的 WebRTC 首選編解碼器
音訊 影片
Chrome
Edge
Firefox VP9(Firefox 46 及更高版本)
VP8
Opera
Safari

選擇合適的編解碼器

在選擇不是強制編解碼器之一(影片為 VP8 或 AVC,音訊為 Opus 或 PCM)的編解碼器之前,您應該認真考慮潛在的缺點:特別是,只有這些編解碼器可以普遍假設在支援 WebRTC 的所有裝置上可用。

如果您選擇優先使用除強制編解碼器以外的編解碼器,您至少應該允許在不支援您喜歡的編解碼器的情況下回退到強制編解碼器之一。

音訊

通常,如果可用,並且您要傳送的音訊的取樣率大於 8 kHz,您應該認真考慮使用 Opus 作為您的主要編解碼器。對於受限環境中的純語音連線,在 8 kHz 取樣率下使用 G.711 可以為對話提供可接受的體驗,但通常您會將 G.711 用作回退選項,因為還有其他更有效且聲音更好的選項,例如 Opus 的窄帶模式。

影片

在決定支援哪個影片編解碼器(或一組編解碼器)時,有許多因素會起作用。

許可條款

在選擇影片編解碼器之前,請確保您瞭解所選編解碼器的任何許可要求;您可以在我們主要的 網路上使用影片編解碼器的指南 中找到有關可能許可問題的資訊。在影片的兩個強制編解碼器中,VP8 和 AVC/H.264,只有 VP8 完全免除許可要求。如果您選擇 AVC,請確保您瞭解您可能需要支付的任何潛在費用;也就是說,專利持有者通常表示,大多數典型的網站開發人員無需擔心支付許可費用,這些費用通常更側重於編碼和解碼軟體的開發人員。

警告: 此處的資料不構成法律建議!在做出可能存在許可問題的最終決定之前,請務必確認您所承擔的責任。

功耗和電池壽命

另一個需要考慮的因素(尤其是在移動平臺上)是編解碼器對電池壽命的影響。如果編解碼器在給定平臺的硬體上處理,該編解碼器很可能允許獲得更好的電池壽命和更低的熱量產生。

例如,適用於 iOS 和 iPadOS 的 Safari 在引入 WebRTC 時僅將 AVC 作為支援的影片編解碼器。AVC 在 iOS 和 iPadOS 上的優勢是可以透過硬體進行編碼和解碼。Safari 12.1 在 IRC 中引入了對 VP8 的支援,這提高了互操作性,但代價是 - VP8 在 iOS 裝置上沒有硬體支援,因此使用它會導致處理器影響增加,電池壽命縮短。

效能

幸運的是,從終端使用者角度來看,VP8 和 AVC 的效能類似,並且同樣適合用於視訊會議和其他 WebRTC 解決方案。最終的決定由您做出。無論您選擇哪種編解碼器,請務必閱讀本文中提供的資訊,瞭解您可能需要解決的任何特定配置問題。

請記住,選擇不在強制編解碼器列表中的編解碼器,可能會存在選擇使用者可能喜歡的瀏覽器不支援的編解碼器的風險。請參閱文章 處理 Web 內容中的媒體支援問題,瞭解如何為您喜歡的編解碼器提供支援,同時仍然能夠回退到未實現該編解碼器的瀏覽器。

安全隱患

在選擇和配置編解碼器時,會存在一些有趣且潛在的安全問題。WebRTC 影片使用資料報傳輸層安全 (DTLS) 進行保護,但在理論上,透過監視流的位元率及其隨時間的變化方式,動機強的方可以推斷出使用可變位元率 (VBR) 編解碼器時幀間變化的程度。鑑於位元率的起伏,這可能會讓攻擊者推斷出有關流內容的資訊。

有關在 WebRTC 中使用 AVC 時的安全注意事項,請參閱 RFC 6184,第 9 節:H.264 影片的 RTP 載荷格式:安全注意事項

RTP 負載格式媒體型別

參考 IANARTP 載荷格式媒體型別列表可能會有用;這是為潛在在 RTP 流中使用(例如在 WebRTC 中使用的流)而定義的 MIME 媒體型別的完整列表。大多數這些型別不用於 WebRTC 上下文,但該列表仍然可能有用。

另請參閱 RFC 4855,其中涵蓋了媒體型別的註冊。

另請參閱