目录

Key APIs of the Client

The WisePlay DRM client APIs are implemented based on the third-party framework APIs. For details about the API definition, please refer to MediaDrm and MediaCodec.

The key APIs of the MediaDrm are as follows:

openSession

getKeyRequest

provideKeyResponse

restoreKeys

queryKeyStatus

isCryptoSchemeSupported

The key APIs of the MediaCodec are as follows:

configure

dequeueInputBuffer

queueSecureInputBuffer

dequeueOutputBuffer

releaseOutputBuffer

Creating a MediaDRM Object

  1. Check whether the UUID of WisePlay DRM is supported.

  2. Create a MediaDrm object and transfer the UUID of WisePlay DRM. The UUID indicates the globally unique ID of each DRM type. For the WisePlay DRM, the UUID is 3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c.

  3. Call the openSession method to open a session.

Sample code:

  1. UUID WISEPLAY_DRM_UUID = new UUID(0x3d5e6d359b9a41e8L, 0xb843dd3c6e72c42cL);
  2. if(MediaDrm.isCryptoSchemeSupported(WISEPLAY_DRM_UUID)){
  3.    MediaDrm mediaDrm = null;
  4.    try {
  5.        mediaDrm = new MediaDrm(WISEPLAY_DRM_UUID);
  6.        mediaDrm.openSession();
  7.    } catch (UnsupportedSchemeException e) {
  8.        e.printStackTrace();
  9.    } catch (ResourceBusyException e) {
  10.        e.printStackTrace();
  11.    } catch (NotProvisionedException e) {
  12.        e.printStackTrace();
  13.    }
  14. }

Obtaining a License

  1. Create a MediaDRM object and pass the UUID of WisePlay DRM.

  2. Call the openSession method of the MediaDRM to open a session and obtain sessionId.

  3. Call getKeyRequest of MeidaDrm to obtain the KeyRequest object in the license request message body. The input parameters are described as follows:

    −  sessionId: session ID returned by the openSession method.

    −   initData: If KeyType is set to MediaDrm.KEY_TYPE_STREAMING or MediaDrm.KEY_TYPE_OFFLINE, set initData to the value of psshbox. The value of pssh box can be obtained from a media index file. (The value is obtained from the MPD file for Dash streams and from M3U8 file for HLS streams.) If keyType is set to MediaDrm.KEY_TYPE_RELEASE, the initData parameter can be left empty.

    −   mimeType: media type. If the Android API level is lower than 26 and mimeType is set to the media type of a video or an audio, value cenc is returned. For other versions, mimeType is returned by default. If keyType is set to KEY_TYPE_RELEASE, the mimeType parameter can be left empty.

    −   keyType: To obtain an offline license, set this parameter to MediaDrm.KEY_TYPE_STREAMING. To obtain an offline license, set this parameter to MediaDrm.KEY_TYPE_OFFLINE. To delete a license, set this parameter to MediaDrm.KEY_TYPE_RELEASE.

    −   optionalParameters: Leave this parameter empty.

  4. Send a license request online to the server in POST mode. Set Content-Type in the request header to application/json and the request body to the data obtained by using the getData method of KeyRequest in the preceding step.

  5. After receiving a response from the server, use the provideKeyResponse method to transfer the content of the WisePlay DRM Server response transparently transmitted by the server to the underlying plug-in. The input parameter is the byte array of the license data obtained from the server.

    Sample code:

  1. UUID WISEPLAY_DRM_UUID = new UUID(0x3d5e6d359b9a41e8L, 0xb843dd3c6e72c42cL);
  2. MediaDrm mediaDrm = null;
  3. try {
  4.    mediaDrm = new MediaDrm(WISEPLAY_DRM_UUID);
  5.    byte[] sessionId = mediaDrm.openSession();
  6.    String PSSH_BOX = "AAAAY3Bzc2gBAAAAPV5tNZuaQei4Q908bnLELAAAAAPNI3qKPeyxmFVnqmWqx5pmxpmL7+8Am67T7xI7qk7vVncfJnvmvqyBLvozK5iuE84AAAAPcXZhc2pGU2ZkZ2Zqc1ZD";
  7.    byte[] initData = Base64.decode(PSSH_BOX, Base64.DEFAULT);
  8.    String mimeType = "video/mp4";
  9.    //... The initData needs to parse the information from the movie.
  10.    MediaDrm.KeyRequest keyRequest = mediaDrm.getKeyRequest(sessionId, initData, mimeType, MediaDrm.KEY_TYPE_STREAMING, null);
  11.    // Start the license request.
  12.    // Set content-type to application/json
  13.    byte [] data = keyRequest.getData();
  14.    // Use license url and data to request the license.
  15.    URL url = new URL(licenseServerUrl);
  16.    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  17.    connection.setRequestMethod("POST");
  18.    connection.setDoOutput(true);
  19.    connection.setDoInput(true);
  20.    connection.setRequestProperty("content-type", "application/json");
  21.    connection.connect();
  22.    String body = "{\"payload\":\""+new String(data , UTF_8)+"\",\"psshBox\":\""+initData+"\",\"keyType\":\""+MediaDrm.KEY_TYPE_STREAMING+"\"}";
  23.    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
  24.    writer.write(body);
  25.    writer.close();
  26.    int responseCode = connection.getResponseCode();
  27.    if (responseCode == HttpURLConnection.HTTP_OK) {
  28.        InputStream inputStream = connection.getInputStream();
  29.        byte[] response = toByteArray(inputStream);
  30.        inputStream.close();
  31.        connection.disconnect();
  32.        mediaDrm.provideKeyResponse(sessionId, response);
  33.    }
  34. } catch (UnsupportedSchemeException | ResourceBusyException | NotProvisionedException | IOException | DeniedByServerException e) {
  35.    e.printStackTrace();
  36. }

