[英]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.将视频像素转换为您可以在 javascript 中使用的 HTML5 的方法是
canvas2dContext.drawImage()
context.getImageData()
将当前视频帧绘制到 ZFCC790C72A86190DE1B549D0DDDC6F5 和上下文中。
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);
This works well and good, until you try to do this on Netflix, Disney+ or a different site of the same caliber.这很好用,直到您尝试在 Netflix、Disney+ 或相同口径的不同网站上执行此操作。 Those sites use DRM, and if there's DRM on that video,
context.drawImage()
will not work.这些网站使用 DRM,如果该视频上有 DRM,则
context.drawImage()
将不起作用。 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.请注意,我不希望捕获受 DRM 保护的视频的实际帧,但我想知道 DRM 是否存在。
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 .在 Firefox 中,这没什么大不了的,因为如果你尝试在受 DRM 保护的视频上调用
context.drawImage()
, 你会得到一个异常。 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.然后,您可以捕获该异常,不要运行繁重的
processData()
,提醒用户您的脚本由于 DRM 而无法在该站点上运行,然后关闭整个程序。
In Chrome (and other Chromium reskins for that matter), on the other hand, context.drawImage()
will not fail.另一方面,在 Chrome(以及其他 Chromium reskins)中,
context.drawImage()
不会失败。 Instead, context.drawImage()
will draw a 100% opaque black square without throwing an exception, and this is a problem because:相反,
context.drawImage()
将绘制一个 100% 不透明的黑色方块而不会引发异常,这是一个问题,因为:
processData()
if it is, you're still doing drawImage()
calls that you don't need to be doingprocessData()
如果是,但您仍在执行您不需要执行的drawImage()
调用context.getImageData()
returns an object that contains an array with RGBA values for each pixel. context.getImageData()
返回一个 object,其中包含每个像素的 RGBA 值的数组。 I initially hoped that I could determine whether the video was being DRM-protected by looking at alpha values.drawImage()
is always¹ completely opaque, which means that this is a dead end.drawImage()
绘制的帧总是¹完全不透明,这意味着这是一个死胡同。 ¹ Unless the video hasn't been loaded yet, in that case it's transparent. ¹ 除非视频尚未加载,否则它是透明的。
You can simply look at the HTMLMediaElement's mediaKeys
property, if it is set, the video is DRM protected:您可以简单地查看HTMLMediaElement 的
mediaKeys
属性,如果已设置,则视频受 DRM 保护:
const isDRMProtected = (elem) => elem.mediaKeys instanceof MediaKeys;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.