1. 简介
本节为非规范性内容本规范定义了一个 API,用于根据媒体的编解码器、配置文件、分辨率、码率等信息,查询用户代理的音频和视频解码与编码能力。该 API 会指示配置是否受支持,以及播放是否预计流畅和/或节能。
本规范重点关注编码和解码能力。它预期将与其它 Web API 配合使用,这些 API 能提供显示属性的信息,如支持的色域或动态范围能力,从而让 Web 应用为显示设备挑选合适的内容,例如避免向 SDR 显示器提供 HDR 内容。
2. 解码与编码能力
2.1. 媒体配置
2.1.1. MediaConfiguration
dictionary {
MediaConfiguration VideoConfiguration ;
video AudioConfiguration ; };
audio
dictionary :
MediaDecodingConfiguration MediaConfiguration {required MediaDecodingType ;
type MediaCapabilitiesKeySystemConfiguration ; };
keySystemConfiguration
dictionary :
MediaEncodingConfiguration MediaConfiguration {required MediaEncodingType ; };
type
解码能力的输入由 MediaDecodingConfiguration
字典表示,编码能力的输入由 MediaEncodingConfiguration
字典表示。
一个 MediaConfiguration
要成为 有效的
MediaConfiguration,必须同时满足以下所有条件:
一个 MediaDecodingConfiguration
要成为 有效的
MediaDecodingConfiguration,必须同时满足以下所有条件:
- 必须是一个有效的 MediaConfiguration。
-
如果
keySystemConfiguration
存在:
一个 MediaDecodingConfiguration
若描述 [ENCRYPTED-MEDIA],
则 keySystemConfiguration
必须存在。
2.1.2. MediaDecodingType
enum {
MediaDecodingType "file" ,"media-source" ,"webrtc" };
MediaDecodingConfiguration
有三种类型:
file
用于表示配置被用于播放除MediaSource
(定义见 [media-source])和RTCPeerConnection
(定义见 [webrtc])以外的媒体源的情况。media-source
用于表示配置被用于播放MediaSource
的情况。webrtc
用于表示配置被用于通过RTCPeerConnection
接收的情况。
2.1.3. MediaEncodingType
enum {
MediaEncodingType "record" ,"webrtc" };
MediaEncodingConfiguration
可以有以下两种类型:
record
用于表示媒体录制的配置, 例如使用MediaRecorder
(定义见 [mediastream-recording])。webrtc
用于表示通过RTCPeerConnection
(定义见 [webrtc])进行传输的配置。
2.1.4. VideoConfiguration
dictionary {
VideoConfiguration required DOMString contentType ;required unsigned long width ;required unsigned long height ;required unsigned long long bitrate ;required double framerate ;boolean hasAlphaChannel ;HdrMetadataType hdrMetadataType ;ColorGamut colorGamut ;TransferFunction transferFunction ;DOMString scalabilityMode ;boolean spatialScalability ; };
contentType
成员表示视频轨道的
MIME 类型。
要判断一个 VideoConfiguration
configuration 是否为
有效视频配置,必须执行以下步骤:
-
如果
framerate
不是有限值或小于等于 0,则返回false
并终止本步骤。 -
如果某个可选成员被用于某个
MediaDecodingType
或MediaEncodingType
并且不适用,则返回false
并终止本步骤。具体适用性规则见下方成员定义。 -
令 mimeType 为运行 解析 MIME 类型
并传入 configuration 的
contentType
的结果。 -
如果 mimeType 是
failure
,返回false
。 -
返回运行 检查 MIME 类型有效性(参数为
mimeType 和
video
)的结果。
width
和
height
成员分别表示编码视频帧中可见的水平和垂直像素数。
bitrate
成员表示视频轨道的比特率,单位为比特每秒。对于使用恒定码率(CBR)编码的视频流,此值表示视频轨道的平均比特率。对于可变码率(VBR)编码的视频流,此值表示视频轨道的最大比特率。
framerate
成员表示视频轨道的帧率,即每秒的帧数。类型为 double。
hasAlphaChannel
成员表示视频轨道是否包含 alpha 通道信息。为 true 时,编码后的视频流在解码时可生成每像素的 alpha 通道信息;为 false 时,解码后的视频流无法生成每像素 alpha
通道信息;如未定义,UA 应根据 contentType
判断是否编码了 alpha 通道信息(如可判断),否则 UA 应默认视频流无法生成 alpha 通道信息。
如存在,hdrMetadataType
成员表示视频轨道包含指定的 HDR 元数据类型,UA 需要能够解析此元数据以将 HDR 内容映射到输出设备的色彩范围和亮度。有效输入由 HdrMetadataType
定义。hdrMetadataType 仅适用于 MediaDecodingConfiguration
类型为 media-source
和 file
。
如存在,colorGamut
成员表示视频轨道是以指定色域传递的,即内容预期显示的颜色集合。如果输出设备也支持该色域,UA 需能使设备渲染相应的颜色或接近的颜色;如输出设备不支持该色域,UA
需能将其映射为设备支持的颜色。有效输入由 ColorGamut
定义。colorGamut 仅适用于 MediaDecodingConfiguration
类型为 media-source
和 file
。
如存在,transferFunction
成员表示视频轨道需要 UA 能理解指定的传递函数。传递函数描述 UA 渲染能力支持的电光转换算法,用于将解码媒体的源颜色映射到显示颜色(与显示设备无关)。有效输入由 TransferFunction
定义。transferFunction 仅适用于 MediaDecodingConfiguration
类型为 media-source
和 file
。
如存在,scalabilityMode
成员表示扩展性模式,定义见 [webrtc-svc]。如未指定,则使用该 contentType
的实现者默认模式(即未通过 setParameters()
指定时得到的模式)。scalabilityMode 仅适用于 MediaEncodingConfiguration
类型为 webrtc
。
如果 scalabilityMode
指示存在多空间层,
width
和
height
的值对应编码的最大空间层。
如存在,spatialScalability
成员表示空间预测能力,即可使用不同分辨率的帧作为依赖帧。如未指定,spatialScalability
默认为 false
。如 spatialScalability
设为 true
,则解码器可解码编码器为所选编解码器编码的任意 scalabilityMode
。如
spatialScalability
设为 false
,则解码器无法解码空间扩展模式,但可解码编码器为所选编解码器编码的所有其他 scalabilityMode
。spatialScalability
仅适用于 MediaDecodingConfiguration
类型为 media-source
、file
和 webrtc
。
2.1.5. HdrMetadataType
enum {
HdrMetadataType "smpteSt2086" ,"smpteSt2094-10" ,"smpteSt2094-40" };
如果存在,HdrMetadataType
描述了解释指定类型 HDR 元数据的能力。
VideoConfiguration
可能包含以下类型之一:
-
smpteSt2086
, 代表由 [SMPTE-ST-2086] 定义的静态元数据类型。 -
smpteSt2094-10
, 代表由 [SMPTE-ST-2094] 定义的动态元数据类型。 -
smpteSt2094-40
, 代表由 [SMPTE-ST-2094] 定义的动态元数据类型。
2.1.6. 色域(ColorGamut)
enum {
ColorGamut "srgb" ,"p3" ,"rec2020" };
VideoConfiguration
可能包含以下类型之一:
2.1.7. 传递函数(TransferFunction)
enum {
TransferFunction "srgb" ,"pq" ,"hlg" };
VideoConfiguration
可能包含以下类型之一:
-
srgb
,表示由 [sRGB] 定义的传递函数。 -
pq
,表示 “感知量化器”(Perceptual Quantizer)传递函数,由 [SMPTE-ST-2084] 定义。 -
hlg
,表示 BT.2100 定义的“混合对数伽玛”(Hybrid Log Gamma)传递函数。
2.1.8. 音频配置(AudioConfiguration)
dictionary {
AudioConfiguration required DOMString contentType ;DOMString channels ;unsigned long long bitrate ;unsigned long samplerate ;boolean spatialRendering ; };
contentType
成员表示音轨的
MIME 类型。
要检查 AudioConfiguration
configuration 是否是
有效音频配置,必须按以下步骤进行:
-
令 mimeType 为使用 configuration 的
contentType
执行 解析 MIME 类型 的结果。 -
如果 mimeType 为
failure
,返回false
。 -
返回以 mimeType 和
audio
执行 检查 MIME 类型有效性 的结果。
channels
成员表示音轨使用的音频声道。channels 仅适用于解码类型 media-source
、
file
、
和 webrtc
,以及编码类型
webrtc
。
channels
需要被定义为 double
(2.1、4.1、5.1 等)、unsigned short
(声道数量)或 enum
值。目前的定义为占位符。
bitrate
成员表示音轨的平均比特率。比特率为编码一秒音轨所用的比特数。
samplerate
成员表示音轨的采样率。采样率是每秒携带的音频采样数。samplerate 仅适用于解码类型 media-source
、
file
、
和 webrtc
,以及编码类型
webrtc
。
samplerate
以 Hz
(即每秒音频采样数)为单位。有时 samplerate 的值以 kHz
表示,代表每秒成千上万个音频采样。
44100 Hz
等价于 44.1 kHz
。
spatialRendering
成员表示音频应以空间方式渲染。空间渲染的细节应从
contentType
推断。
如果其未 存在,UA 必须假定不需要空间渲染。当 true
时,用户代理仅在当前音频输出设备能支持空间渲染且不回退为非空间混合流时,才应报告此配置为
supported
。spatialRendering
仅适用于
MediaDecodingConfiguration
的类型 media-source
和 file
。
2.1.9. MediaCapabilitiesKeySystemConfiguration
dictionary {
MediaCapabilitiesKeySystemConfiguration required DOMString keySystem ;DOMString initDataType = "";MediaKeysRequirement distinctiveIdentifier = "optional";MediaKeysRequirement persistentState = "optional";sequence <DOMString >sessionTypes ;KeySystemTrackConfiguration audio ;KeySystemTrackConfiguration video ; };
本字典涉及多个由 [ENCRYPTED-MEDIA](EME)定义的类型。EME 类型的序列在序列意图为
让 requestMediaKeySystemAccess()
选择其支持的子集时,会被展平成单一值。
使用 MediaCapabilities 时,调用者会通过多次调用提供序列,最终由调用者选择要使用的配置。
keySystem
成员表示 keySystem
名称,详见 [ENCRYPTED-MEDIA]。
initDataType
成员表示 initDataTypes
序列中的单一值,详见 [ENCRYPTED-MEDIA]。
distinctiveIdentifier
成员表示 distinctiveIdentifier
要求,详见 [ENCRYPTED-MEDIA]。
persistentState
成员表示 persistentState
要求,详见 [ENCRYPTED-MEDIA]。
sessionTypes
成员表示所需 sessionTypes
的序列,详见 [ENCRYPTED-MEDIA]。
audio
成员表示与 KeySystemTrackConfiguration
关联的 AudioConfiguration
。
video
成员表示与 KeySystemTrackConfiguration
关联的 VideoConfiguration
。
2.1.10. KeySystemTrackConfiguration(密钥系统轨道配置)
dictionary {
KeySystemTrackConfiguration DOMString robustness = "";DOMString ?encryptionScheme =null ; };
robustness
成员表示
robustness
等级,详见 [ENCRYPTED-MEDIA]。
encryptionScheme
成员表示
encryptionScheme
,详见 [ENCRYPTED-MEDIA-DRAFT]。
2.2. 媒体能力信息
dictionary {
MediaCapabilitiesInfo required boolean supported ;required boolean smooth ;required boolean powerEfficient ; };
dictionary :
MediaCapabilitiesDecodingInfo MediaCapabilitiesInfo {required MediaKeySystemAccess ?keySystemAccess ;required MediaDecodingConfiguration configuration ; };
dictionary :
MediaCapabilitiesEncodingInfo MediaCapabilitiesInfo {required MediaEncodingConfiguration configuration ; };
MediaCapabilitiesInfo
关联有 supported
、smooth
、powerEfficient
字段,均为布尔值。
当编码或解码被认为是高能效时,说明功耗为最优。编码或解码的最优功耗定义由用户代理决定。不过,常见实现方式是以硬件使用作为最优化功耗的标志。用户代理不应默认将硬件编码或解码标记为高能效,因为非硬件加速的编解码器在低分辨率视频下也可能非常高效。在判断编码能效时,用户代理不应考虑设备的电源来源,除非电源来源有副作用(如启用不同的编码或解码模块)。
MediaCapabilitiesDecodingInfo
关联有
keySystemAccess
,其类型为 MediaKeySystemAccess
或 null
。
如果加密解码配置受支持,返回的 MediaCapabilitiesInfo
将包含 MediaKeySystemAccess
。
作者可以用此来创建
MediaKeys
并设置加密播放。
MediaCapabilitiesDecodingInfo
关联有 configuration
,为用于生成
MediaCapabilitiesDecodingInfo
的解码配置属性。
MediaCapabilitiesEncodingInfo
关联有 configuration
,为用于生成
MediaCapabilitiesEncodingInfo
的编码配置属性。
2.3. 算法
2.3.1. 创建 MediaCapabilitiesEncodingInfo
要创建
MediaCapabilitiesEncodingInfo,给定
MediaEncodingConfiguration
configuration,执行以下步骤。将返回一个 MediaCapabilitiesEncodingInfo
:
-
令 info 为一个新的
MediaCapabilitiesEncodingInfo
实例。除非另有说明,后续步骤的读写都应用于 info。 -
将
configuration
设为一个新的MediaEncodingConfiguration
。 对于 configuration 中的每个属性,在configuration
中创建同名同值的新属性。 -
令 videoSupported 为
unknown
。 -
如果
video
存在于 configuration,执行以下步骤:-
令 videoMimeType 为用 configuration 的
contentType
执行 解析 MIME 类型 的结果。 -
将 videoSupported 设为执行
检查 MIME 类型支持算法(参数为
videoMimeType 和 configuration 的
type
)的结果。
-
令 videoMimeType 为用 configuration 的
-
令 audioSupported 为
unknown
。 -
如果
audio
存在于 configuration,执行以下步骤:-
令 audioMimeType 为用 configuration 的
contentType
执行 解析 MIME 类型 的结果。 -
将 audioSupported 设为执行
检查 MIME 类型支持算法(参数为
audioMimeType 和 configuration 的
type
)的结果。
-
令 audioMimeType 为用 configuration 的
-
如果 videoSupported 或 audioSupported 有一个为
unsupported
,将supported
、smooth
、powerEfficient
都设为false
,并返回 info。 -
否则,将
supported
设为true
。 -
如果用户代理能够以所指示帧率编码 configuration 所表示的媒体,将
smooth
设为true
;否则设为false
。 -
如果用户代理能够以高能效方式编码 configuration 所表示的媒体,将
powerEfficient
设为true
;否则设为false
。 - 返回 info。
2.3.2. 创建 MediaCapabilitiesDecodingInfo
要创建
MediaCapabilitiesDecodingInfo,给定
MediaDecodingConfiguration
configuration,执行以下步骤。将返回一个 MediaCapabilitiesDecodingInfo
:
-
令 info 为一个新的
MediaCapabilitiesDecodingInfo
实例。除非另有说明,后续步骤的读写都应用于 info。 -
将
configuration
设为一个新的MediaDecodingConfiguration
。 对于 configuration 中的每个属性,在configuration
中创建同名同值的新属性。 -
如果
configuration.keySystemConfiguration
存在:-
将
keySystemAccess
设为执行 检查加密解码支持算法(参数为 configuration)的结果。 -
如果
keySystemAccess
为null
,将supported
、smooth
、powerEfficient
都设为false
,并返回 info。 -
否则,将
supported
设为true
,并继续到步骤 6。
-
将
-
否则,执行以下步骤:
-
将
keySystemAccess
设为null
。 -
令 videoSupported 为
unknown
。 -
如果
video
存在于 configuration,执行以下步骤:-
令 videoMimeType 为用 configuration 的
contentType
执行 解析 MIME 类型 的结果。 -
将 videoSupported 设为执行
检查 MIME
类型支持算法(参数为 videoMimeType、configuration 的
type
、 configuration 的colorGamut
和 configuration 的transferFunction
)的结果。
-
令 videoMimeType 为用 configuration 的
-
令 audioSupported 为
unknown
。 -
如果
audio
存在于 configuration,执行以下步骤:-
令 audioMimeType 为用 configuration 的
contentType
执行 解析 MIME 类型 的结果。 -
将 audioSupported 设为执行
检查 MIME
类型支持算法(参数为 audioMimeType 和 configuration 的
type
)的结果。
-
令 audioMimeType 为用 configuration 的
-
如果 videoSupported 或 audioSupported 有一个为
unsupported
,将supported
、smooth
、powerEfficient
都设为false
,并返回 info。
-
将
-
将
supported
设为true
。 -
如果用户代理能以所指示帧率且不丢帧地解码 configuration 所表示的媒体,将
smooth
设为true
;否则设为false
。 -
如果用户代理能以高能效方式解码 configuration 所表示的媒体,将
powerEfficient
设为true
;否则设为false
。 - 返回 info。
2.3.3. 检查 MIME 类型有效性
要检查 MIME 类型有效性,给定 MIME 类型记录 mimeType 和字符串 media,执行以下步骤:
-
若 mimeType 的类型(见 [RFC9110])既不是 media 也不是
application
,返回false
。 -
若 mimeType 的
type
和subtype
联合只允许单一媒体编解码器,且 mimeType 的parameters
非空,返回false
。 -
若 mimeType 的
type
和subtype
联合允许多个媒体编解码器,执行以下步骤:-
若 mimeType 的
parameters
不只包含一个名为 "codecs" 的键,返回false
。为什么只列出单一媒体编解码器很重要?[Issue #235]
-
若
mimeType.parameters["codecs"]
的值不是描述单一媒体编解码器,则返回false
。
-
若 mimeType 的
-
返回
true
。
该逻辑是否适用于
webrtc
?[Issue
#238]
2.3.4. 检查 MIME 类型支持
要检查 MIME 类型支持,给定
MIME 类型记录 mimeType、
MediaEncodingType
或 MediaDecodingType
encodingOrDecodingType,可选的 colorGamut(来自
colorGamut
),
以及可选的 transferFunction
(来自 transferFunction
),
执行以下步骤。若 MIME 类型被用户代理支持则返回 supported
,否则返回
unsupported
:
-
如果 encodingOrDecodingType 是
webrtc
(MediaEncodingType
) 或webrtc
(MediaDecodingType
),且 mimeType 不是 RTP 使用的类型(详见相应 RTP 负载格式规范 [IANA-MEDIA-TYPES] [RFC6838]),则返回unsupported
。编解码器名称通常以 subtype 指定,根据编解码器可能存在零个或多个参数。
-
如果 colorGamut 存在且对 mimeType 无效,则返回
unsupported
。 -
如果 transferFunction 存在且对 mimeType 无效,则返回
unsupported
。用户代理应参考 mimeType 所命名的视频编解码器规范,以确定 colorGamut 和 transferFunction 的有效值。
如何保证此处验证步骤的互操作性?[Issue #245]
-
如果 mimeType 不被用户代理支持,则返回
unsupported
。 -
返回
supported
。
2.3.5. 检查加密解码支持
要检查加密解码支持,给定 MediaDecodingConfiguration
config,其中 keySystemConfiguration
存在,执行以下步骤。根据情况返回
MediaKeySystemAccess
或 null
:
-
如果
keySystem
成员不是用户代理支持的密钥系统之一,则返回null
。字符串比较区分大小写。 -
令 origin 为调用上下文的
Document
的源。 -
令 implementation 为
config.keySystemConfiguration.keySystem
的实现。 -
令 emeConfiguration 为一个新的
MediaKeySystemConfiguration
,并按如下方式初始化:-
将
initDataTypes
属性设为包含config.keySystemConfiguration.initDataType
的序列。 -
将
distinctiveIdentifier
属性设为config.keySystemConfiguration.distinctiveIdentifier
。 -
将
persistentState
属性设为config.keySystemConfiguration.peristentState
。 -
将
sessionTypes
属性设为config.keySystemConfiguration.sessionTypes
。 -
如果
audio
在 config 中存在,将 audioCapabilities 属性设为包含一个MediaKeySystemMediaCapability
的序列,并按如下方式初始化:-
将
contentType
属性设为config.audio.contentType
。 -
如果
config.keySystemConfiguration.audio
存在:-
如果
config.keySystemConfiguration.audio.robustness
存在且不为null
,将robustness
属性设为config.keySystemConfiguration.audio.robustness
。 -
将
encryptionScheme
属性设为config.keySystemConfiguration.audio.encryptionScheme
。
-
如果
-
将
-
如果
video
在 config 中存在,将 videoCapabilities 属性设为包含一个MediaKeySystemMediaCapability
的序列,并按如下方式初始化:-
将
contentType
属性设为config.video.contentType
。 -
如果
config.keySystemConfiguration.video
存在:-
如果
config.keySystemConfiguration.video.robustness
存在且不为null
,将robustness
属性设为config.keySystemConfiguration.video.robustness
。 -
将
encryptionScheme
属性设为config.keySystemConfiguration.video.encryptionScheme
。
-
如果
-
将
-
将
- 令 supported configuration 为对 implementation、emeConfiguration 和 origin 执行 获取支持的配置算法(见 [ENCRYPTED-MEDIA])的结果。
-
如果 supported configuration 为
NotSupported
,返回null
。 -
令 access 为一个新的
MediaKeySystemAccess
对象,并按如下方式初始化:-
将
keySystem
属性设为emeConfiguration.keySystem
。 - 令 configuration 值为 supported configuration。
- 令 cdm implementation 值为 implementation。
-
将
- 返回 access。
2.4. Navigator 和 WorkerNavigator 扩展
[Exposed =Window ]partial interface Navigator { [SameObject ]readonly attribute MediaCapabilities ; };
mediaCapabilities
[Exposed =Worker ]partial interface WorkerNavigator { [SameObject ]readonly attribute MediaCapabilities ; };
mediaCapabilities
2.5. MediaCapabilities 接口
[Exposed =(Window ,Worker )]interface { [
MediaCapabilities NewObject ]Promise <MediaCapabilitiesDecodingInfo >(
decodingInfo MediaDecodingConfiguration ); [
configuration NewObject ]Promise <MediaCapabilitiesEncodingInfo >(
encodingInfo MediaEncodingConfiguration ); };
configuration
2.5.1. MediaCapabilities 任务源
本规范中涉及的任务的 任务源为 media capabilities 任务源。
当某算法排队 MediaCapabilities 任务 T时,用户代理必须使用 排队全局任务方式,将 T 排入 media capabilities 任务源,使用 当前 realm record 的全局对象。
2.5.2. decodingInfo() 方法
decodingInfo()
方法必须按照如下步骤执行:
-
如果 configuration 不是 有效的
MediaDecodingConfiguration,则返回一个新建的
TypeError
拒绝的 Promise。 -
如果
configuration.keySystemConfiguration
存在, 执行以下子步骤:-
如果全局对象类型为
WorkerGlobalScope
, 则返回一个新建的DOMException
,其 name 为InvalidStateError
的拒绝 Promise。 -
如果全局对象的相关设置对象是
非安全上下文,则返回一个新建的
DOMException
,其 name 为SecurityError
的拒绝 Promise。
-
如果全局对象类型为
- 令 p 为一个新的 Promise。
-
并行执行以下步骤:
- 使用 configuration 执行 创建 MediaCapabilitiesDecodingInfo 算法。
- 排队 MediaCapabilities 任务,以其结果解析 p。
- 返回 p。
注意,调用 decodingInfo()
且 keySystemConfiguration
存在时,可能产生用户可见效果,包括请求用户授权。此类调用仅应在作者确实打算使用所提供配置创建并使用
MediaKeys
对象时进行。
2.5.3. encodingInfo() 方法
encodingInfo()
方法必须按照如下步骤执行:
-
如果 configuration 不是 有效的 MediaConfiguration,
则返回一个新建的
TypeError
拒绝的 Promise。 - 令 p 为一个新的 Promise。
-
并行执行以下步骤:
- 使用 configuration 执行 创建 MediaCapabilitiesEncodingInfo 算法。
- 排队 MediaCapabilities 任务,以其结果解析 p。
- 返回 p。
3. 安全与隐私注意事项
本规范没有引入任何安全敏感信息或 API,但确实让一些可用于指纹识别的信息更容易被访问。
3.1. 能力模型
本规范支持 MediaDecodingType
的值 file
、
media-source
或 webrtc
,
以及 MediaEncodingType
的值 record
和 webrtc
。
在 [webrtc] 支持的实时通信中,媒体会在对等方之间传输。虽然网站负责交换协商媒体参数所需的信息,使双方用户代理能够兼容,但它们通常不参与媒体的传输、编码或解码。对于一对一通话,用户代理会协商需要发送和接收的媒体。
在会议场景中,用户代理可以发送媒体给几十甚至上百个接收者。为了提升扩展性,应用会利用外部服务器,如选择性转发单元或会议桥。这些服务器会与参与者协商媒体参数,确保发送者和接收者之间的一致性。这比用户代理之间的协商更具扩展性,否则会需要 N * (N -1) 次协商。通常发送方会用同一种编解码器进行编码,会议服务器不支持转码,因此用户代理不能简单地“选择自己最喜欢的”。
3.2. 解码/编码与指纹识别
解码/编码能力暴露的信息(除了 API 可能会提供更准确和一致的信息外),已经可以通过实验方式发现。预期这些信息会与网页已获得的其它信息高度相关,因为同类设备的解码/编码能力通常非常相似。换句话说,某一年高端设备预计可以解码某种类型视频,而旧设备可能不行。因此,预期该 API 增加的熵不会很显著。
HDR 检测则更微妙。新增 colorGamut
、
transferFunction
和
hdrMetadataType
可能会增加显著的熵。然而,如果 UA 的解码器是软件实现的,因此各设备能力是固定的,则该特性不会有效增加熵。此外,在很多情况下,设备往往归类于大类,类内能力相似,从而降低了有效熵。
另一种设计思路是让网站暴露可用媒体格式,浏览器对照能力进行评估,只返回选定格式。但实际上,这不会带来隐私益处,因为网站可以多次调用 API 获取完整能力集。若对 API 严格限速,可能会影响正常网站行为,比如对多个播放项的预加载。
如果实现希望实现一个防指纹版本的规范,建议伪造一组能力(如解码至 1080p VP9 等),而不是始终返回 yes 或 no,因为后者可能严重影响用户体验。另一种缓解方式是将这些 Web API 限制在顶级浏览上下文。还可以采用隐私预算,超出阈值则限制或阻断 API 调用。此外,浏览器还可以考虑站点是否使用了检测到的能力,对未使用的站点施加更严格的管控。
4. 示例
4.1. 使用 decodingInfo()
查询播放能力
以下示例展示了如何使用 decodingInfo()
在使用 Media Source Extensions
[media-source] 时查询媒体播放能力。
< script> const contentType= 'video/mp4;codecs=avc1.640028' ; const configuration= { type: 'media-source' , video: { contentType: contentType, width: 640 , height: 360 , bitrate: 2000 , framerate: 29.97 } }; navigator. mediaCapabilities. decodingInfo( configuration) . then(( result) => { console. log( 'Decoding of ' + contentType+ ' is' + ( result. supported? '' : ' NOT' ) + ' supported,' + ( result. smooth? '' : ' NOT' ) + ' smooth and' + ( result. powerEfficient? '' : ' NOT' ) + ' power efficient' ); }) . catch (( err) => { console. error( err, ' caused decodingInfo to reject' ); }); < /script>
下列示例展示了如何使用 decodingInfo()
查询 WebRTC 接收能力 [webrtc]。
< script> const contentType= 'video/VP8' ; const configuration= { type: 'webrtc' , video: { contentType: contentType, width: 640 , height: 360 , bitrate: 2000 , framerate: 25 } }; navigator. mediaCapabilities. decodingInfo( configuration) . then(( result) => { console. log( 'Decoding of ' + contentType+ ' is' + ( result. supported? '' : ' NOT' ) + ' supported,' + ( result. smooth? '' : ' NOT' ) + ' smooth and' + ( result. powerEfficient? '' : ' NOT' ) + ' power efficient' ); }) . catch (( err) => { console. error( err, ' caused decodingInfo to reject' ); }); < /script>
< script> const contentType= 'video/H264;level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f' ; const configuration= { type: 'webrtc' , video: { contentType: contentType, width: 640 , height: 360 , bitrate: 2000 , framerate: 25 } }; navigator. mediaCapabilities. decodingInfo( configuration) . then(( result) => { console. log( 'Decoding of ' + contentType+ ' is' + ( result. supported? '' : ' NOT' ) + ' supported,' + ( result. smooth? '' : ' NOT' ) + ' smooth and' + ( result. powerEfficient? '' : ' NOT' ) + ' power efficient' ); }) . catch (( err) => { console. error( err, ' caused decodingInfo to reject' ); }); < /script>
4.2. 使用 encodingInfo()
查询录制能力
< script> const contentType= 'video/VP9' ; const configuration= { type: 'webrtc' , video: { contentType: contentType, width: 640 , height: 480 , bitrate: 10000 , framerate: 29.97 , scalabilityMode: "L3T3_KEY" } }; navigator. mediaCapabilities. encodingInfo( configuration) . then(( result) => { console. log( contentType+ ' is:' + ( result. supported? '' : ' NOT' ) + ' supported,' + ( result. smooth? '' : ' NOT' ) + ' smooth and' + ( result. powerEfficient? '' : ' NOT' ) + ' power efficient' ); }) . catch (( err) => { console. error( err, ' caused encodingInfo to reject' ); }); < /script>
< script> const contentType= 'video/webm;codecs=vp8' ; const configuration= { type: 'record' , video: { contentType: contentType, width: 640 , height: 480 , bitrate: 10000 , framerate: 29.97 } }; navigator. mediaCapabilities. encodingInfo( configuration) . then(( result) => { console. log( contentType+ ' is:' + ( result. supported? '' : ' NOT' ) + ' supported,' + ( result. smooth? '' : ' NOT' ) + ' smooth and' + ( result. powerEfficient? '' : ' NOT' ) + ' power efficient' ); }) . catch (( err) => { console. error( err, ' caused encodingInfo to reject' ); }); < /script>