# 加密播放

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推行的浏览器标准,允许开发者忽略平台带来的差异进行开发。
design.002.png 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'
  }
})

这就是最简单的调用方式,有几点需要注意:

  1. 在桌面端,widevine需要通过hls内核使用,移动端上Android设备可以原生播放。Fairplay则只能通过原生内核播放。
  2. keySystem 需要根据使用的加密和平台决定。常见的有com.widevine.alpha, com.apple.fps, com.apple.fps.1_0
  3. 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;
    },
  }
});

有几点需要注意:

  1. 这里的drmConfigplay接口中所使用的是等效的,你也可以在接口调用时才传入。

# 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

# 一些对你可能有帮助的参考文档

上次更新: 10/11/2021, 9:48:12 PM