disablePictureInPicture="true"可禁用画中画及浏览器投屏入口,但仅限UI层隐藏;Chrome/Edge 89+、Safari 16.4+支持,Firefox忽略;需配合JS监听enterpictureinpicture事件及时退出,并依赖服务端Referer校验、签名URL或DRM防护。

video 标签加 disablePictureInPicture 属性最直接
浏览器原生投屏(如 Chrome 的“投射到设备”)无法被 JavaScript 完全拦截,但可通过 HTML 属性主动禁用画中画和投屏入口。在 <video> 标签上设置 disablePictureInPicture="true",能阻止右键菜单出现“画中画”选项,同时让投屏按钮(如 Chrome 地址栏的 Cast 图标)对当前视频失效。
注意这不是加密或 DRM,只是 UI 层隐藏——用户仍可能通过录屏软件、系统级截屏或抓包获取视频流。实际效果取决于浏览器支持程度:
- Chrome / Edge 89+、Safari 16.4+ 支持该属性
- Firefox 不支持
disablePictureInPicture,但会忽略该属性,不报错 - 必须写成
disablePictureInPicture="true",仅写disablePictureInPicture(布尔属性简写)在部分版本中无效
示例:
<video controls disablePictureInPicture="true"> <source src="video.mp4" type="video/mp4"> </video>
JavaScript 动态禁用需配合 onenterpictureinpicture 拦截
如果视频是动态插入或需条件控制(比如仅会员可投屏),光靠 HTML 属性不够,得用 JS 监听并退出画中画状态。关键不是阻止进入,而是「一进就退」:
- 监听
enterpictureinpicture事件,在触发时立即调用document.exitPictureInPicture() - 同时建议监听
leavepictureinpicture做清理(比如恢复播放状态) - 必须在
video元素加载完成(loadedmetadata或canplay)后绑定事件,否则监听无效
示例:
const video = document.querySelector('video');
video.addEventListener('loadedmetadata', () => {
video.addEventListener('enterpictureinpicture', () => {
if (document.pictureInPictureElement === video) {
document.exitPictureInPicture().catch(() => {});
}
});
});
防投屏 ≠ 防盗链,别漏掉服务端配合
前端加属性或 JS 只影响浏览器 UI 行为,完全不阻止用户从 Network 面板复制 src 地址、用 curl 下载或改 Referer 绕过。真正限制投屏场景下的内容扩散,得靠服务端策略:
立即学习“前端免费学习笔记(深入)”;
- 对视频资源启用 Referer 校验,拒绝非本站域名的直接请求
- 使用带时效的签名 URL(如
/video/abc123?token=xxx&exp=171xxxxx),过期即 403 - 关键业务场景建议接入 MSE + EME,配合 Widevine 或 FairPlay 实现硬件级解密,此时即使投屏,输出帧也会被 DRM 策略标记为不可录制(但开发成本高、兼容性差)
单独改 HTML 源码,解决不了地址暴露问题——src 写死在页面里,等于把钥匙挂在门把手上。
移动端 Safari 的 webkit-playsinline 会影响投屏行为
iOS Safari 默认全屏播放视频,而投屏功能依赖于页面内可交互的 video 元素。如果没加 webkit-playsinline,用户点播后立刻全屏,此时系统投屏按钮往往不可见或无法关联到该视频。
所以 iOS 防投屏要多做一步:显式禁用内联播放,反而让视频保持在页面容器中(便于 JS 控制),再配合 disablePictureInPicture 和事件拦截:
- HTML 中加
webkit-playsinline="false"(注意是false,不是移除属性) - 同时确保
playsinline也设为false(现代 Safari 已支持标准属性) - 不推荐依赖
x5-video-player-type="h5"等微信私有属性,它们对投屏无实质影响
这个细节容易被忽略:很多开发者只测桌面 Chrome,却没在真机上验证投屏按钮是否真的消失。
防投屏的边界很清晰——你能控制的只有浏览器 UI 和基础行为拦截;一旦视频流已加载到内存,后续所有操作(包括系统级投屏、录屏、抓包)都不再受 HTML 或 JS 约束。真正敏感的内容,不能只靠改源码。



















