WebRTC 使用的編解碼器

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

無容器媒體

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

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

雖然在處理網路媒體時壓縮總是必要的,但在視訊會議中它格外重要,以確保參與者能夠進行通訊而不會出現延遲或中斷。次要重要的是需要保持影片和音訊同步,以便同時呈現動作和任何輔助資訊(例如幻燈片或投影)以及相應的音訊。

一般編解碼器要求

在檢視特定於編解碼器的功能和要求之前,任何用於 WebRTC 的編解碼器配置都必須滿足一些總體要求。

除非 SDP 明確另有說明,否則接收 WebRTC 影片流的網路瀏覽器必須能夠以 20 FPS 的速度處理影片,最小解析度為 320 畫素寬 x 240 畫素高。鼓勵影片以不低於此幀率和尺寸進行編碼,因為這基本上是 WebRTC 通常預期處理的下限。

SDP 支援一種獨立於編解碼器的方式來指定首選影片解析度(RFC 6236)。這是透過傳送 a=image-attr SDP 屬性來指示可接受的最大解析度來完成的。但是,傳送方不要求支援此機制,因此您必須準備好接收與您請求的解析度不同的媒體。除了此最大解析度請求之外,特定編解碼器可能會提供更多方式來請求特定的媒體配置。

支援的影片編解碼器

WebRTC 建立了一套基線編解碼器,所有相容的瀏覽器都必須支援。一些瀏覽器也可能選擇允許其他編解碼器。

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

強制影片編解碼器
編解碼器名稱 配置檔案 瀏覽器相容性
VP8

Chrome、Edge、Firefox、Safari (12.1+)

Firefox 134 支援 simulcast 的 VP8。Firefox 136+ 支援使用 VP8 的 DD RTP 頭擴充套件

AVC / H.264 受限基線 (CB)

Chrome (52+)、Edge、Firefox、Safari

  • Firefox 137+ 在桌面版上支援使用 H264 的 DD RTP 頭擴充套件。Android 上的 Firefox 不支援 DD 頭(Firefox bug 1947116)。
  • Firefox 136+ 支援 simulcast 的 H.264。
  • Firefox for Android 73+ 受硬體支援。
  • Firefox for Android 版本 68 到 72 不支援 H.264(由於 Google Play 商店要求的更改,阻止 Firefox 下載和安裝處理 WebRTC 連線中 H.264 所需的 OpenH264 編解碼器)。

有關每個編解碼器的 WebRTC 相關考慮因素的詳細資訊,請參閱以下子部分,點選每個編解碼器名稱上的連結。

WebRTC 需要支援哪些影片編解碼器和配置的完整詳細資訊可以在 RFC 7742:WebRTC 影片處理和編解碼器要求中找到。值得注意的是,該 RFC 涵蓋了各種影片相關要求,包括色彩空間(sRGB 是首選,但不是必需的預設色彩空間)、網路攝像頭處理功能(自動對焦、自動白平衡、自動光照水平)的建議等等。

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

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

其他影片編解碼器
編解碼器名稱 配置檔案 瀏覽器相容性
VP9

Chrome (48+)、Firefox

Firefox 預設不支援 VP9 的 simulcast (Firefox bug 1633876)。Firefox 136+ 支援使用 VP9 的 DD RTP 頭擴充套件

AV1

Chrome (113+)、Firefox (136+)

Firefox 136 支援 AV1 的 simulcast 和 DD RTP 頭擴充套件

VP8

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 一起使用時,此資訊必須帶內信令;因此,SDP 中不得包含 sprop-parameter-sets 引數。

必須指定的引數

在 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 訊息;這些訊息用於支援在多個輸入流之間無縫切換。

AV1

AV1 的一般描述可以在網路上使用的影片編解碼器主指南中找到。

依賴描述符 RTP 頭擴充套件

WebRTC 支援兩種主要技術,用於高效地傳送影片,供具有不同功能和網路條件的接收者使用。

AV1 使用依賴描述符 (DD) RTP 頭擴充套件來提供支援多方視訊會議用例所需的幀依賴資訊。

支援的音訊編解碼器

下表顯示了 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

網際網路低位元率編解碼器 (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

RFC 6716 定義的 Opus 格式是 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 mono) 48 到 64 kbps
全頻帶立體聲音樂 (FB stereo) 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;
      }
    });
  }

  codecList = null;
});

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

有了這些,我們遍歷傳送者列表,查詢第一個 MediaStreamTrack 指示其 kindvideo 的傳送者,表示該軌道的資料是影片媒體。然後我們呼叫該傳送者的 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 請求的預設——或者更準確地說,首選——編解碼器。

主流網路瀏覽器中 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 解決方案。最終決定權在您。無論您選擇哪個,請務必閱讀本文中提供的有關您可能需要為該編解碼器解決的任何特定配置問題的資訊。

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

安全隱患

在選擇和配置編解碼器時,會出現一些有趣的安全問題。WebRTC 影片使用資料報傳輸層安全(DTLS)進行保護,但從理論上講,在使用可變位元率 (VBR) 編解碼器時,有動機的方可以透過監視流的位元率及其隨時間的變化來推斷幀之間發生的變化量。這可能允許不良行為者根據位元率的潮起潮落推斷流內容的一些資訊。

有關在 WebRTC 中使用 AVC 時的安全考慮因素的更多資訊,請參閱 RFC 6184 第 9 節:H.264 影片的 RTP 有效負載格式:安全考慮

RTP 有效載荷格式媒體型別

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

另請參閱 RFC 4855,其中涵蓋了媒體型別登錄檔。

另見