encrypted事件是EME DRM播放流程的关键触发点,用于响应加密媒体片段加载,携带initData(如PSSH)和type信息;需配合requestMediaKeySystemAccess、setMediaKeys、generateRequest和update四步完成密钥协商与解密。

移动端视频通过 encrypted 事件支持 DRM 播放,本质是利用 HTML5 Media API 与 CDM(Content Decryption Module)协同完成密钥协商和解密流程。它不是单独靠一个事件就能实现保护,而是整个 EME(Encrypted Media Extensions)工作流的关键触发点。
encrypted 事件的作用定位
当浏览器加载到加密的媒体片段(如带 keyid 的 MP4 或 fMP4,或含 #EXT-X-KEY 的 HLS 加密切片)时,会自动触发 encrypted 事件。这个事件本身不包含密钥,只携带加密信息:
– initData:初始化数据,通常是 PSSH(Protection System Specific Header),含 DRM 系统标识(如 Widevine、FairPlay)和内容 ID;
– type:指定 DRM 类型(如 “application/vnd.apple.pkpass” 对应 FairPlay,“video/webm; codecs=\"vp9\"” 常用于 Widevine)。
完整 DRM 播放流程依赖的四步联动
仅监听 encrypted 事件远远不够,必须配合以下环节才能完成受控播放:
-
提前请求许可:页面需先调用
navigator.requestMediaKeySystemAccess(),传入所需 DRM 系统(如“com.widevine.alpha”)、编码格式和鲁棒性要求,确认设备是否支持并获取MediaKeySystemAccess实例。 -
创建并关联 MediaKeys:用上一步返回的对象创建
MediaKeys,再通过video.setMediaKeys()绑定到 video 元素——这是后续encrypted事件能被响应的前提。 -
在 encrypted 回调中发起密钥请求:监听到事件后,调用
mediaKeys.createSession()创建会话,再用session.generateRequest()提交initData,触发与许可证服务器的通信(通常走 HTTPS POST)。 -
接收并注入许可证:从许可证服务器拿到加密的 license 后,调用
session.update()注入,CDM 自动完成解密并允许播放器继续加载和渲染。
移动端特别要注意的兼容细节
不同平台对 EME 的支持差异明显,实际开发中需针对性处理:
-
iOS Safari 不支持 Widevine:只能使用 FairPlay,且必须走 Apple 要求的服务器签名流程(ASPK、CKC 请求),
encrypted事件中的initData是 SPC(Streaming Request),需用专用证书生成 CKC 响应。 -
Android WebView 行为不一致:系统 WebView 可能禁用 EME,建议明确使用 Chrome Custom Tabs 或 TWA(Trusted Web Activity);若用原生封装,需确认 WebView 启用了
setMediaPlaybackRequiresUserGesture(false)等策略。 -
HLS + FairPlay 需额外配置:Safari 要求 M3U8 中
#EXT-X-KEY的URI指向 .sinf 或 .skd 文件,并启用content-id和uri参数传递,否则encrypted事件可能不触发。
避免常见失效场景
很多项目卡在“有 encrypted 事件但没播放”,往往源于基础链路断裂:
- 未在
标签上设置crossorigin="anonymous",导致加密资源跨域加载失败,encrypted根本不会触发; - 许可证服务器返回 HTTP 状态非 200 或响应头缺失
Content-Type: application/octet-stream,导致session.update()报错; - 未监听
keystatuseschange事件排查密钥状态(如"status"为"output-not-allowed"),容易忽略 HDCP 或屏幕录制限制引发的黑屏; - 安卓部分低端机型 CDM 初始化缓慢,需设置合理超时并 fallback 到清晰度降级或提示重试。











