The #ChromeDevSummit site is live, happening Nov 12-13 in San Francisco, CA
Check it out for details and request an invite. We'll be diving deep into modern web tech & looking ahead to the platform's future.

Audio/Video Updates in Chrome 69

AV1 video decoder

Chromestatus Tracker | Chromium Bug

EME: Querying encryption scheme support

Some platforms or key systems only support CENC mode, while others only support CBCS mode. Still others are able to support both. These two encryption schemes are incompatible, so web developers must be able to make intelligent choices about what content to serve.

To avoid having to determine which platform they’re on to check for “known” encryption scheme support, a new encryptionScheme key is added in MediaKeySystemMediaCapability dictionary to allow websites to specify which encryption scheme could be used in Encrypted Media Extensions (EME).

The new encryptionScheme key can be one of two values:

  • 'cenc' AES-CTR mode full sample and video NAL subsample encryption.
  • 'cbcs' AES-CBC mode partial video NAL pattern encryption.

If not specified, it indicates that any encryption scheme is acceptable. Note that Clear Key always supports the 'cenc' scheme.

The example below shows how to query two configurations with different encryption schemes. In this case, only one will be chosen.

await navigator.requestMediaKeySystemAccess('org.w3.clearkey', [
    {
      label: 'configuration using the "cenc" encryption scheme',
      videoCapabilities: [{
        contentType: 'video/mp4; codecs="avc1.640028"',
        encryptionScheme: 'cenc'
      }],
      audioCapabilities: [{
        contentType: 'audio/mp4; codecs="mp4a.40.2"',
        encryptionScheme: 'cenc'
      }],
      initDataTypes: ['keyids']
    },
    {
      label: 'configuration using the "cbcs" encryption scheme',
      videoCapabilities: [{
        contentType: 'video/mp4; codecs="avc1.640028"',
        encryptionScheme: 'cbcs'
      }],
      audioCapabilities: [{
        contentType: 'audio/mp4; codecs="mp4a.40.2"',
        encryptionScheme: 'cbcs'
      }],
      initDataTypes: ['keyids']
    },
  ]);

In the example below, only one configuration with two different encryption schemes is queried. In that case, Chrome will discard any capabilities object it cannot support, so the accumulated configuration may contain one encryption scheme or both.

await navigator.requestMediaKeySystemAccess('org.w3.clearkey', [{
    videoCapabilities: [
      { // A video capability using the "cenc" encryption scheme
        contentType: 'video/mp4; codecs="avc1.640028"',
        encryptionScheme: 'cenc'
      },
      { // A video capability using the "cbcs" encryption scheme
        contentType: 'video/mp4; codecs="avc1.640028"',
        encryptionScheme: 'cbcs'
      },
    ],
    audioCapabilities: [
      { // An audio capability using the "cenc" encryption scheme
        contentType: 'audio/mp4; codecs="mp4a.40.2"',
        encryptionScheme: 'cenc'
      },
      { // An audio capability using the "cbcs" encryption scheme
        contentType: 'audio/mp4; codecs="mp4a.40.2"',
        encryptionScheme: 'cbcs'
      },
    ],
    initDataTypes: ['keyids']
  }]);

Intent to Implement | Chromestatus Tracker | Chromium Bug

EME: HDCP policy check

Nowadays HDCP is a common policy requirement for streaming high resolutions of protected content. And web developers who want to enforce an HDCP policy must either wait for the license exchange to complete or start streaming content at a low resolution. This, is a sad situation that the HDCP Policy Check API aims to solve.

This proposed API allows web developers to query whether a certain HDCP policy can be enforced so that playback can be started at the optimum resolution for the best user experience. It consists of a simple method to query the status of a hypothetical key associated with an HDCP policy, without the need to create a MediaKeySession or fetch a real license. It does not require MediaKeys to be attached to any audio or video elements either.

