Tamius Han
Tamius Han

Reputation: 239

How to detect whether a HTML video is DRM-protected with javascript in Chrome?

Quick background: I am writing a browser extension that manipulates video while it's being played in a browser. The script itself is supposed to be as general purpose as it gets, and it should run on any site that has a video on it.

My video manipulations rely on being able to manipulate pixel data from the video. The HTML5-blesed way to do get video pixels into something you can work with in javascript is canvas2dContext.drawImage() function to draw the current video frame to a canvas, and context.getImageData() to get said data.

The current code boils down to (I am simplifying things a fair bit):


let video = document.findElementsByTagName('video')[0];
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');

handleVideoFrame() {
  context.drawImage(video, 0, 0, canvas.width, canvas.height);
  let data = context.getImageData(0,0,canvas.width, canvas.height);

  processData(data);
}

processData(data) {
  // a lot of heavy calculations going on here
}

window.requestAnimationFrame(handleVideoFrame);

The Problem: DRM

This works well and good, until you try to do this on Netflix, Disney+ or a different site of the same caliber. Those sites use DRM, and if there's DRM on that video, context.drawImage() will not work. Note that I do not wish to capture the actual frames of DRM protected videos, but I want to know whether the DRM is there.

In Firefox, this is not a big deal, because if you try to call context.drawImage() on a DRM-protected video, you will get an exception. You can then catch that exception, don't run the heavy processData(), alert the user to the fact that your script won't be working on that site because of DRM, and then shut the entire thing down.

In Chrome (and other Chromium reskins for that matter), on the other hand, context.drawImage() will not fail. Instead, context.drawImage() will draw a 100% opaque black square without throwing an exception, and this is a problem because:

Solutions that I've tried

¹ Unless the video hasn't been loaded yet, in that case it's transparent.

Solutions that I wish to avoid

Upvotes: 1

Views: 3309

Answers (1)

Kaiido
Kaiido

Reputation: 136707

You can simply look at the HTMLMediaElement's mediaKeys property, if it is set, the video is DRM protected:

const isDRMProtected = (elem) => elem.mediaKeys instanceof MediaKeys;

Upvotes: 3

Related Questions