1# DRM系统管理(C/C++) 2 3DRM系统管理(MediaKeySystem)支持MediaKeySystem实例管理、设备DRM证书申请与处理、会话实例管理、离线媒体密钥管理、获取DRM度量统计信息、设备属性等。在使用DRM Kit功能时,先查询设备是否支持对应DRM解决方案的DRM功能。在DRM Kit里DRM解决方案以插件形式存在,所以也叫DRM插件。 4 5## 开发步骤 6 7详细的API说明请参考[DRM API参考](../../reference/apis-drm-kit/_drm.md)。 8 91. 导入NDK相关接口,导入方法如下。 10 11 ```c++ 12 #include "multimedia/drm_framework/native_drm_common.h" 13 #include "multimedia/drm_framework/native_drm_err.h" 14 #include "multimedia/drm_framework/native_mediakeysession.h" 15 #include "multimedia/drm_framework/native_mediakeysystem.h" 16 ``` 17 182. 在CMake脚本中链接Drm NDK动态库。 19 20 ```txt 21 target_link_libraries(PUBLIC libnative_drm.so) 22 ``` 23 243. 查询设备是否支持对应DRM解决方案名称、媒体类型、安全保护级别的DRM解决方案。 25 26 ```c++ 27 bool isSupported = OH_MediaKeySystem_IsSupported3("com.clearplay.drm", "video/avc", CONTENT_PROTECTION_LEVEL_SW_CRYPTO); 28 if (isSupported != true) { 29 printf("The device does not support the content protection level."); 30 } 31 ``` 32 334.(可选)获取设备支持的DRM解决方案的名称和唯一标识的列表。 34 35 ```c++ 36 uint32_t count = 1; // count是当前设备实际支持的DRM插件的个数,用户根据实际情况设置 37 DRM_MediaKeySystemDescription descriptions[1]; 38 memset(descriptions, 0, sizeof(descriptions)); 39 Drm_ErrCode ret = OH_MediaKeySystem_GetMediaKeySystems(descriptions, &count); 40 if (ret != DRM_ERR_OK) { 41 printf("OH_MediaKeySystem_GetMediaKeySystems failed."); 42 } 43 ``` 44 455. 创建MediaKeySystem实例。 46 47 ```c++ 48 MediaKeySystem *mediaKeySystem = NULL; 49 Drm_ErrCode ret = OH_MediaKeySystem_Create("com.clearplay.drm", &mediaKeySystem); 50 if (ret != DRM_ERR_OK) { 51 printf("OH_MediaKeySystem_Create failed."); 52 } 53 ``` 54 556.(可选)声明MediaKeySystem事件监听回调。 56 57 ```c++ 58 // 适用于多个MediaKeySystem实例的场景 59 static Drm_ErrCode SystemCallBack(DRM_EventType eventType, uint8_t *info, int32_t infoLen, char *extra) 60 { 61 printf("SystemCallBack"); 62 } 63 // 适用于单个MediaKeySystem实例的场景。 64 static Drm_ErrCode SystemCallBackWithObj(MediaKeySystem *mediaKeySystem, DRM_EventType eventType, 65 uint8_t *info, int32_t infoLen, char *extra) 66 { 67 printf("TestSystemCallBackWithObj"); 68 } 69 ``` 70 717.(可选)设置MediaKeySystem事件监听回调。 72 73 ```c++ 74 // 适用于多个MediaKeySystem实例的场景 75 Drm_ErrCode ret = OH_MediaKeySystem_SetMediaKeySystemCallback(mediaKeySystem, SystemCallBack); 76 if (ret != DRM_ERR_OK) { 77 printf("OH_MediaKeySystem_SetMediaKeySystemCallback failed."); 78 } 79 80 // 适用于单个MediaKeySystem实例的场景。 81 ret = OH_MediaKeySystem_SetCallback(mediaKeySystem, SystemCallBackWithObj); 82 if (ret != DRM_ERR_OK) { 83 printf("OH_MediaKeySystem_SetCallback failed."); 84 } 85 ``` 86 878. 创建MediaKeySession会话实例。 88 89 ```c++ 90 MediaKeySession *mediaKeySession = nullptr; 91 DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO; 92 ret = OH_MediaKeySystem_CreateMediaKeySession(mediaKeySystem, &contentProtectionLevel, &mediaKeySession); 93 if (ret != DRM_ERR_OK || mediaKeySession == nullptr) { 94 printf("OH_MediaKeySystem_CreateMediaKeySession failed."); 95 } 96 ``` 97 989. 检查设备DRM证书状态,设备DRM证书不存在或状态异常,则生成设备DRM证书请求,处理设备DRM证书响应。 99 100 ```c++ 101 unsigned char request[12288] = { 0x00 }; // 设备DRM证书request最大长度为12288,按实际大小申请 102 int32_t requestLen = 12288; 103 // DRM服务URL的最大长度为2048 104 char defaultUrl[2048] = { 0x00 }; 105 int32_t defaultUrlLen = 2048; 106 DRM_CertificateStatus certStatus = CERT_STATUS_INVALID; 107 // 检查设备DRM证书状态 108 ret = OH_MediaKeySystem_GetCertificateStatus(mediaKeySystem, &certStatus); 109 if (ret == DRM_ERR_OK && certStatus == CERT_STATUS_NOT_PROVISIONED) { 110 ret = OH_MediaKeySystem_GenerateKeySystemRequest(mediaKeySystem, request, &requestLen, defaultUrl, 111 defaultUrlLen); 112 /* 113 应用通过网络请求,将设备DRM证书请求信息传到DRM服务获取设备DRM证书请求响应keySystemResponse, 114 再将设备DRM证书请求响应设置到设备上,请根据实际值和长度传入 115 */ 116 unsigned char KeySystemResponse[12288] = {0x00}; 117 ret = OH_MediaKeySystem_ProcessKeySystemResponse(mediaKeySystem, KeySystemResponse, sizeof(KeySystemResponse)); 118 if (ret != DRM_ERR_OK) { 119 printf("OH_MediaKeySystem_ProcessKeySystemResponse failed."); 120 } 121 } 122 ``` 123 12410. (可选)获取离线媒体密钥标识,获取离线媒体密钥状态、清理离线媒体密钥。 125 126 ```c++ 127 DRM_OfflineMediakeyIdArray offlineMediaKeyIds; 128 ret = OH_MediaKeySystem_GetOfflineMediaKeyIds(mediaKeySystem, &offlineMediaKeyIds); 129 if (ret != DRM_ERR_OK) { 130 printf("OH_MediaKeySystem_GetOfflineMediaKeyIds failed."); 131 } 132 DRM_OfflineMediaKeyStatus OfflineMediaKeyStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN; 133 ret = OH_MediaKeySystem_GetOfflineMediaKeyStatus(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0], &OfflineMediaKeyStatus); 134 if (ret != DRM_ERR_OK) { 135 printf("OH_MediaKeySystem_GetOfflineMediaKeyStatus failed."); 136 } 137 ret = OH_MediaKeySystem_ClearOfflineMediaKeys(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0]); 138 if (ret != DRM_ERR_OK) { 139 printf("OH_MediaKeySystem_ClearOfflineMediaKeys failed."); 140 } 141 ``` 142 14311. (可选)设置和获取DRM配置属性信息。 144 145 > **说明:** 146 > 147 > 不同的DRM方案的配置属性信息可能存在差别,支持的属性名包含:"vendor"、"version"、"description"、"algorithms"、"maxSessionNum"、"currentHDCPLevel"。需解决方案支持属性值设置能力才能设置DRM配置属性信息。 148 149 ```c++ 150 ret = OH_MediaKeySystem_SetConfigurationString(mediaKeySystem, "version", "2.0"); // 设置字符串类型的配置信息 151 if (ret == DRM_ERR_OK) { 152 printf("MediaKeySystem_SetConfigurationString success"); 153 } else { 154 printf("MediaKeySystem_SetConfigurationString failed. %d ", ret); 155 } 156 char value[32]; 157 int32_t valueLen = 32; 158 // 获取字符串类型的配置信息 159 ret = OH_MediaKeySystem_GetConfigurationString(mediaKeySystem, "version", value, valueLen); 160 if (ret == DRM_ERR_OK) { 161 printf("OH_MediaKeySystem_GetConfigurationString success"); 162 } else { 163 printf("OH_MediaKeySystem_GetConfigurationString failed. %d ", ret); 164 } 165 // 设置字符数组类型的配置信息,请根据实际数据和长度传入 166 uint8_t description[4] = {0x00, 0x00, 0x00, 0x00}; 167 ret = OH_MediaKeySystem_SetConfigurationByteArray(mediaKeySystem, "description", description, sizeof(description)/sizeof(uint8_t)); 168 if (ret == DRM_ERR_OK) { 169 printf("OH_MediaKeySystem_SetConfigurationByteArray success "); 170 } else { 171 printf("OH_MediaKeySystem_SetConfigurationByteArray failed. %d ", ret); 172 } 173 // 获取字符数组类型的配置信息,根据DRM解决方案实际情况填入 174 uint8_t descriptionValue[32]; 175 int32_t descriptionValueLen = 32; 176 ret = OH_MediaKeySystem_GetConfigurationByteArray(mediaKeySystem, "description", descriptionValue, &descriptionValueLen); 177 if (ret == DRM_ERR_OK) { 178 printf("OH_MediaKeySystem_GetConfigurationByteArray success "); 179 } else { 180 printf("OH_MediaKeySystem_GetConfigurationByteArray failed. %d ", ret); 181 } 182 ``` 183 18412. (可选)获取设备支持的最大内容保护级别。 185 186 ```c++ 187 DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_UNKNOWN; 188 ret = OH_MediaKeySystem_GetMaxContentProtectionLevel(mediaKeySystem, &contentProtectionLevel); 189 if (ret != DRM_ERR_OK) { 190 printf("OH_MediaKeySystem_GetMaxContentProtectionLevel failed."); 191 } 192 ``` 193 19413. 销毁MediaKeySession实例。 195 196 ```c++ 197 ret = OH_MediaKeySession_Destroy(mediaKeySession); 198 if (ret != DRM_ERR_OK) { 199 printf("OH_MediaKeySession_Destroy failed."); 200 } 201 ``` 202 20314. 销毁MediaKeySystem实例。 204 205 ```c++ 206 ret = OH_MediaKeySystem_Destroy(mediaKeySystem); 207 if (ret != DRM_ERR_OK) { 208 printf("OH_MediaKeySystem_Destroy failed."); 209 } 210 ```