# 加密播放
thumbplayer-core提供了基于浏览器Encrypted Media Extension(EME)标准的DRM(Digital Rights Management)视频播放能力。同时,通过hls内核提供了AES加密视频的播放能力。 目前已经支持的加密格式如下:
widevine | fairplay | playready | clearkey | AES | |
---|---|---|---|---|---|
Safari | ❌ | ✅ | ❌ | ** | ✅ * |
Safari iOS | ❌ | ✅ | ❌ | ** | ✅ * |
Chrome | ✅ | ❌ | ❌ | ** | ✅ * |
Chrome iOS | ❌ | ✅ | ❌ | ** | ✅ * |
Firefox | ✅ | ❌ | ❌ | ** | ✅ * |
Firefox iOS | ❌ | ✅ | ❌ | ** | ✅ * |
Note:
* 在不支持原生hls播放的环境中,AES加密目前仅支持通过hls内核使用
** clearkey能力排期开发中
# 加密播放?DRM?他们有什么区别和关联
首先,加密播放不等同于DRM(Digital Rights Management)。作为加密标准的代表,AES加密虽然难以破解,但是一旦攻击者获取到了密钥即可轻松播放加密内容。业界通常的做法是通过鉴权获取密钥,并设置一个相对短的有效期来应对密钥泄漏的问题(key-rotation)。然而这种方法还是无法保障在有效期内产生的盗播问题。
DRM在这种背景下应运而生,其核心在于密钥不通过任何形式暴露给外界。解密的流程由浏览器内部模块完成,被称为CDM(Content Decryption Module)。各家的实现方式均有不同,并且对web应用保持黑盒以保护加密算法的安全性。而EME(Encrypted Media Extension)则作为web应用访问CDM获取解密能力的桥梁,是w3c推行的浏览器标准,允许开发者忽略平台带来的差异进行开发。
EME相关的技术标准,可以参阅w3c specification (opens new window)
# 使用
Talk is cheap, show me the code!
player.play({
url: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8',
drmConfig: {
keySystem: 'com.widevine.alpha',
licenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth'
}
})
这就是最简单的调用方式,有几点需要注意:
- 在桌面端,widevine需要通过hls内核使用,移动端上Android设备可以原生播放。Fairplay则只能通过原生内核播放。
keySystem
需要根据使用的加密和平台决定。常见的有com.widevine.alpha
,com.apple.fps
,com.apple.fps.1_0
。- Fairplay还需要传入服务端证书,详见进阶使用。
# 进阶使用
如果你的DRM证书服务有鉴权的需求,又或者返回的证书并非标准的二进制数据,我们也提供了相应的配置。
以腾讯视频为例,其加密后台的证书服务返回的证书是一个json格式的数据包,其中包含了base64编码的证书。那么我们可以通过下面的方法来支持:
const player = KernelFactory.create({
container: '.thumbplayer-container',
drmConfig: {
licenseResponseSetup: (response) => {
// json格式为{ code: xxx, ckc: xxx, message: xxx }
const ckc = base64ToUint8Array(response.ckc);
return ckc
},
licenseRequestSetup: (opts) => {
opts.responseType = 'json';
return opts;
},
}
});
有几点需要注意:
- 这里的
drmConfig
和play
接口中所使用的是等效的,你也可以在接口调用时才传入。
# Fairplay
Apple Fairplay在通过上述办法传入配置的同时,还需要设置服务端证书:
player.play({
url: 'https://publicread-75538.gzc.vod.tencent-cloud.com/drm/fairplay/j0032f73cpt.320190/j0032f73cpt.320190.ts.m3u8',
drmConfig: {
licenseUrl: 'https://testvv.video.qq.com/vod/fairplay/v1/getckc?key=01vxZdic4r0Z0hCkGAhPDiG7RwQNFMuLPX2Ii3SIli1zcjHQI2HJn8KqYpmXjd9dl0-RBED14ITTfkhg&vid=j0032f73cpt&fmt=320190&ip=&platform=10403&uin=&openid=oQFqrjkqTn33iH4jpiYRkFdS7A9M&guid=test&version=1&iosVersion=14.4.2',
certificate: {
'com.apple.fps': 'https://fairplay.l.qq.com/static/fairplay.cer'
},
keySystem: 'com.apple.fps',
})
certificate
中传入的可以是证书的地址,也可以是已经准备好的uint8Array
数据。
注意
iOS/ipadOS设备需要最低12.2版本,macOS需要最低10.14.4版本才可以通过EME接口实现Fairplay播放
# Fairplay via Webkit
Apple Fairplay也有通过Webkit实现的接口,和使用EME接口的相比可以兼容更低版本的设备。
使用上,只需要调整keySystem
即可:
player.play({
url: '',
drmConfig: {
keySystem: 'com.apple.fps.1_0',
certificate: {
'com.apple.fps.1_0': '',
}
}
})
注意
iOS/ipadOS设备需要最低11.2版本,macOS需要最低10.10.3版本。
# API和常用值
drmConfig
- drm配置参数
属性 | 类型 | 可选 | 含义 |
---|---|---|---|
keySystem | string | false | 加密类型 |
licenseUrl | string | false | 证书地址 |
certificate | object | true | 服务端证书(地址或数据),目前仅Fairplay使用 |
licenseRequestSetup | Function | true | 证书请求配置。可以用来调整请求方法,设置Cookie等 |
licenseResponseSetup | Function | true | 证书请求回调函数。可以用来解析返回的数据,转换格式等 |
licenseRequestSetup
- 证书请求配置函数
licenseRequestSetup(opts: xhrOpts): xhrOpts
xhrOpts
属性 | 类型 | 默认值 | 含义 |
---|---|---|---|
responseType | string | arraybuffer | 证书类型 |
headers | Object | undefined | 证书请求时携带的headers ,格式为键值对 |
body | string | spc=xxx | undefined | 证书请求时携带的form body ,fairplay会默认携带spc 信息 |
licenseResponseSetup
- 证书请求回调函数
licenseResponseSetup(response: any): any
keySystem
- 加密类型
类型 | keySystem字符串 |
---|---|
widevine | com.widevine.alpha |
fairplay | com.apple.fps |
fairplay via webkit | com.apple.fps.1_0 |