1# DRM会话管理(ArkTS)
2
3DRM会话管理(MediaKeySession)支持媒体密钥管理及媒体解密等,MediaKeySession实例由系统管理里的MediaKeySystem实例创建和销毁。
4
5## 开发步骤
6
7详细的API说明请参考[DRM API参考](../../reference/apis-drm-kit/js-apis-drm.md)。
8
91. 导入相关接口,导入方法如下。
10
11   ```ts
12   import { drm } from '@kit.DrmKit';
13   ```
14
152. 导入BusinessError模块,用于获取drm模块相关接口抛出的错误码。
16
17   ```ts
18   import { BusinessError } from '@kit.BasicServicesKit';
19   ```
20
213. 状态监听。
22
23    监听MediaKeySession实例的事件,包括密钥请求事件、密钥过期事件、第三方自定义事件、密钥过期更新事件、密钥变换事件。
24
25    - 监听密钥请求事件,媒体密钥请求时触发。
26
27       ```ts
28       mediaKeySession.on('keyRequired', (eventInfo: drm.EventInfo) => {
29         console.log('keyRequired' + 'info:' + eventInfo.info + ' extraInfo:' + eventInfo.extraInfo);
30       });
31       ```
32
33    - 监听媒体密钥过期事件,媒体密钥过期时触发。
34
35       ```ts
36       mediaKeySession.on('keyExpired', (eventInfo: drm.EventInfo) => {
37          console.log('keyExpired' + 'info:' + eventInfo.info + ' extraInfo:' + eventInfo.extraInfo);
38       });
39       ```
40
41    - 监听DRM解决方案自定义事件,DRM解决方案自定义事件发生时触发。
42
43       ```ts
44       mediaKeySession.on('vendorDefined', (eventInfo: drm.EventInfo) => {
45         console.log('vendorDefined' + 'info:' + eventInfo.info + ' extraInfo:' + eventInfo.extraInfo);
46       });
47       ```
48
49    - 监听媒体密钥过期更新事件,媒体密钥过期更新时触发。
50
51       ```ts
52       mediaKeySession.on('expirationUpdate', (eventInfo: drm.EventInfo) => {
53         console.log('expirationUpdate' + 'info:' + eventInfo.info + ' extraInfo:' + eventInfo.extraInfo);
54       });
55       ```
56
57    - 监听密钥变换事件,媒体密钥变换时触发。
58
59       ```ts
60       mediaKeySession.on('keysChange', (keyInfo : drm.KeysInfo[], newKeyAvailable:boolean) => {
61         for(let i = 0; i < keyInfo.length; i++){
62           console.log('keysChange' + 'info:' + keyInfo[i].keyId + ' extraInfo:' + keyInfo[i].value);
63         }
64       });
65       ```
66
674. 生成媒体密钥请求、设置媒体密钥请求响应。
68
69   ```ts
70   let initData = new Uint8Array([0x00, 0x00, 0x00, 0x00]);
71   // 根据DRM解决方案要求设置可选数据的值
72   let optionalData:drm.OptionsData[] = [{
73     name: "...",
74     value: "..."
75   }];
76   // 以下示例完成在线媒体密钥请求和响应设置
77   mediaKeySession.generateMediaKeyRequest("video/avc", initData, drm.MediaKeyType.MEDIA_KEY_TYPE_ONLINE, optionalData).then(async (licenseRequest) => {
78      console.info("generateMediaKeyRequest success", licenseRequest.mediaKeyRequestType, licenseRequest.data, licenseRequest.defaultURL);
79      // 将媒体密钥请求返回的licenseRequest.data通过网络请求发送给DRM服务获取媒体密钥请求响应,设置媒体密钥请求响应
80      let licenseResponse = new Uint8Array([0x00, 0x00, 0x00, 0x00]);
81      mediaKeySession.processMediaKeyResponse(licenseResponse).then((mediaKeyId: Uint8Array) => {
82        console.info("processMediaKeyResponse success");
83      }).catch((err:BusinessError) =>{
84        console.info("processMediaKeyResponse err end", err.code);
85     });
86   }).catch((err:BusinessError) =>{
87     console.info("generateMediaKeyRequest err end", err.code);
88   });
89   // 以下示例完成离线媒体密钥请求和响应设置
90   let offlineMediaKeyId = new Uint8Array([0x00, 0x00, 0x00, 0x00]);
91   mediaKeySession.generateMediaKeyRequest("video/avc", initData, drm.MediaKeyType.MEDIA_KEY_TYPE_OFFLINE, optionalData).then((licenseRequest: drm.MediaKeyRequest) => {
92      console.info("generateMediaKeyRequest success", licenseRequest.mediaKeyRequestType, licenseRequest.data, licenseRequest.defaultURL);
93      // 将媒体密钥请求返回的licenseRequest.data通过网络请求发送给DRM服务获取媒体密钥请求响应,设置媒体密钥请求响应
94      let licenseResponse = new Uint8Array([0x00, 0x00, 0x00, 0x00]);
95      mediaKeySession.processMediaKeyResponse(licenseResponse).then((mediaKeyId: Uint8Array) => {
96	offlineMediaKeyId = mediaKeyId;
97        console.info("processMediaKeyResponse success");
98      }).catch((err:BusinessError) =>{
99        console.info("processMediaKeyResponse err end", err.code);
100     });
101   }).catch((err:BusinessError) =>{
102     console.info("generateMediaKeyRequest err end", err.code);
103   });
104   ```
105
1065. (可选)检查当前MediaKeySession会话的媒体密钥状态。
107
108    ```ts
109    try {
110      let keyvalue: drm.MediaKeyStatus[] = mediaKeySession.checkMediaKeyStatus();
111      console.info("checkMediaKeyStatus success", keyvalue[0].value);
112    } catch (err) {
113      let error = err as BusinessError;
114      console.error(`checkMediaKeyStatus ERROR: ${error}`);
115    }
116    ```
117
1186. (可选)生成离线媒体密钥释放请求和处理离线媒体密钥释放响应。
119
120   ```ts
121   mediaKeySession.generateOfflineReleaseRequest(offlineMediaKeyId).then((OfflineReleaseRequest: Uint8Array) => {
122     console.info("generateOfflineReleaseRequest success", OfflineReleaseRequest);
123     // 将媒体密钥释放请求返回的OfflineReleaseRequest通过网络请求发送给DRM服务获取媒体密钥释放请求响应,设置媒体密钥释放请求响应
124     let OfflineReleaseResponse = new Uint8Array([0x00, 0x00, 0x00, 0x00]);
125     mediaKeySession.processOfflineReleaseResponse(offlineMediaKeyId, OfflineReleaseResponse).then(() => {
126       console.info("processOfflineReleaseResponse success");
127     }).catch((err:BusinessError) =>{
128       console.info("processOfflineReleaseResponse err end", err.code);
129     });
130   }).catch((err:BusinessError) =>{
131     console.info("generateOfflineReleaseRequest err end", err.code);
132   });
133   ```
134
1357. (可选)恢复离线媒体密钥。
136
137   ```ts
138   // 恢复指定媒体密钥信息到当前会话
139   mediaKeySession.restoreOfflineMediaKeys(offlineMediaKeyId).then(() => {
140     console.log("restoreOfflineMediaKeys success.");
141   }).catch((err: BusinessError) => {
142     console.error(`restoreOfflineMediaKeys: ERROR: ${err}`);
143   });
144   ```
145
1468. (可选)获取当前会话的安全级别。
147
148    ```ts
149    try {
150      let contentProtectionLevel: drm.ContentProtectionLevel = mediaKeySession.getContentProtectionLevel();
151    } catch (err) {
152      let error = err as BusinessError;
153      console.error(`getContentProtectionLevel ERROR: ${error}`);
154    }
155   ```
156
1579. (可选)查询是否需要安全解码。
158
159    ```ts
160    try {
161      let status: boolean = mediaKeySession.requireSecureDecoderModule("video/avc");
162    } catch (err) {
163      let error = err as BusinessError;
164      console.error(`requireSecureDecoderModule ERROR: ${error}`);
165    }
166    ```
167
16810. (可选)删除当前会话的媒体密钥。
169
170    ```ts
171    try {
172       mediaKeySession.clearMediaKeys();
173    } catch (err) {
174      let error = err as BusinessError;
175      console.error(`clearMediaKeys ERROR: ${error}`);
176    }
177    ```