MediaCapabilities: decodingInfo() 方法

MediaCapabilities 接口的 decodingInfo() 方法返回一个 Promise,该 Promise 会使用有关用户代理如何解码/显示具有给定配置的媒体的信息来完成。

已解析的对象包含三个布尔属性 supportedsmoothpowerefficient,它们指示是否支持解码所描述的媒体,以及如果是,解码是否会平滑且节能。

该方法还可以用于测试用户代理对使用密钥系统解码媒体的功能,但前提是在主线程和安全上下文中调用。如果在 configuration.keySystemConfiguration 属性中传递的配置受支持用于解码数据,则已解析的 Promise 还将包含一个 MediaKeySystemAccess 对象,该对象可用于创建 MediaKeys 对象以设置加密播放。

注意: 使用此属性调用 decodingInfo() 可能会导致用户可见的效果,例如请求访问一个或多个系统资源的权限。因此,此函数应仅在应用程序准备好使用提供的配置创建和使用 MediaKeys 对象时调用。

语法

js
decodingInfo(configuration)

参数

configuration

一个对象,其中包含一个 type 属性,或者 一个 videoaudio 属性,其中包含适当类型的配置,以及可选的 keySystemConfiguration(在解码使用密钥系统加密的媒体时)。

type

正在测试的媒体类型。它可以取以下三个值之一

file

表示旨在用于普通文件播放的配置。

media-source

表示旨在用于 MediaSource 播放的配置。

webrtc

表示旨在使用 RTCPeerConnection 接收的配置(当设置了 keySystemConfiguration 时不允许)。

video

视频媒体源的配置对象。它具有以下属性

contentType

包含有效视频 MIME 类型的字符串,以及(可选)codecs 参数

width

视频的宽度。

height

视频的高度。

bitrate

用于编码视频文件一秒钟的位数。

framerate

构成视频播放一秒钟的帧数。

audio

音频媒体源的配置对象。它具有以下属性

contentType

包含有效音频 MIME 类型的字符串,以及(可选)codecs 参数

channels

音频轨道使用的声道数。

bitrate

用于编码音频文件一秒钟的位数。

samplerate

构成音频文件一秒钟的音频样本数。

keySystemConfiguration 可选

指定加密媒体的密钥系统配置的对象。

注意: Navigator.requestMediaKeySystemAccess() 在其 supportedConfigurations 参数中采用一些相同数据类型的数组。

如果指定,则 type 必须为 media-sourcefile(而不是 webrtc)。它具有以下属性

keySystem

标识媒体密钥系统的字符串。例如 org.w3.clearkeycom.widevine.alpha

initDataType 可选

一个字符串,指示初始化数据格式的数据类型名称,例如 "cenc""keyids""webm"。允许的名称在 加密媒体扩展初始化数据格式注册表 中定义。

distinctiveIdentifier 可选

一个字符串,指示实现是否可以使用“独特标识符”(或独特永久标识符)来执行与从该配置创建的任何对象关联的任何操作。允许的值为

required

返回的对象必须支持此功能。

optional

返回的对象可能支持此功能。这是默认值

not-allowed

返回的对象不得支持或使用此功能。

persistentState 可选

一个字符串,指示返回的对象是否必须能够持久化会话数据或任何其他类型的状态。允许的值为

required

返回的对象必须支持此功能。

optional

返回的对象可能支持此功能。这是默认值

not-allowed

返回的对象不得支持或使用此功能。当不允许持久化状态时,只能创建“临时”会话。

sessionTypes 可选

一个字符串数组,指示必须支持的会话类型。允许的值包括

temporary

一个会话,其中许可证、密钥和与会话相关的记录或数据不会持久化。应用程序不需要管理此类存储。实现必须支持此选项,它是默认值。

persistent-license

一个会话,其中许可证(以及可能与会话相关的其他数据)将持久化。即使许可证被销毁,许可证和关联密钥的记录也会持久化,从而证明许可证及其包含的密钥不再可供客户端使用。

audio 可选

与上面 audio 配置 关联的音频密钥系统轨道配置。如果设置,则 audio 配置 也必须设置。

encryptionScheme

与内容类型关联的加密方案,例如 cenccbcscbcs-1-9。此值应由应用程序设置(它默认为 null,表示可以采用任何加密方案)。

