如何解决如何在 Chrome 中使用 javascript 检测 HTML 视频是否受 DRM 保护?
快速背景:我正在编写一个浏览器扩展程序,它可以在浏览器中播放视频时对其进行操作。脚本本身应该是通用的,它应该在任何有视频的网站上运行。
我的视频操作依赖于能够操作视频中的像素数据。将视频像素转化为可在 JavaScript 中使用的 HTML5 支持的方法是 canvas2dContext.drawImage()
函数将当前视频帧绘制到画布上,context.getimageData()
函数用于获取所述数据。
当前代码归结为(我正在简化一些事情):
let video = document.findElementsByTagName('video')[0];
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
handleVideoFrame() {
context.drawImage(video,canvas.width,canvas.height);
let data = context.getimageData(0,canvas.height);
processData(data);
}
processData(data) {
// a lot of heavy calculations going on here
}
window.requestAnimationFrame(handleVideoFrame);
问题:DRM
这很有效,直到您尝试在 Netflix、disney+ 或其他相同级别的网站上执行此操作。这些网站使用 DRM,如果该视频有 DRM,context.drawImage()
将无法工作。请注意,我不想捕获受 DRM 保护的视频的实际帧,但我想知道 DRM 是否存在。
在 Firefox 中,这不是什么大问题,因为如果您尝试在受 DRM 保护的视频上调用 context.drawImage()
,you will get an exception。然后,您可以捕获该异常,不要运行繁重的 processData()
,提醒用户您的脚本由于 DRM 而无法在该站点上运行,然后关闭整个程序。>
另一方面,在 Chrome(以及其他 Chromium reskins)中,context.drawImage()
不会失败。相反,context.drawImage()
将绘制一个 100% 不透明的黑色方块而不抛出异常,这是一个问题,因为:
- 您永远无法确定视频是否受 DRM 保护
- 因此你不能通知用户,谁会责怪你的脚本
- 虽然您可以检查框架是否为黑色并避免调用沉重的
processData()
(如果是),但您仍在执行不需要执行的drawImage()
调用
我尝试过的解决方案
-
context.getimageData()
返回一个对象,该对象包含一个包含每个像素的 RGBA 值的数组。我最初希望可以通过查看 alpha 值来确定视频是否受 DRM 保护。但是,drawImage()
绘制的框架总是¹完全不透明,这意味着这是一个死胡同。
¹ 除非视频尚未加载,否则它是透明的。
我希望避免的解决方案
- 任何涉及我根据框架已经黑了一段时间这一事实做出假设的事情。当然,我可以将视频运行 n 秒,如果我检查过的所有帧都是全黑的,我就会发出警告。如果 n 太低,我就有误报的风险。如果 n 太高,视频播放和“whoops DRM”警告之间的延迟可能会太长。
- 维护我知道使用 DRM 的已知站点列表
解决方法
您可以简单地查看 HTMLMediaElement's mediaKeys
属性,如果已设置,则视频受 DRM 保护:
const isDRMProtected = (elem) => elem.mediaKeys instanceof MediaKeys;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。