• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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