Chrome 63/64 中的媒体更新

François Beaufort
François Beaufort

Media Capabilities - Decoding Info API

目前,Web 开发者依赖 isTypeSupported()canPlayType() 来大致了解某些媒体是否可以解码。不过,真正的问题应该是:“它在这种设备上的表现如何?”

这正是我们提出的 Media Capabilities 想要解决的问题之一:提供一个 API,以便根据编解码器、配置文件、分辨率、比特率等信息向浏览器查询设备的解码能力。该 API 会根据浏览器记录的之前的播放统计信息,公开播放是否应流畅、节能等信息。

简而言之,目前 Decoding Info API 的运作方式如下。请查看官方示例

const mediaConfig = {
  type: 'media-source', // or 'file'
  audio: {
    contentType: 'audio/webm; codecs=opus',
    channels: '2', // audio channels used by the track
    bitrate: 132266, // number of bits used to encode a second of audio
    samplerate: 48000 // number of samples of audio carried per second
  },
  video: {
    contentType: 'video/webm; codecs="vp09.00.10.08"',
    width: 1920,
    height: 1080,
    bitrate: 2646242, // number of bits used to encode a second of video
    framerate: '25' // number of frames used in one second
  }
};

navigator.mediaCapabilities.decodingInfo(mediaConfig).then(result => {
  console.log('This configuration is' +
      (result.supported ? '' : ' NOT') + ' supported,' +
      (result.smooth ? '' : ' NOT') + ' smooth and' +
      (result.powerEfficient ? '' : ' NOT') + ' power efficient.');
});

您可以尝试不同的媒体配置,直到找到最佳配置(smoothpowerEfficient),然后使用该配置播放适当的媒体流。顺便提一下,Chrome 的当前实现基于之前记录的播放信息。当丢帧百分比低于 10% 时,它将 smooth 定义为 true;当超过 50% 的帧由硬件解码时,powerEfficient 为 true。小帧始终被视为能效高。

建议您使用类似于以下代码段的内容来检测可用性,并针对不支持此 API 的浏览器回退到您当前的实现。

function isMediaConfigSupported(mediaConfig) {

  const promise = new Promise((resolve, reject) => {
    if (!('mediaCapabilities' in navigator)) {
      return reject('MediaCapabilities API not available');
    }
    if (!('decodingInfo' in navigator.mediaCapabilities)) {
      return reject('Decoding Info not available');
    }
    return resolve(navigator.mediaCapabilities.decodingInfo(mediaConfig));
  });

  return promise.catch(_ => {
    let fallbackResult = {
      supported: false,
      smooth: false, // always false
      powerEfficient: false // always false
    };
    if ('video' in mediaConfig) {
      fallbackResult.supported = MediaSource.isTypeSupported(mediaConfig.video.contentType);
      if (!fallbackResult.supported) {
        return fallbackResult;
      }
    }
    if ('audio' in mediaConfig) {
      fallbackResult.supported = MediaSource.isTypeSupported(mediaConfig.audio.contentType);
    }
    return fallbackResult;
  });
}

适用于起源试验

为了从实际使用 Decoding Info API(Media Capabilities 的一部分)的开发者那里获得尽可能多的反馈,我们之前在 Chrome 64 中以源试用形式添加了此功能。

该试行计划已于 2018 年 4 月成功结束。

Intent to Experiment | Intent to Ship | Chromestatus Tracker | Chromium Bug

在 Windows 10 上播放 HDR 视频

高动态范围 (HDR) 视频的对比度更高,可呈现精确、细致的阴影和令人惊艳的高光,清晰度比以往更高。此外,支持广色域意味着颜色更鲜艳。

模拟 SDR 与 HDR 的对比效果(如需观看真实 HDR 内容,需要使用 HDR 显示屏)
模拟的 SDR 与 HDR 对比(如需查看真实的 HDR,需要 HDR 显示屏)

由于适用于 Windows 10 秋季创作者更新的 Chrome 现在支持 VP9 Profile 2 10 位播放,因此当 Windows 10 处于 HDR 模式时,Chrome 还支持 HDR 视频播放。从技术层面来说,Chrome 64 现在支持 scRGB 色彩配置文件,这反过来又允许媒体以 HDR 格式播放。

您可以尝试在 YouTube 上观看以 4K(超高清)HDR 格式观看世界,并查看 YouTube 播放器的画质设置,确认是否以 HDR 格式播放。

支持 HDR 的 YouTube 播放器画质设置
支持 HDR 的 YouTube 播放器画质设置

