DRM Development (C/C++)
When to Use
DRM Kit provides C/C++ APIs for comprehensive digital rights management, covering certificate management, license management, content authorization, and content decryption.
Its implementation is built around two core classes: MediaKeySystem and MediaKeySession. MediaKeySystem handles system-level management of DRM certificates and licenses, as well as the lifecycle of MediaKeySession instances. MediaKeySession, in turn, is responsible for authorizing specific content and enabling its decryption through integration with AVCodec Kit for playback.
How to Develop
For details on the APIs, see DRM API.
-
Import the DRM Kit module.
#include "multimedia/drm_framework/native_drm_common.h" #include "multimedia/drm_framework/native_drm_err.h" #include "multimedia/drm_framework/native_mediakeysession.h" #include "multimedia/drm_framework/native_mediakeysystem.h" -
Link the dynamic libraries in the CMake script.
target_link_libraries(PUBLIC libnative_drm.so) -
Obtain the name and ID list of the DRM solutions supported by the device.
uint32_t count = 3; // count specifies the number of DRM plugins supported by the device. Pass in the actual number. DRM_MediaKeySystemDescription descriptions[3]; memset(descriptions, 0, sizeof(descriptions)); Drm_ErrCode ret = OH_MediaKeySystem_GetMediaKeySystems(descriptions, &count); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_GetMediaKeySystems failed."); } -
(Optional) Check whether the device supports a specific DRM solution based on the name, MIME type, and content protection level.
bool isSupported = OH_MediaKeySystem_IsSupported3("com.clearplay.drm", "video/mp4", CONTENT_PROTECTION_LEVEL_SW_CRYPTO); if (isSupported != true) { printf("The device does not support the content protection level."); } -
Create a MediaKeySystem instance.
MediaKeySystem *mediaKeySystem = nullptr; ret = OH_MediaKeySystem_Create("com.clearplay.drm", &mediaKeySystem); if (ret != DRM_ERR_OK || mediaKeySystem == nullptr) { printf("OH_MediaKeySystem_Create failed."); } -
(Optional) Set the MediaKeySystem event listener callback.
static Drm_ErrCode SystemCallBackWithObj(MediaKeySystem *mediaKeySystem, DRM_EventType eventType, uint8_t *info, int32_t infoLen, char *extra) { printf("SystemCallBackWithObj enter"); if (eventType == EVENT_PROVISION_REQUIRED) { // Request and process the DRM certificate. } return DRM_ERR_OK; } ret = OH_MediaKeySystem_SetCallback(mediaKeySystem, SystemCallBackWithObj); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_SetCallback failed."); } -
(Optional) Obtain the status of the DRM certificate.
DRM_CertificateStatus certStatus = CERT_STATUS_INVALID; // Check the DRM certificate status of the device. ret = OH_MediaKeySystem_GetCertificateStatus(mediaKeySystem, &certStatus); if (ret == DRM_ERR_OK && certStatus != CERT_STATUS_PROVISIONED) { // Request and process the DRM certificate. } -
(Optional) Generate a DRM certificate request and process its response.
#define MAX_DRM_PROVISION_BUF_SIZE 24576 // 24576: (2 * 12 * 1024) 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. int32_t requestLen = MAX_DRM_PROVISION_BUF_SIZE; // The maximum length of the DRM service URL is 2048. char defaultUrl[2048] = { 0x00 }; int32_t defaultUrlLen = 2048; ret = OH_MediaKeySystem_GenerateKeySystemRequest(mediaKeySystem, request, &requestLen, defaultUrl, defaultUrlLen); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_GenerateKeySystemRequest failed."); } /* The application sends a DRM certificate request to the DRM service through a network request, obtains a response, and sets the response to the device. Pass in the actual data and length. */ unsigned char keySystemResponse[MAX_DRM_PROVISION_BUF_SIZE] = {0x00}; ret = OH_MediaKeySystem_ProcessKeySystemResponse(mediaKeySystem, keySystemResponse, sizeof(keySystemResponse)); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_ProcessKeySystemResponse failed."); } -
(Optional) Obtain the maximum content protection level supported by the device.
DRM_ContentProtectionLevel maxContentProtectionLevel = CONTENT_PROTECTION_LEVEL_UNKNOWN; ret = OH_MediaKeySystem_GetMaxContentProtectionLevel(mediaKeySystem, &maxContentProtectionLevel); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_GetMaxContentProtectionLevel failed."); } -
Create a MediaKeySession instance.
MediaKeySession *mediaKeySession = nullptr; DRM_ContentProtectionLevel contentProtectionLevel = CONTENT_PROTECTION_LEVEL_SW_CRYPTO; // Set the content protection level supported by the device. ret = OH_MediaKeySystem_CreateMediaKeySession(mediaKeySystem, &contentProtectionLevel, &mediaKeySession); if (ret != DRM_ERR_OK || mediaKeySession == nullptr) { printf("OH_MediaKeySystem_CreateMediaKeySession failed."); } -
(Optional) Set the MediaKeySession event listener callback.
static Drm_ErrCode SessionEventCallBackWithObj(MediaKeySession *mediaKeySession, DRM_EventType eventType, uint8_t *info, int32_t infoLen, char *extra) { if (eventType == EVENT_KEY_REQUIRED) { // Request and process the media key. } return DRM_ERR_OK; } static Drm_ErrCode SessionKeyChangeCallBackWithObj(MediaKeySession *mediaKeySession, DRM_KeysInfo *keysInfo, bool hasNewGoodKeys) { return DRM_ERR_OK; } OH_MediaKeySession_Callback sessionCallback = { SessionEventCallBackWithObj, SessionKeyChangeCallBackWithObj }; ret = OH_MediaKeySession_SetCallback(mediaKeySession, &sessionCallback); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_SetCallback failed."); } -
(Optional) Check whether secure decoding is required.
bool requireSecureDecoder; ret = OH_MediaKeySession_RequireSecureDecoderModule(mediaKeySession, "video/avc", &requireSecureDecoder); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_RequireSecureDecoderModule failed."); } -
Generate a media key request and process its response to request a license for content authorization.
#define MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE 24576 // 24576: (2 * 12 * 1024) DRM_MediaKeyRequest mediaKeyRequest; DRM_MediaKeyRequestInfo info; // initData corresponds to PSSH data in the stream. Pass in the actual data. unsigned char initData[512] = {0x00}; memset(&info, 0, sizeof(DRM_MediaKeyRequestInfo)); info.initDataLen = sizeof(initData); info.type = MEDIA_KEY_TYPE_ONLINE; // MEDIA_KEY_TYPE_ONLINE: online media key request; MEDIA_KEY_TYPE_OFFLINE: offline media key request. memcpy(info.mimeType, (char *)"video/mp4", sizeof("video/mp4")); memcpy(info.initData, initData, sizeof(initData)); memcpy(info.optionName[0], (char *)"optionalDataName", sizeof("optionalDataName")); memcpy(info.optionData[0], (char *)"optionalDataValue", sizeof("optionalDataValue")); info.optionsCount = 1; ret = OH_MediaKeySession_GenerateMediaKeyRequest(mediaKeySession, &info, &mediaKeyRequest); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_GenerateMediaKeyRequest failed."); } /* The application requests the DRM service through the network, obtains a media key response, and sends the response to OH_MediaKeySession_ProcessMediaKeyResponse. 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. */ unsigned char mediaKeyId[128] = {0x00}; int32_t mediaKeyIdLen = 128; // MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE specifies the maximum length of a media key response. Pass in the actual length. unsigned char mediaKeyResponse[MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE] = {0x00}; int32_t mediaKeyResponseLen = MAX_DRM_MEDIA_KEY_RESPONSE_BUF_SIZE; ret = OH_MediaKeySession_ProcessMediaKeyResponse(mediaKeySession, mediaKeyResponse, mediaKeyResponseLen, mediaKeyId, &mediaKeyIdLen); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_ProcessMediaKeyResponse failed."); } -
(Optional) Restore offline media keys.
// Load the media key with the specified media key ID to the current session. ret = OH_MediaKeySession_RestoreOfflineMediaKeys(mediaKeySession, mediaKeyId, mediaKeyIdLen); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_RestoreOfflineMediaKeys failed."); } -
(Optional) Check the status of media keys.
DRM_MediaKeyStatus mediaKeyStatus; ret = OH_MediaKeySession_CheckMediaKeyStatus(mediaKeySession, &mediaKeyStatus); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_CheckMediaKeyStatus failed."); } -
(Optional) Obtain the IDs of offline media keys, obtain their status, and clear them.
DRM_OfflineMediakeyIdArray offlineMediaKeyIds; ret = OH_MediaKeySystem_GetOfflineMediaKeyIds(mediaKeySystem, &offlineMediaKeyIds); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_GetOfflineMediaKeyIds failed."); } DRM_OfflineMediaKeyStatus OfflineMediaKeyStatus = OFFLINE_MEDIA_KEY_STATUS_UNKNOWN; ret = OH_MediaKeySystem_GetOfflineMediaKeyStatus(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0], &OfflineMediaKeyStatus); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_GetOfflineMediaKeyStatus failed."); } ret = OH_MediaKeySystem_ClearOfflineMediaKeys(mediaKeySystem, offlineMediaKeyIds.ids[0], offlineMediaKeyIds.idsLen[0]); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_ClearOfflineMediaKeys failed."); } -
Destroy the MediaKeySession instance.
ret = OH_MediaKeySession_Destroy(mediaKeySession); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySession_Destroy failed."); } -
Destroy the MediaKeySystem instance.
ret = OH_MediaKeySystem_Destroy(mediaKeySystem); if (ret != DRM_ERR_OK) { printf("OH_MediaKeySystem_Destroy failed."); }