The HDCP Policy Check API works simply by calling mediaKeys.getStatusForPolicy() with an object that has a minHdcpVersion key and a valid value. If HDCP is available at the specified version, the returned promise resolves with a MediaKeyStatus of 'usable'. Otherwise, the promise resolves with other error values of MediaKeyStatus such as 'output-restricted' or 'output-downscaled'. If the key system does not support HDCP Policy Check at all (e.g. Clear Key System), the promise rejects.

In a nutshell, here’s how the API works for now. Check out the official sample to try out all versions of HDCP.

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

navigator.requestMediaKeySystemAccess('com.widevine.alpha', config)
.then(mediaKeySystemAccess => mediaKeySystemAccess.createMediaKeys())
.then(mediaKeys => {

  // Get status for HDCP 2.2
  return mediaKeys.getStatusForPolicy({ minHdcpVersion: 'hdcp-2.2' })
  .then(status => {
    if (status !== 'usable')
      return Promise.reject(status);

    console.log('HDCP 2.2 can be enforced.');
    // TODO: Fetch high resolution protected content...
  });
})
.catch(error => {
  // TODO: Fallback to fetch license or stream low-resolution content...
});

Available for Origin Trials

To get feedback from web developers, the HDCP Policy Check API is available as an Origin Trial in Chrome 69 for Desktop (Chrome OS, Linux, Mac, and Windows). You will need to request a token, so that the feature is automatically enabled for your origin for a limited period of time, without the need to enable the experimental "Web Platform Features" flag at chrome://flags/#enable-experimental-web-platform-features.

Intent to Experiment | Chromestatus Tracker | Chromium Bug

MSE PTS/DTS compliance

Buffered ranges and duration values are now reported by Presentation Time Stamp (PTS) intervals, rather than by Decode Time Stamp (DTS) intervals in Media Source Extensions (MSE).

When MSE was new, Chrome’s implementation was tested against WebM and MP3, some media stream formats where there was no distinction between PTS and DTS. And it was working fine until ISO BMFF (aka MP4) was added. This container frequently contains out-of-order presentation versus decode time streams (for codecs like H.264 for example) causing DTS and PTS to differ. That caused Chrome to report (usually just slightly) different buffered ranges and duration values than expected. This new behavior will roll out gradually in Chrome 69 and make its MSE implementation compliant with the MSE specification.

PTS/DTS
Figure 2. PTS/DTS

This change affects MediaSource.duration (and consequently HTMLMediaElement.duration), SourceBuffer.buffered (and consequently HTMLMediaElement.buffered), and SourceBuffer.remove(start, end).

If you’re not sure which method is used to report buffered ranges and duration values, you can go to the internal chrome://media-internals page and search for "ChunkDemuxer: buffering by PTS" or "ChunkDemuxer: buffering by DTS" in the logs.

Intent to Implement | Chromium Bug

Handling of media view intents on Android Go

Android Go is a lightweight version of Android designed for entry-level smartphones. To that end, it does not necessarily ship with some media-viewing applications, so if a user tries to open a downloaded video for instance, they won’t have any applications to handle that intent.

To fix this, Chrome 69 on Android Go now listens for media-viewing intents so users can view downloaded audio, videos, and images. In other words, it takes the place of the missing viewing applications.

Media intent handler
Figure 3. Media intent handler

Note that this Chrome feature is enabled on all Android devices running Android O and onwards with 1 GB of RAM or less.

Chromium Bug

Removal of “stalled” events for media elements using MSE

A "stalled" event is raised on a media element if downloading media data has failed to progress for about 3 seconds. When using Media Source Extensions (MSE), the web app manages the download and the media element is not aware of its progress. This caused Chrome to raise "stalled" events at inappropriate times whenever the website has not appended new media data chunks with SourceBuffer.appendBuffer() in the last 3 seconds.

As websites may decide to append large chunks of data at a low frequency, this is not a useful signal about buffering health. Removing "stalled" events for media elements using MSE clears up confusion and brings Chrome more in line with the MSE specification. Note that media elements that don't use MSE will continue to raise "stalled" events as they do today.

Intent to Deprecate and Remove | Chromestatus Tracker | Chromium Bug

rss_feed Subscribe to our RSS or Atom feed and get the latest updates in your favorite feed reader!