目前,您只需安装 Windows 10 秋季创作者更新、具有 HDR 功能的显卡和显示屏(例如 NVIDIA 10 系列显卡、LG HDR 电视或显示器),然后在 Windows 显示设置中开启 HDR 模式即可。

Web 开发者可以使用最新的 color-gamut media query 检测输出设备支持的大致色域,并使用 screen.colorDepth 检测在屏幕上显示颜色所用的位数。例如,下面是使用这些方法检测是否支持 VP9 HDR 的一种方法:

// Detect if display is in HDR mode and if browser supports VP9 HDR.
function canPlayVp9Hdr() {

  // TODO: Adjust VP9 codec string based on your video encoding properties.
  return (window.matchMedia('(color-gamut: p3)').matches &&
      screen.colorDepth >= 48 &&
      MediaSource.isTypeSupported('video/webm; codecs="vp09.02.10.10.01.09.16.09.01"'))
}

在上述示例中,传递给 isTypeSupported()采用 Profile 2 的 VP9 编解码器字符串需要根据您的视频编码属性进行更新。

请注意,目前还无法在 CSS画布、图片和受保护的内容中定义 HDR 颜色。Chrome 团队正在努力解决此问题。敬请期待!

适用于 Windows 和 Mac 的永久性许可

Encrypted Media Extensions (EME) 中的永久许可意味着许可可以在设备上保留,以便应用可以将许可加载到内存中,而无需向服务器发送其他许可请求。这就是 EME 中支持离线播放的方式。

到目前为止,ChromeOS 和 Android 是唯一支持永久许可的平台。现在情况已经不同了。现在,Windows 和 Mac 上的 Chrome 64 也支持在设备离线时通过 EME 播放受保护的内容。

const config = [{
  sessionTypes: ['persistent-license'],
  videoCapabilities: [{
    contentType: 'video/webm; codecs="vp09.00.10.08"',
    robustness: 'SW_SECURE_DECODE' // Widevine L3
  }]
}];

navigator.requestMediaKeySystemAccess('com.widevine.alpha', config)
.then(access => {
  // User will be able to watch encrypted content while being offline when
  // license is stored locally on device and loaded later.
})
.catch(error => {
  // Persistent licenses are not supported on this platform yet.
});

您可以自行试用永久性许可,只需查看 Media PWA 示例并按照以下步骤操作即可:

  1. 前往 https://biograf-155113.appspot.com/ttt/episode-2/
  2. 点击“设为可离线使用”,然后等待视频下载。
  3. 关闭互联网连接。
  4. 点击“播放”按钮,畅享视频!

媒体预加载默认为“metadata”

为了与其他浏览器的实现保持一致,Chrome 桌面版现在将 <video><audio> 元素的默认预加载值设置为 "metadata",以减少带宽和资源使用。从 Chrome 64 开始,这种新行为仅适用于未设置预加载值的情况。请注意,当 MediaSource 附加到媒体元素时,系统会舍弃预加载属性的提示,因为网站会处理自己的预加载。

换句话说,<video> 预加载值现在为 "metadata",而 <video preload="auto"> 预加载值保持为 "auto"。不妨试试官方示例

发货意向 | Chromestatus 跟踪器 | Chromium bug

不受支持的 playbackRate 会引发异常

HTML 规范变更后,如果媒体元素的 playbackRate 设置为 Chrome 不支持的值(例如负值),Chrome 63 中会抛出 "NotSupportedError" DOMException

const audio = document.querySelector('audio');
try {
  audio.playbackRate = -1;
} catch(error) {
  console.log(error.message); // Failed to set the playbackRate property
}

顺便提一下,当 playbackRate 为负、小于 0.0625 或大于 16 时,Chrome 的当前实现会引发此异常。请试用官方示例,了解其运作方式。

发货意向 | Chromestatus 跟踪器 | Chromium bug

后台视频轨道优化

Chrome 团队一直在努力寻找新的方法来延长电池续航时间,Chrome 63 也不例外。

如果视频不含任何音轨,则在 Chrome 桌面版(Windows、Mac、Linux 和 ChromeOS)中在后台(例如在不可见的标签页中)播放时,视频将自动暂停。这是继之前仅适用于 Chrome 62 中的 MSE 视频的类似更改之后的后续措施。

Chromium bug

移除了极端播放速率的静音功能

在 Chrome 64 之前,当 playbackRate 低于 0.5 或高于 4 时,系统会静音,因为音质会严重下降。由于 Chrome 已改用波形相似性叠加添加 (WSOLA) 方法来降低画质,因此无需再将音频静音。这意味着,您现在可以超慢或超快地播放音频。

Chromium bug