Javascript Encrypted Media Extensions API (HTML5) Is Now Official W3C Recommendation

HTML5 Encrypted Media Extensions (EME) an API used to play digital Rights Management (DRM) content (encrypted video or audio) on web applications.

It is in draft state from last few years and today its officially approved by W3C. (58.4 percent of W3C members voted in support  and 30.8 percent to opposed, with 10.8 percent abstaining).

But it triggered controversy EFF resigned from W3C after this decision.

 

Why HTML5 based DRM?

 

The existing DRM schemes such as Google Widevine, Adobe PrimeTime, and Microsoft PlayReady are working very well, and very effective in protecting content but they are proprietary and comes with couple of restrictions.

But for the past few years, JavaScript is becoming very powerful and playing a key role in web development.

Now with the use of Html5 Media Source Extensions, and Encrypted Media Extensions Apis customers can define their own set of rules and they can easily change between schemes.

Apple developed it’s own DRM scheme fairplay using EME and MSE which protects content served by AppleTV.

 

Encrypted media extension API:

 

It’s an extension to Htmlmediaelement so its called extension API.

When the browser tries to play encrypted content it recognizes and fires an encrypted event with metadata (initData) obtained from the content.

If no MediaKeys object has been attached with the media element, then it first selects an available Key System by using navigator.requestMediaKeySystemAccess()  then create a MediaKeys object using MediaKeySystemAccessobject.

And after that we have to assign the key to HtmlMediaelement (audio or video) using

 var sysaccessobject= navigator.requestMediaKeySystemAccess('org.w3.clearkey', [
        { initDataTypes: ['webm'],
          videoCapabilities: [{ contentType: 'video/webm; codecs="vp8"' }] }
      ]);
var mediaKey=sysaccessobject.createMediaKeys();
video.setMediaKeys(mediaKey);
var te = new TextEncoder();
//using plain text
var initData = te.encode( '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}');
var keySession = mediaKey.createSession();
keySession.addEventListener("message", handleMessage, false);
//Returns new Key
//return keySession.generateRequest('keyids', initData);
function handleMessage(event) {
    var keySession = event.target;
    var te = new TextEncoder();
    var license = te.encode('{"keys":[{"kty":"oct","k":"tQ0bJVWb6b0KPL6KtZIy_A","kid":"LwVHf8JLtPrv2GUXFW2v_A"}],"type":"temporary"}');
    keySession.update(license).catch(
      console.error.bind(console, 'update() failed')
    );
  }

Now by calling, createSession() on the created MediaKey will create a MediaKeySession object, which represents the lifetime of a license and its key(s).

MediaKeySession call generateRequest() method to get license key from license server

And after receiving the response from the server MediaKeySession object updates the license key using update() method.

And it its valid media playback resumes.

This example I took it from W3C documentation 

ExtensionMediaAPI

ExtensionMediaAPI

 

You can read more about Encrypted media extension API in w3c specification.