html无法实现视频防投屏,因浏览器无api可禁用airplay等系统级投屏;唯一有效方案是eme+商业drm(如fairplay/widevine),配合加密流、许可证服务及硬件级安全支持。

HTML 本身无法通过接口“实现视频防投屏”——这是个常见误解。浏览器标准不提供 API 让网页主动禁用系统级投屏(如 macOS 的 AirPlay、Windows 的 Miracast、Chromecast),所有宣称“防投屏”的方案,本质都是在特定条件下降低被录屏/镜像的成功率,且极易被绕过。
为什么 navigator.mediaDevices.getDisplayMedia() 和投屏无关
这个 API 用于**请求用户共享屏幕/窗口**(比如会议软件截图),不是检测或阻止投屏。调用它不会触发投屏行为,也无法感知用户是否点了 AirPlay 按钮。
常见误用:
– 在视频播放前调用 getDisplayMedia({ video: false }) 并认为“占用了媒体通道”;
– 监听 document.visibilityState === 'hidden' 就暂停视频,以为能防投屏——实际投屏时页面 visibility 仍为 'visible';
– 依赖 screen.orientation 或 window.screen.availWidth 判断设备类型,但投屏后这些值完全不变。
真正可干预的点只有 DRM + MSE + 自定义解密
唯一被主流平台(iOS Safari、Android Chrome、Tizen、WebOS)认可的防录屏机制,是通过 EncryptedMediaExtensions (EME) + 商业 DRM 方案(如 Widevine、FairPlay、PlayReady)实现:
- 视频必须是 AES-128 或 CENC 加密的 HLS/DASH 流,不能是普通
<video src="xxx.mp4"></video> - 需在
video元素上设置crossOrigin="anonymous",否则 EME 初始化失败 - 必须由后端接口返回许可证(license)URL,并在
mediaKeys.setServerCertificate()后调用generateRequest()获取密钥 - 关键限制:iOS Safari 仅支持 FairPlay,且要求证书由 Apple 签发;Chrome on Android 需启用 Widevine L1,而 L1 依赖硬件 TEE,低端机默认降级为 L3(无防录屏能力)
前端能做的“软性防御”只有三件事
这些不防投屏,但能增加简单录屏成本,适合对安全性要求不高的场景:
– 禁用右键和上下文菜单:video.addEventListener('contextmenu', e => e.preventDefault())
– 隐藏原生控件并自绘 UI:<video controls="{false}"></video>,所有按钮用 <div> 实现,避免系统控件暴露“投屏按钮”<p>– 检测全屏状态异常:<br>监听 <code>document.fullscreenElement 变化,若 video 元素未进入全屏但 screen.width > window.innerWidth * 1.5,可能是投屏拉伸——此时可静音或模糊画面(但用户可手动恢复)
真正需要防投屏的业务(如付费课程、版权影视),必须走 DRM 接入流程,前端只是执行层;把希望寄托在某个 JS 接口或 CSS 属性上,基本等于没防。











