跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScript大前端

前端 EME DRM 反录屏原理与实战代码

EME 通过浏览器原生 API 调用 DRM 模块实现视频加密播放。核心在于 CDM 沙箱解密及硬件级保护路径,防止帧数据泄露至 CPU。Widevine L1 可阻断系统截屏,但 PC 浏览器 L3 环境防护有限。本文详解 EME 初始化、License 请求流程及代码实现,并提供方案选型建议。

清心发布于 2026/3/28更新于 2026/10/478 浏览
前端 EME DRM 反录屏原理与实战代码

EME 架构示意图

在实际业务场景中,我们常遇到视频防盗需求。当用户尝试截屏或录屏时,画面变黑是常见现象。这并非简单的 JS 监听快捷键所能实现,单纯依靠脚本极易被绕过。真正有效的方案依赖于浏览器原生支持的 Encrypted Media Extensions (EME)。

EME 工作原理图

什么是 Encrypted Media Extensions(EME)

EME 是 W3C 定义的一套 Web API,用于让浏览器播放受 DRM(数字版权管理)加密的媒体内容。通俗来说,它是一套 JS 接口,负责协调网页应用、浏览器与底层的 CDM(内容解密模块)之间的通信。

详细文档可参考:W3C Encrypted Media Extensions

主流平台对应的 DRM 方案:

平台DRM
Chrome、AndroidGoogle Widevine
Edge/WindowsMicrosoft PlayReady
Safari/iOS/macOSApple FairPlay

EME 如何实现防截屏 / 防录屏

在浏览器层面,EME 结合 DRM 机制可以实现一定程度的防护:

  1. 媒体文件加密:内容本身采用加密格式(如 Widevine Modular 加密)。
  2. CDM 沙箱解密:浏览器内置 CDM 模块(如 Chrome 内置 Widevine CDM),运行在沙箱环境中,密钥不暴露给 JS。
  3. 禁止系统级截屏:取决于 DRM 等级。例如在 Chrome 上播放 Netflix 时,使用系统截图键或录屏工具,视频区域会显示为黑色。
    • 原理:Widevine L1(硬件级)支持防截屏。DRM 解密后的视频帧不会进入 CPU 层,而是通过 GPU 的保护路径直接输出,截屏 API 无法捕获受保护的视频帧。
  4. 禁止扩展抓取:DRM 视频帧在受保护的 Video Pipeline 中,浏览器扩展无法获取。
  5. 禁止调试记录:解密密钥不会暴露在 JS 上下文中。

EME 播放加密媒体的代码示例

EME 充当网页应用、浏览器和底层 DRM 系统之间的'安全信使',在不暴露密钥的前提下完成解密流程。以下是一个使用 EME 播放加密 DASH(mpd)视频的完整流程示例。

注意:实际运行需要服务器提供 License Server 才能获取许可证。

1. 创建 video 标签
< =  =>
video
id
"video"
controls
width
"600"
</video>
2. JavaScript 初始化 EME

首先请求浏览器支持的 DRM 类型,并配置允许的编码格式。

const video = document.getElementById("video");

async function initEME() {
  // 请求支持的 DRM,如 Widevine
  const keySystem = "com.widevine.alpha";
  
  // 配置允许的编解码器
  const config = [{
    initDataTypes: ["cenc"],
    videoCapabilities: [{
      contentType: 'video/mp4; codecs="avc1.64001E"'
    }]
  }];

  // 请求 DRM 支持
  const access = await navigator.requestMediaKeySystemAccess(keySystem, config);
  const mediaKeys = await access.createMediaKeys();
  await video.setMediaKeys(mediaKeys);
  
  console.log("EME 初始化成功");
}

initEME();
3. 处理 license 请求

当视频开始播放且需要解密时,会触发 encrypted 事件。我们需要监听该事件并向授权服务器发送消息以获取 License。

video.addEventListener("encrypted", async (event) => {
  const session = video.mediaKeys.createSession();
  
  session.addEventListener("message", async (e) => {
    // 向授权服务器发送的消息
    const license = await fetch("/license", {
      method: "POST",
      body: e.message
    }).then(r => r.arrayBuffer());

    // 将 license 喂给 CDM 进行解密
    await session.update(license);
  });

  // 初始化 CDM,生成请求
  await session.generateRequest(event.initDataType, event.initData);
});
4. 设置加密视频源

最后加载加密后的视频流地址。

video.src = "https://example.com/encrypted.mpd";

如何为你的应用选择方案?

  • 防止复制、下载、非法传播音视频内容:需要实现 EME DRM。这需要后端准备加密内容、部署许可证服务器,并在前端集成相应的 DRM 厂商 SDK。
  • 防止界面泄露(聊天窗口、文档等):Web 环境下的防截屏能力有限。若需严格禁止截屏,建议寻找操作系统或框架提供的原生 API,通常需要将应用打包为 Electron 等桌面应用才能实现更深层的控制。

总结

EME 本质是浏览器访问 DRM 的 API,其本身不直接实现防录屏。真正的防护能力来自 DRM 方案(Widevine / PlayReady / FairPlay)以及设备硬件级别的支持。

  • 在 L1 级设备上,可完全禁止系统级截屏与录屏。
  • 在 PC 浏览器(通常为 L3 软件级)上,基本无法完全防住录屏行为。

如果你计划构建一个高安全级别的防盗录系统,建议采用组合策略:

DRM 加密 + 授权服务器 + 移动端 App 或支持 L1 的浏览器 + 行为水印 / 动态鉴权


EME 架构图

目录

  1. 什么是 Encrypted Media Extensions(EME)
  2. EME 如何实现防截屏 / 防录屏
  3. EME 播放加密媒体的代码示例
  4. 1. 创建 video 标签
  5. 2. JavaScript 初始化 EME
  6. 3. 处理 license 请求
  7. 4. 设置加密视频源
  8. 如何为你的应用选择方案?
  9. 总结

更多推荐文章

查看全部
  • Z-Image-Turbo 极速云端创作室入门与提示词实战指南
  • Capacitor 跨平台 Web 原生应用开发及鸿蒙适配指南
  • 基于 Python 与 Stable Diffusion 的企业营销素材生成方案
  • Python 可变与不可变数据类型详解
  • MyBatis 源码阅读:Mapper 映射文件解析流程
  • 基于多版本YOLO与SpringBoot的实时跌倒检测系统
  • 架构设计基础:系统架构演进历程(初始阶段至读写分离)
  • 知网 AIGC 检测算法升级分析与应对策略
  • 利用 cpolar 实现 Open-Lovable 远程访问与网页克隆
  • Copilot 指令文件解析:copilot-instructions.md、AGENTS.md、.instructions.md
  • Python 爬虫抓取企业年报与财务报告技术实现
  • 如何利用 Python 进行数据分析:核心概念与实战入门
  • JavaScript Web API 入门与常用操作
  • Transformer 核心机制解析:自注意力与多头机制
  • 机器人数值优化基础:从理论到实战指南
  • 国产 AI 智能体工具盘点:Claw 系列收录与官网指引
  • Python heapq 入门与实战:最小堆、Top-K 和优先队列
  • DWR3 基于 Spring MVC 配置 Controller 的方法
  • 基于 Leaflet Trackplayer 的高速公路轨迹 WebGIS 可视化
  • 贪心算法和动态规划:原理、区别与 C++ 示例

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online