MediaCapabilities: decodingInfo() 方法

Baseline 廣泛可用 *

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

* 此特性的某些部分可能存在不同級別的支援。

注意:此功能在 Web Workers 中可用。

MediaCapabilities 介面的 decodingInfo() 方法返回一個 Promise,該 Promise 以關於使用者代理如何解碼/顯示具有給定配置的媒體的資訊來 fulfilled。

解析後的物件包含三個布林屬性 supportedsmoothpowerefficient,它們指示是否支援解碼描述的媒體,如果支援,則指示解碼是否會流暢且省電。

該方法還可以用於測試使用者代理解碼使用金鑰系統編碼的媒體的能力,但前提是在主執行緒和安全上下文中呼叫。如果 configuration.keySystemConfiguration 屬性中傳遞的配置支援解碼資料,則解析後的 Promise 還包括一個 MediaKeySystemAccess 物件,該物件可用於建立 MediaKeys 物件以設定加密播放。

注意:使用此屬性呼叫 decodingInfo() 可能會導致使用者可見的效果,例如請求訪問一個或多個系統資源的許可權。因此,應僅在應用程式準備好使用提供的配置建立和使用 MediaKeys 物件時呼叫此函式。

語法

js
decodingInfo(configuration)

引數

configuration

一個物件,其中包含一個 type 屬性,並且一個 videoaudio 屬性,其中包含相應型別的配置,以及一個可選的 keySystemConfiguration,用於解碼使用金鑰系統加密的媒體。

type

正在測試的媒體型別。這接受以下三種值之一:

檔案

表示用於普通檔案播放的配置。

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"。允許的名稱定義在 Encrypted Media Extensions Initialization Data Format Registry 中。

distinctiveIdentifier 可選

一個字串,指示實現是否可能為從該配置建立的任何物件的任何操作使用“獨特識別符號”(或獨特永久識別符號)。允許的值為:

required

返回的物件必須支援此功能。

可選

返回的物件可能支援此功能。這是預設值。

not-allowed

返回的物件不得支援或使用此功能。

persistentState 可選

一個字串,指示返回的物件是否能夠持久化會話資料或任何其他型別的狀態。允許的值為:

required

返回的物件必須支援此功能。

可選

返回的物件可能支援此功能。這是預設值。

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,以一個包含以下屬性的物件 fulfilled:

supported

如果媒體內容根本無法解碼,則為 true。否則為 false

平滑

如果在不丟幀的情況下可以以配置中指定的幀率播放媒體,則為 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 時,該方法在 worker 中呼叫。

SecurityError DOMException

該方法在安全上下文之外呼叫,並且定義了 configuration.keySystemConfiguration

用法說明

與 Navigator.requestMediaKeySystemAccess() 的比較

decodingInfo() 方法和 Encrypted Media Extensions APINavigator.requestMediaKeySystemAccess() 方法反映了選擇加密媒體解碼配置的基本不同的方法。

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(videoConfig).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() 為加密內容選擇媒體配置。

與前面的示例一樣,我們定義了一個媒體配置,但這次我們使用了 media-source(而不是 file)的 type,並指定了音訊和影片內容。我們還指定了一個簡單的 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.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!
}

如果沒有支援的配置,我們將別無選擇,只能失敗並通知使用者。

規範

規範
Media Capabilities
# dom-mediacapabilities-decodinginfo

瀏覽器相容性

另見