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,其中涵盖了媒体类型注册表。

另见