如何用video.js适配多DRM保护的跨主流浏览器直播流?
Video.js 适配多DRM保护的跨浏览器直播流方案
我之前搭建过完全匹配需求的方案,核心思路是跳过有问题的detectSupportedCDMs(),通过浏览器/设备特性判断结合Video.js-contrib-eme的自动适配能力,分发对应的流和DRM配置。以下是可直接复用的实现方案:
一、核心实现逻辑
- 通过设备特性快速区分苹果设备与其他设备,避免依赖不可靠的CDM检测方法
- 为不同DRM系统单独配置许可证请求逻辑,交由contrib-eme自动匹配浏览器支持的CDM
- 强制使用第三方流处理库(HLS.js、dash.js)确保跨平台兼容性
二、完整代码示例
// 初始化Video.js播放器 const player = videojs('my-video-player', { controls: true, autoplay: false, preload: 'auto', html5: { vhs: { overrideNative: true // 强制用HLS.js处理HLS流,保证Fairplay兼容性 }, dash: { overrideNative: true // 强制用dash.js处理DASH流 }, eme: { keySystems: {} // 留空,后续动态配置 } } }); // 检测苹果设备(Safari/iOS/MacOS) function isAppleDevice() { return /iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent) && navigator.vendor.includes('Apple'); } // 动态配置流与DRM if (isAppleDevice()) { // 苹果设备:加载Fairplay加密的HLS直播流 player.src({ src: '你的Fairplay HLS直播流地址.m3u8', type: 'application/x-mpegURL' }); // 配置Fairplay DRM player.eme().setKeySystems({ 'com.apple.fps.1_0': { certificateUri: '你的Fairplay证书获取URL', getLicense: (emeOptions, keyMessage, callback) => { // 向Fairplay授权服务器请求许可证 fetch('你的Fairplay许可证获取URL', { method: 'POST', body: keyMessage, headers: { 'Content-Type': 'application/octet-stream', 'Authorization': 'Bearer 你的认证令牌' // 按需添加认证头 } }) .then(res => res.arrayBuffer()) .then(license => callback(null, license)) .catch(err => callback(err)); } } }); } else { // 其他设备:加载Widevine/Playready加密的DASH直播流 player.src({ src: '你的MPEG-DASH直播流地址.mpd', type: 'application/dash+xml' }); // 配置Widevine与Playready DRM player.eme().setKeySystems({ 'com.widevine.alpha': { getLicense: (emeOptions, keyMessage, callback) => { fetch('你的Widevine许可证获取URL', { method: 'POST', body: keyMessage, headers: { 'Content-Type': 'application/octet-stream', 'Authorization': 'Bearer 你的认证令牌' } }) .then(res => res.arrayBuffer()) .then(license => callback(null, license)) .catch(err => callback(err)); } }, 'com.microsoft.playready': { getLicense: (emeOptions, keyMessage, callback) => { fetch('你的Playready许可证获取URL', { method: 'POST', body: new TextDecoder().decode(keyMessage), headers: { 'Content-Type': 'application/xml', 'Authorization': 'Bearer 你的认证令牌' } }) .then(res => res.arrayBuffer()) .then(license => callback(null, license)) .catch(err => callback(err)); } } }); } // 播放器错误捕获 player.on('error', () => { console.error('播放异常:', player.error()); });
三、关键注意事项
- 放弃
detectSupportedCDMs():该方法在新版Chrome、Firefox中存在兼容性失效问题,设备类型判断更直接可靠 - 流处理库强制启用:苹果设备上必须强制使用HLS.js,避免原生HLS播放器的Fairplay兼容性问题
- 许可证请求格式差异:Fairplay和Widevine用二进制流请求,Playready需转成XML文本,需严格匹配DRM服务商要求
- Manifest校验:确保HLS的
.m3u8包含EXT-X-KEY标签、DASH的.mpd包含ContentProtection节点,否则播放器无法识别加密信息
内容的提问来源于stack exchange,提问作者Will
相关产品推荐
相关产品推荐