robustness

与内容类型关联的鲁棒性级别。空字符串表示接受任何解密和解码内容类型的能力。

video 可选

与上面 video 配置 关联的视频密钥系统轨道配置。如果设置,则 video 配置 也必须设置。

encryptionScheme

与内容类型关联的加密方案,例如 cenccbcscbcs-1-9。此值应由应用程序设置(它默认为 null,表示可以采用任何加密方案)。

robustness

与内容类型关联的鲁棒性级别。空字符串表示接受任何解密和解码内容类型的能力。

返回值

一个 Promise,使用包含以下属性的对象完成

supported

如果媒体内容可以解码,则为 true。否则为 false

smooth

如果媒体的播放可以在配置指定的帧速率下进行播放,而无需丢弃帧,则为 true。否则为 false

powerEfficient

如果媒体的播放将是节能的,则为 true。否则为 false

keySystemAccess

一个 MediaKeySystemAccess,可用于创建 MediaKeys 对象以设置加密播放,或者如果使用提供的配置不支持解码,则为 null

浏览器会将支持的媒体配置报告为 smoothpowerEfficient,直到记录了有关该设备的统计信息。所有受支持的音频编解码器都会将 powerEfficient 报告为 true。

异常

TypeError

如果传递给 decodingInfo() 方法的 configuration 无效,则抛出此异常,原因可能是类型不是 video 或 audio、contentType 不是有效的编解码器 MIME 类型、媒体解码配置不是 type(file、media-source 或 webrtc)的有效值,或者传递给该方法的媒体配置中的任何其他错误,包括省略任何值。

InvalidStateError DOMException

configuration.keySystemConfiguration 定义时,该方法在工作线程中被调用。

SecurityError DOMException

该方法在安全上下文之外被调用,并且定义了 configuration.keySystemConfiguration

用法说明

与 Navigator.requestMediaKeySystemAccess() 的比较

decodingInfo()Navigator.requestMediaKeySystemAccess() 方法(加密媒体扩展 API)反映了选择加密媒体解码配置的根本不同方法。

Navigator.requestMediaKeySystemAccess() 的配置参数采用可能的配置数组,并允许系统选择它认为合适的配置。

相比之下,decodingInfo() 每次只采用一个配置。预期调用者会多次执行 decodingInfo(),从最优先的配置开始,并在找到满足应用程序要求(平滑、节能或两者兼而有之)的配置后停止。换句话说,选择决策权下放给了调用者。

示例

获取未加密媒体文件的解码信息

此示例显示如何为音频文件创建媒体配置,然后在 MediaCapabilities.decodingInfo() 中使用它。

js
//Create media configuration to be tested
const audioConfig = {
  type: "file", // or 'media-source' or 'webrtc'
  audio: {
    contentType: "audio/ogg; codecs=vorbis", // valid content type
    channels: 2, // audio channels used by the track
    bitrate: 132700, // number of bits used to encode 1s of audio
    samplerate: 5200, // number of audio samples making up that 1s.
  },
};

// check support and performance
navigator.mediaCapabilities.decodingInfo(audioConfig).then((result) => {
  if (result.supported) {
    log(
      `The audio configuration is supported${result.smooth ? ", smooth" : ", not smooth"}${result.powerEfficient ? ", power efficient" : ", not power efficient"}.`,
    );
  } else {
    log("The audio configuration is not supported");
  }
});

类似地,以下代码显示了视频文件的配置。

js
const videoConfig = {
  type: "file",
  video: {
    contentType: "video/webm;codecs=vp8", // valid content type
    width: 800, // width of the video
    height: 600, // height of the video
    bitrate: 10000, // number of bits used to encode 1s of video
    framerate: 30, // number of frames making up that 1s.
  },
};

// check support and performance
navigator.mediaCapabilities.decodingInfo(audioConfig).then((result) => {
  if (result.supported) {
    log(
      `The video configuration is supported${result.smooth ? ", smooth" : ", not smooth"}${result.powerEfficient ? ", power efficient" : ", not power efficient"}.`,
    );
  } else {
    log("The video configuration is not supported");
  }
});

获取加密媒体的解码信息

此示例演示了如何使用 decodingInfo() 为加密内容选择媒体配置。

