1# DRM Development (C/C++) 2 3## When to Use 4 5You can call the C/C++ APIs of DRM Kit to implement digital copyright protection features such as DRM certificate management, DRM license management, DRM content authorization, and DRM content decryption. 6 7DRM Kit provides MediaKeySystem to manage DRM certificates, DRM licenses, and MediaKeySession instances. MediaKeySession is responsible for authorizing DRM content and can work with Media Kit or AVCodec Kit to decrypt the DRM content, thereby enabling playback of DRM-protected content. 8 9## How to Develop 10 11Read [DRM](../../reference/apis-drm-kit/capi-drm.md) for the API reference. 12 131. Import the DRM Kit module. 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. Link the dynamic libraries in the CMake script. 23 24 ```txt 25 target_link_libraries(PUBLIC libnative_drm.so) 26 ``` 27 283. Obtain the name and ID list of the DRM solutions supported by the device. 29 30 ```c++ 31 uint32_t count = 3; // count indicates the number of DRM plugins supported by the device. Pass in the actual number. 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. (Optional) Check whether the device supports the specified DRM solution based on the name, MIME type, and content protection level. 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. Create a MediaKeySystem instance. 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. (Optional) Set the MediaKeySystem event listener callback. 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 // Request and process the DRM certificate. 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. (Optional) Obtain the status of the DRM certificate. 79 80 ```c++ 81 DRM_CertificateStatus certStatus = CERT_STATUS_INVALID; 82 // Check the DRM certificate status of the device. 83 ret = OH_MediaKeySystem_GetCertificateStatus(mediaKeySystem, &certStatus); 84 if (ret == DRM_ERR_OK && certStatus != CERT_STATUS_PROVISIONED) { 85 // Request and process the DRM certificate. 86 } 87 ``` 88 898. (Optional) Generate a DRM certificate request and process its response. 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 }; // MAX_DRM_PROVISION_BUF_SIZE specifies the maximum length of a DRM certificate request. Apply for memory based on the actual length. 94 int32_t requestLen = MAX_DRM_PROVISION_BUF_SIZE; 95 // The maximum length of the DRM service URL is 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 The application sends a DRM certificate request to the DRM service through a network request, obtains a response, 105 and sets the response to the device. Pass in the actual data and length. 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. (Optional) Obtain the maximum content protection level supported by the device. 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. Create a MediaKeySession instance. 125 126 ```c++ 127 MediaKeySession *mediaKeySession = nullptr; 128 DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO; // Set the content protection level supported by the device. 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. (Optional) Set the MediaKeySession event listener callback. 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 // Request and process the media key. 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. (Optional) Check whether secure decoding is required. 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. Generate a media key request and process its response to request a license for DRM content authorization. 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 corresponds to PSSH data in the stream. Pass in the actual data. 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: online media key request; MEDIA_KEY_TYPE_OFFLINE: offline media key request. 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 The application requests the DRM service through the network, obtains a media key response, and sends the response to OH_MediaKeySession_ProcessMediaKeyResponse. 190 If the response is an offline media key response, the offline media key ID is returned. Set mediaKeyId based on the actual data and length. 191 */ 192 unsigned char mediaKeyId[128] = {0x00}; 193 int32_t mediaKeyIdLen = 128; 194 // MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE specifies the maximum length of a media key response. Pass in the actual length. 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. (Optional) Restore offline media keys. 205 206 ```c++ 207 // Load the media key with the specified media key ID to the current session. 208 ret = OH_MediaKeySession_RestoreOfflineMediaKeys(mediaKeySession, mediaKeyId, mediaKeyIdLen); 209 if (ret != DRM_ERR_OK) { 210 printf("OH_MediaKeySession_RestoreOfflineMediaKeys failed."); 211 } 212 ``` 213 21415. (Optional) Check the status of media keys. 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. (Optional) Obtain the IDs of offline media keys, obtain their status, and clear the keys. 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. Destroy the MediaKeySession instance. 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. Destroy the MediaKeySystem instance. 253 254 ```c++ 255 ret = OH_MediaKeySystem_Destroy(mediaKeySystem); 256 if (ret != DRM_ERR_OK) { 257 printf("OH_MediaKeySystem_Destroy failed."); 258 } 259 ``` 260