Decrypting Content

  1. Create a MediaCrypto object and pass the UUID of WisePlay DRM and sessionId that has been obtained.

  2. Create a MediaCodec object, call the configure method to configure the object, and pass the MediaCrypto object that has been created.

  3. Parses media data and creates a CryptoInfo object based on the obtained data. The object data encapsulates the metadata described in ISO/IEC FDIS 23001-7:2016 "Common encryption in ISO base media file format files" .

  4. Call dequeueInputBuffer of MediaCodec to apply for an empty buffer from an input buffer queue.

  5. Copy each frame of data to be decoded to the empty buffer, and call queueSecureInputBuffer of MediaCodec to place the data in the input buffer queue.

  6. Use MediaCodec to obtain the frame of data from the input buffer queue for decoding. After the decoding, MediaCodec sets the original data buffer to empty again, places the buffer back to the input buffer queue, and places the decoded data in the output buffer queue.

  7. Call dequeueOutputBuffer of MediaCodec to obtain the decoded data buffer from the output buffer queue.

  8. Call releaseOutputBuffer of MediaCodeC to render or play the decoded buffer. After the rendering or playback, release the buffer back to the output buffer queue.

Managing an Offline License

1.Obtain offline license information.

  1.  After obtaining an offline license, call the provideKeyResponse method to query keySetId, unique ID of the offline license. Keep it secure for subsequent use.

  2. Call restoreKeys of MediaDrm and pass keySetId. The offline license can be used later. If the license has expired or keySetid does not exist, restoreKeys fails to be called. In this case, the client needs to apply for a new license from the server.

  3. Use the queryKeyStatus method of MediaDrm to query the remaining playback duration and remaining validity period of the license.

     Sample code:

  1. UUID WISEPLAY_DRM_UUID = new UUID(0x3d5e6d359b9a41e8L, 0xb843dd3c6e72c42cL);  
  2. MediaDrm mediaDrm = null;
  3. try {
  4.    mediaDrm = new MediaDrm(WISEPLAY_DRM_UUID);
  5.    byte[] sessionId = mediaDrm.openSession();
  6.    // The keySetId of the offline license has been downloaded.
  7.    boolean restoerKeys = restoreKeys(sessionId, keySetId);
  8.    if (restoerKeys){
  9.        HashMap<String, String>licenseStatus = mediaDrm.queryKeyStatus(keySetId);
  10.        // Remaining duration for playing a license.
  11.        long playbackDuration = Long.parseLong(licenseStatus.get("PlaybackDurationRemaining"));
  12.        // Remaining license duration
  13.        long licenseDuration = Long.parseLong(licenseStatus.get("LicenseDurationRemaining"));
  14.    } else{
  15.        // Delete the cache of the license association relationship.
  16.    }
  17. } catch (UnsupportedSchemeException e) {
  18.    e.printStackTrace();
  19. } catch (ResourceBusyException e) {
  20.    e.printStackTrace();
  21. } catch (NotProvisionedException e) {
  22.    e.printStackTrace();
  23. }
  24. public boolean restoreKeys(byte[] sessionId, byte[] keySetId) {
  25.    try {
  26.        mediaDrm.restoreKeys(sessionId, keySetId);
  27.        return true;
  28.    } catch (Exception e){
  29.        return false;
  30.    }
  31. }

