微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Chrome 中使用 javascript 检测 HTML 视频是否受 DRM 保护?

如何解决如何在 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 举报,一经查实,本站将立刻删除。