• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 数字版权保护(C/C++)
2
3## 功能介绍
4
5开发者可以调用DRM Kit的C/C++接口实现DRM证书管理、DRM许可证管理、DRM节目授权、DRM节目解密等数字版权保护功能。
6
7DRM Kit提供MediaKeySystem实现DRM证书管理、DRM许可证管理功能,并管理MediaKeySession实例;MediaKeySession实现DRM节目授权,并可支持Media Kit或AVCodec Kit实现DRM节目解密以实现DRM节目播放。
8
9## 开发步骤
10
11详细的API说明请参考[DRM API](../../reference/apis-drm-kit/capi-drm.md)。
12
131. 导入DRM Kit接口。
14
15    ```c++
16    #include "multimedia/drm_framework/native_drm_common.h"
17    #include "multimedia/drm_framework/native_drm_err.h"
18    #include "multimedia/drm_framework/native_mediakeysession.h"
19    #include "multimedia/drm_framework/native_mediakeysystem.h"
20    ```
21
222. 在CMake脚本中链接动态库。
23
24    ```txt
25    target_link_libraries(PUBLIC libnative_drm.so)
26    ```
27
283. 获取设备支持的DRM解决方案名称和唯一标识的列表。
29
30    ```c++
31    uint32_t count = 3; // count是当前设备实际支持的DRM插件的个数,用户根据实际情况设置。
32    DRM_MediaKeySystemDescription descriptions[3];
33    memset(descriptions, 0, sizeof(descriptions));
34    Drm_ErrCode ret = OH_MediaKeySystem_GetMediaKeySystems(descriptions, &count);
35    if (ret != DRM_ERR_OK) {
36        printf("OH_MediaKeySystem_GetMediaKeySystems failed.");
37    }
38    ```
39
404. (可选)查询设备是否支持对应DRM解决方案名称、媒体类型、安全保护级别的DRM解决方案。
41
42    ```c++
43    bool isSupported = OH_MediaKeySystem_IsSupported3("com.clearplay.drm", "video/mp4", CONTENT_PROTECTION_LEVEL_SW_CRYPTO);
44    if (isSupported != true) {
45        printf("The device does not support the content protection level.");
46    }
47    ```
48
495. 创建MediaKeySystem实例。
50
51    ```c++
52    MediaKeySystem *mediaKeySystem = nullptr;
53    ret = OH_MediaKeySystem_Create("com.clearplay.drm", &mediaKeySystem);
54    if (ret != DRM_ERR_OK || mediaKeySystem == nullptr) {
55        printf("OH_MediaKeySystem_Create failed.");
56    }
57    ```
58
596. (可选)设置MediaKeySystem事件监听回调。
60
61    ```c++
62    static Drm_ErrCode SystemCallBackWithObj(MediaKeySystem *mediaKeySystem, DRM_EventType eventType,
63        uint8_t *info, int32_t infoLen, char *extra)
64    {
65        printf("SystemCallBackWithObj enter");
66        if (eventType == EVENT_PROVISION_REQUIRED) {
67            // 设备DRM证书请求和处理。
68        }
69        return DRM_ERR_OK;
70    }
71
72    ret = OH_MediaKeySystem_SetCallback(mediaKeySystem, SystemCallBackWithObj);
73    if (ret != DRM_ERR_OK) {
74        printf("OH_MediaKeySystem_SetCallback failed.");
75    }
76    ```
77
787. (可选)获取设备DRM证书状态。
79
80    ```c++
81    DRM_CertificateStatus certStatus = CERT_STATUS_INVALID;
82    // 检查设备DRM证书状态。
83    ret = OH_MediaKeySystem_GetCertificateStatus(mediaKeySystem, &certStatus);
84    if (ret == DRM_ERR_OK && certStatus != CERT_STATUS_PROVISIONED) {
85        // 设备DRM证书请求和处理。
86    }
87    ```
88
898. (可选)生成设备DRM证书请求与处理设备DRM证书响应。
90
91    ```c++
92    #define MAX_DRM_PROVISION_BUF_SIZE 24576 // 24576: (2 * 12 * 1024)
93    unsigned char request[MAX_DRM_PROVISION_BUF_SIZE] = { 0x00 };  // 设备DRM证书request最大长度为MAX_DRM_PROVISION_BUF_SIZE,按实际大小申请。
94    int32_t requestLen = MAX_DRM_PROVISION_BUF_SIZE;
95    // DRM服务URL的最大长度为2048。
96    char defaultUrl[2048] = { 0x00 };
97    int32_t defaultUrlLen = 2048;
98    ret = OH_MediaKeySystem_GenerateKeySystemRequest(mediaKeySystem, request, &requestLen, defaultUrl,
99        defaultUrlLen);
100    if (ret != DRM_ERR_OK) {
101        printf("OH_MediaKeySystem_GenerateKeySystemRequest failed.");
102    }
103    /*
104      应用通过网络请求,将设备DRM证书请求信息传到DRM服务获取设备DRM证书请求响应keySystemResponse,
105      再将设备DRM证书请求响应设置到设备上,请根据实际的数据和长度传入。
106    */
107    unsigned char keySystemResponse[MAX_DRM_PROVISION_BUF_SIZE] = {0x00};
108    ret = OH_MediaKeySystem_ProcessKeySystemResponse(mediaKeySystem, keySystemResponse, sizeof(keySystemResponse));
109    if (ret != DRM_ERR_OK) {
110        printf("OH_MediaKeySystem_ProcessKeySystemResponse failed.");
111    }
112    ```
113
1149. (可选)获取设备支持的最大内容保护级别。
115
116    ```c++
117    DRM_ContentProtectionLevel maxContentProtectionLevel = CONTENT_PROTECTION_LEVEL_UNKNOWN;
118    ret = OH_MediaKeySystem_GetMaxContentProtectionLevel(mediaKeySystem, &maxContentProtectionLevel);
119    if (ret != DRM_ERR_OK) {
120        printf("OH_MediaKeySystem_GetMaxContentProtectionLevel failed.");
121    }
122    ```
123
12410. 创建MediaKeySession实例。
125
126    ```c++
127    MediaKeySession *mediaKeySession = nullptr;
128    DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO; // 依据设备支持的内容保护级别设置。
129    ret = OH_MediaKeySystem_CreateMediaKeySession(mediaKeySystem, &contentProtectionLevel, &mediaKeySession);
130    if (ret != DRM_ERR_OK || mediaKeySession == nullptr) {
131        printf("OH_MediaKeySystem_CreateMediaKeySession failed.");
132    }
133    ```
134
13511. (可选)设置MediaKeySession事件监听回调。
136
137    ```c++
138    static Drm_ErrCode SessionEventCallBackWithObj(MediaKeySession *mediaKeySession, DRM_EventType eventType, uint8_t *info, int32_t infoLen, char *extra)
139    {
140        if (eventType == EVENT_KEY_REQUIRED) {
141            // 媒体密钥请求与处理。
142        }
143        return DRM_ERR_OK;
144    }
145
146    static Drm_ErrCode SessionKeyChangeCallBackWithObj(MediaKeySession *mediaKeySession, DRM_KeysInfo *keysInfo, bool hasNewGoodKeys)
147    {
148        return DRM_ERR_OK;
149    }
150
151    OH_MediaKeySession_Callback sessionCallback = { SessionEventCallBackWithObj, SessionKeyChangeCallBackWithObj };
152    ret = OH_MediaKeySession_SetCallback(mediaKeySession, &sessionCallback);
153    if (ret != DRM_ERR_OK) {
154        printf("OH_MediaKeySession_SetCallback failed.");
155    }
156    ```
157
15812. (可选)查询是否需要安全解码。
159
160    ```c++
161    bool requireSecureDecoder;
162    ret = OH_MediaKeySession_RequireSecureDecoderModule(mediaKeySession, "video/avc", &requireSecureDecoder);
163    if (ret != DRM_ERR_OK) {
164        printf("OH_MediaKeySession_RequireSecureDecoderModule failed.");
165    }
166    ```
167
16813. 生成媒体密钥请求与处理媒体密钥响应,以请求许可证完成DRM节目授权。
169
170    ```c++
171    #define MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE 24576 // 24576: (2 * 12 * 1024)
172    DRM_MediaKeyRequest mediaKeyRequest;
173    DRM_MediaKeyRequestInfo info;
174    // initData对应码流中的pssh数据,请按实际数据填入。
175    unsigned char initData[512] = {0x00};
176    memset(&info, 0, sizeof(DRM_MediaKeyRequestInfo));
177    info.initDataLen = sizeof(initData);
178    info.type = MEDIA_KEY_TYPE_ONLINE; // MEDIA_KEY_TYPE_ONLINE: 在线媒体密钥请求类型; MEDIA_KEY_TYPE_OFFLINE: 离线媒体密钥请求类型。
179    memcpy(info.mimeType, (char *)"video/mp4", sizeof("video/mp4"));
180    memcpy(info.initData, initData, sizeof(initData));
181    memcpy(info.optionName[0], (char *)"optionalDataName", sizeof("optionalDataName"));
182    memcpy(info.optionData[0], (char *)"optionalDataValue", sizeof("optionalDataValue"));
183    info.optionsCount = 1;
184    ret = OH_MediaKeySession_GenerateMediaKeyRequest(mediaKeySession, &info, &mediaKeyRequest);
185    if (ret != DRM_ERR_OK) {
186        printf("OH_MediaKeySession_GenerateMediaKeyRequest failed.");
187    }
188    /*
189      应用通过网络请求DRM服务,获取媒体密钥响应mediaKeyResponse,将响应传到OH_MediaKeySession_ProcessMediaKeyResponse,
190      若是离线媒体密钥响应处理,则返回离线媒体密钥标识mediaKeyId,请根据实际的数据和长度传入。
191    */
192    unsigned char mediaKeyId[128] = {0x00};
193    int32_t mediaKeyIdLen = 128;
194    // 媒体密钥响应长度最大为MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE,请按实际数据输入。
195    unsigned char mediaKeyResponse[MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE] = {0x00};
196    int32_t mediaKeyResponseLen = MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE;
197    ret = OH_MediaKeySession_ProcessMediaKeyResponse(mediaKeySession, mediaKeyResponse,
198        mediaKeyResponseLen, mediaKeyId, &mediaKeyIdLen);
199    if (ret != DRM_ERR_OK) {
200        printf("OH_MediaKeySession_ProcessMediaKeyResponse failed.");
201    }
202    ```
203
20414. (可选)恢复离线媒体密钥。
205
206    ```c++
207    // 将指定媒体密钥标识的媒体密钥加载到当前会话。
208    ret = OH_MediaKeySession_RestoreOfflineMediaKeys(mediaKeySession, mediaKeyId, mediaKeyIdLen);
209    if (ret != DRM_ERR_OK) {
210        printf("OH_MediaKeySession_RestoreOfflineMediaKeys failed.");
211    }
212    ```
213
21415. (可选)检查媒体密钥状态。
215
216    ```c++
217    DRM_MediaKeyStatus mediaKeyStatus;
218    ret = OH_MediaKeySession_CheckMediaKeyStatus(mediaKeySession, &mediaKeyStatus);
219    if (ret != DRM_ERR_OK) {
220        printf("OH_MediaKeySession_CheckMediaKeyStatus failed.");
221    }
222    ```
223
22416. (可选)获取离线媒体密钥标识列表、获取离线媒体密钥状态与清除离线媒体密钥。
225
226    ```c++
227    DRM_OfflineMediakeyIdArray offlineMediaKeyIds;
228    ret = OH_MediaKeySystem_GetOfflineMediaKeyIds(mediaKeySystem, &offlineMediaKeyIds);
229    if (ret != DRM_ERR_OK) {
230        printf("OH_MediaKeySystem_GetOfflineMediaKeyIds failed.");
231    }
232    DRM_OfflineMediaKeyStatus OfflineMediaKeyStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN;
233    ret = OH_MediaKeySystem_GetOfflineMediaKeyStatus(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0], &OfflineMediaKeyStatus);
234    if (ret != DRM_ERR_OK) {
235        printf("OH_MediaKeySystem_GetOfflineMediaKeyStatus failed.");
236    }
237    ret = OH_MediaKeySystem_ClearOfflineMediaKeys(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0]);
238    if (ret != DRM_ERR_OK) {
239        printf("OH_MediaKeySystem_ClearOfflineMediaKeys failed.");
240    }
241    ```
242
24317. 销毁MediaKeySession实例。
244
245    ```c++
246    ret = OH_MediaKeySession_Destroy(mediaKeySession);
247    if (ret != DRM_ERR_OK) {
248        printf("OH_MediaKeySession_Destroy failed.");
249    }
250    ```
251
25218. 销毁MediaKeySystem实例。
253
254    ```c++
255    ret = OH_MediaKeySystem_Destroy(mediaKeySystem);
256    if (ret != DRM_ERR_OK) {
257        printf("OH_MediaKeySystem_Destroy failed.");
258    }
259    ```