WebRTC 使用的编解码器
WebRTC API 使构建网站和应用程序成为可能,这些网站和应用程序允许用户使用音频和/或视频以及可选数据和其他信息进行实时通信。要进行通信,两台设备需要就每个音轨的相互理解的编解码器达成一致,以便它们能够成功地进行通信并呈现共享的媒体。本指南回顾了浏览器必须实现的编解码器,以及某些或所有浏览器支持用于 WebRTC 的其他编解码器。
无容器媒体
WebRTC 使用裸 MediaStreamTrack
对象来表示从一个对等方共享到另一个对等方的每个音轨,没有容器甚至与音轨相关的 MediaStream
。WebRTC 规范没有规定这些音轨中可以包含哪些编解码器。但是,RFC 7742 指定所有与 WebRTC 兼容的浏览器必须支持 VP8 和 H.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 的比特率。允许 µ-law 和 A-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()
),将媒体类型指定为输入参数。例如,要确定对视频支持的编解码器,您可以执行以下操作
codecList = RTCRtpSender.getCapabilities("video").codecs;
现在 codecList
是一个包含 codec
对象的数组,每个对象都描述了一种编解码器配置。列表中还会包含对 重传 (RTX)、冗余编码 (RED) 和 前向纠错 (FEC) 的条目。
如果连接正在启动,您可以使用 icegatheringstatechange
事件来监视 ICE 候选收集完成,然后获取列表。
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
对象的列表。
有了它,我们遍历发送者列表,寻找第一个 MediaStreamTrack
的 kind
指示其数据为视频媒体的发送者。然后,我们调用该发送者的 getParameters()
方法,将 codecList
设置为返回对象中的 codecs
属性,然后返回到调用者。
如果找不到视频轨道,我们将 codecList
设置为 null
。
然后,在返回时,codecList
既可以是 null
(表示未找到任何视频轨道),也可以是 RTCCodecStats
对象的数组,每个对象都描述了一种允许的编解码器配置。在这些对象中特别重要的是:payloadType
属性,它是一个唯一的标识所描述配置的字节值。
注意: 此处显示的两种用于获取编解码器列表的方法在其编解码器列表中使用不同的输出类型。在使用结果时请注意这一点。
自定义编解码器列表
获得可用编解码器列表后,您可以对其进行修改,然后将修改后的列表发送到 RTCRtpTransceiver.setCodecPreferences()
以重新排列编解码器列表。这会更改编解码器优先级的顺序,让您可以告诉 WebRTC 优先考虑其他所有编解码器。
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
中获取转发器所代表的媒体类型。我们还使用 RTCRtpSender
和 RTCRtpReceiver
的 getCapabilities()
静态方法获取浏览器支持的所有用于发送和接收视频的编解码器列表。
如果媒体是视频,我们针对发送方和接收方的编解码器列表都调用名为 preferCodec()
的方法;此方法以我们想要的方式重新排列编解码器列表(见下文)。
最后,我们调用 RTCRtpTransceiver
的 setCodecPreferences()
方法以指定允许使用给定的发送和接收编解码器,并按照新重新排列的顺序进行。
对于 RTCPeerConnection
上的每个收发器,都会执行此操作;一旦所有收发器都更新完毕,我们就会调用 onnegotiationneeded
事件处理程序,它将创建一个新的提议,更新本地描述,将提议发送到远程对等方,等等,从而触发连接的重新协商。
上面的代码调用的 preferCodec()
函数看起来像这样,用于将指定的编解码器移动到列表的顶部(以便在协商期间优先考虑)。
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 时请求的默认编解码器(或更准确地说是首选编解码器)如以下表格所示。
音频 | 视频 | |
---|---|---|
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 载荷格式:安全注意事项。