与前面的示例一样,我们定义了一个媒体配置,但这次我们使用 typemedia-source(而不是 file),并指定音频和视频内容。我们还指定了一个简单的 keySystemConfiguration

js
const encryptedMediaConfig = {
  type: "media-source", // or 'file'
  audio: {
    contentType: "audio/webm; codecs=opus",
    channels: 2, // audio channels used by the track
    bitrate: 132700, // number of bits used to encode 1s of audio
    samplerate: 48000, // number of audio samples making up that 1s.
  },
  video: {
    contentType: 'video/webm; codecs="vp09.00.10.08"',
    width: 800, // width of the video
    height: 600, // height of the video
    bitrate: 10000, // number of bits used to encode 1s of video
    framerate: 30, // number of frames making up that 1s.
  },
  keySystemConfiguration: {
    keySystem: "org.w3.clearkey",
    initDataType: "webm",
    distinctiveIdentifier: "required",
  },
};

在前面的示例中,我们使用了 promise 链式调用 来等待结果。在这里,我们选择使用 asyncawait 来等待结果,然后记录它。

js
getDecodingInfo(encryptedMediaConfig);

async function getDecodingInfo(mediaConfig) {
  const result = await navigator.mediaCapabilities.decodingInfo(mediaConfig);
  console.log(result);
  if (!result.supported) {
    log("This encrypted media configuration is not supported.");
    return;
  }

  // keySystemAccess is returned if decoding encrypted media is supported
  // This can be used to decrypt and playback the media
  if (!result.keySystemAccess) {
    log("Encrypted media support is not available.");
    return;
  }

  log(
    `The encrypted media configuration is supported${result.smooth ? ", smooth" : ", not smooth"}${result.powerEfficient ? ", power efficient" : ", not power efficient"}.`,
  );
}

日志输出如下所示。

迭代加密媒体的解码信息

前面的示例演示了如何使用 decodingInfo() 获取单个配置的信息。实际上,该方法通常会以迭代的方式调用,并使用多个配置,选择第一个满足应用程序对流畅播放或能耗要求的支持的配置。工作原理如下所示。

假设我们已经有一个名为 orderedMediaConfigs 的媒体配置 Array,我们已经按最想要到最不想要的方式排序,我们可以使用 Array.prototype.map() 为每个配置调用 decodingInfo(),并获得一个包含所有返回的 Promise 对象的数组。

js
const capabilitiesPromises = orderedMediaConfigs.map((mediaConfig) =>
  navigator.mediaCapabilities.decodingInfo(mediaConfig),
);

然后,我们使用 for await...of 循环 迭代这些 promise,并在它们解析时进行处理。在循环中,我们将最后一个支持的配置存储到 nonSmoothConfig 中,并在找到流畅的配置后立即退出循环,将其设置为我们的 bestConfig

js
// Assume this app wants a supported && smooth config.
let bestConfig = null;
let nonSmoothConfig = null;
for await (const mediaCapabilityInfo of capabilitiesPromises) {
  if (!mediaCapabilityInfo.supported) continue;

  if (!mediaCapabilityInfo.smooth) {
    nonSmoothConfig = mediaCapabilityInfo;
    continue;
  }

  bestConfig = mediaCapabilityInfo;
  break;
}

如果我们在循环中找到一个流畅且支持的配置 (bestConfig),我们将使用它来 创建媒体密钥 并解码媒体。如果没有发现任何流畅的配置,我们可以使用 nonSmoothConfig 来解码媒体。这将是最后一个找到的支持的配置,由于我们对原始 orderedMediaConfigs 的排序方式,它应该是帧率最低的配置。

js
let keys = null;
if (bestConfig) {
  keys = await bestConfig.keySystemAccess.createMediaKeys();
  // ... use keys to decode media using best config
} else if (nonSmoothConfig) {
  console.log(
    "No smooth configs found. Using lowest resolution configuration!",
  );
  keys = await nonSmoothConfig.keySystemAccess.createMediaKeys();
  // ... use keys to decode media using lowest framerate config
} else {
  console.log("No supported configs!");
  // Fail!
}

如果没有支持的配置,我们别无选择,只能失败并通知用户。

规范

规范
媒体功能
# ref-for-dom-mediacapabilities-decodinginfo

浏览器兼容性

BCD 表只在浏览器中加载

另请参阅