2.Delete the offline license.

  1. The process is the same as that in Obtaining a License. The difference lies in the input parameter for calling the getKeyRequest API of MediaDRM.

     Sample code:

  1. UUID WISEPLAY_DRM_UUID = new UUID(0x3d5e6d359b9a41e8L, 0xb843dd3c6e72c42cL);
  2. MediaDrm mediaDrm = null;
  3. try {
  4.    mediaDrm = new MediaDrm(WISEPLAY_DRM_UUID);
  5.    byte[] sessionId = mediaDrm.openSession();
  6.    //... The initData needs to parse the information from the movie.
  7.    MediaDrm.KeyRequest keyRequest = mediaDrm.getKeyRequest(keySetId, null, null, MediaDrm.KEY_TYPE_RELEASE, null);
  8.    // Start the license request.
  9.    //  Set content-type to application/json
  10.    byte [] data = keyRequest.getData();
  11.    // Use license url and data to request the license.
  12.    URL url = new URL(licenseServerUrl);
  13.    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  14.    connection.setRequestMethod("POST");
  15.    connection.setDoOutput(true);
  16.    connection.setDoInput(true);
  17.    connection.setRequestProperty("content-type", "application/json");
  18.    connection.connect();
  19.    String body = "{\"payload\":\""+new String(data , UTF_8)+"\",\"psshBox\":\""+initData+"\",\"keyType\":\""+MediaDrm.KEY_TYPE_RELEASE+"\"}";
  20.    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
  21.    writer.write(body);
  22.    writer.close();
  23.    int responseCode = connection.getResponseCode();
  24.    if (responseCode == HttpURLConnection.HTTP_OK) {
  25.        InputStream inputStream = connection.getInputStream();
  26.        byte[] response = toByteArray(inputStream);
  27.        inputStream.close();
  28.        connection.disconnect();
  29.        mediaDrm.provideKeyResponse(sessionID, response);
  30.    }
  31. } catch (UnsupportedSchemeException e) {
  32.    e.printStackTrace();
  33. } catch (ResourceBusyException e) {
  34.    e.printStackTrace();
  35. } catch (NotProvisionedException e) {
  36.    e.printStackTrace();
  37. }

3.Play content using the offline license.

  1.  Use the restoreKeys method of MediaDrm to pass sessionId and keySetId of the license to determine whether the license can be restored. If so, go to the next step. Otherwise, delete the locally cached license association.

  2. If the license has expired, do not initialize the codec.

4.Listen to the offline license during playback.

  1.  Use the setOnEventListener method of MediaDrm to set a listener.

  2. If the event of the listener is specified by MediaDrm.EVENT_KEY_REQUIRED, the license is about to expire (this event is triggered when the license is about to expire in 30 seconds).

  3. If the event of the listener is specified by MediaDrm.EVENT_KEY_EXPIRED, the license has expired.

  4. If the license is about to expire, the service can determine whether to trigger the license application process.