DRM authentication during playback

When the DRM metadata for a video is included in the media stream, perform authentication during playback.

Consider the license rotation feature, where an asset is encrypted with multiple DRM licenses. Each time that new DRM metadata is discovered, use DRMHelper methods to check whether the DRM metadata requires DRM authentication.

Note:

This tutorial does not handle domain bound licenses.Ideally, before starting playback, check whether you are dealing with a domain bound license. If yes, perform domain authentication (if needed) and join the domain.

  1. When new DRM Metadata is discovered in an asset, an event is dispatched at the application layer.
    mediaPlayer.addEventListener(MediaPlayer.Event.DRM, 
                                         new MediaPlayer.DRMEventListener() {
       public void onDRMMetadata(final DRMMetadataInfo drmMetadataInfo) {
       }
    });
  2. Use the DRMMetadata to check whether authentication is needed. If not, do nothing; playback continues uninterrupted.
  3. Otherwise, perform DRM authentication. Since this operation is asynchronous and is handled in a different thread, it has have no impact on the user interface nor on video playback.
  4. If authentication fails, the user cannot continue viewing the video and playback ceases. Otherwise, playback will continue uninterruptedly.
private final MediaPlayer.DRMEventListener drmEventListener = new
MediaPlayer.DRMEventListener() {
   @Override
   public void onDRMMetadata(final DRMMetadataInfo drmMetadataInfo) {
       Log.i(LOG_TAG + "::MediaPlayer.DRMEventListener#onDRMMetadata", 
                       "DRM metadata available: " + drmMetadataInfo + ".");
       if (drmMetadataInfo == null ||
!DRMHelper.isAuthNeeded(drmMetadataInfo.getDRMMetadata())) {
           Log.i(LOG_TAG + "#onDRMMetadata", "DRM auth is not needed.");
           return;
       }
       // Perform DRM auth.
       // Possible logic might take into consideration a threshold between 
       // the current player time and the
       // DRM metadata start time. For the time being, we resolve it as soon 
       // as we receive the DRM metadata.
       DRMManager drmManager = mediaPlayer.getDRMManager();
       if (drmManager == null) {
           Log.e(LOG_TAG + "#onDRMMetadata", "DRMManager is null.");
           return;
       }
       DRMHelper.performDrmAuthentication(drmManager, 
                                          drmMetadataInfo.getDRMMetadata(), 
                                          CatalogActivity.DRM_USERNAME, 
                                          CatalogActivity.DRM_PASSWORD, 
                                          new DRMAuthenticationListener()
{
   @Override
   public void onAuthenticationStart() {
         metadata at ["Log.i(LOG_TAG + "#onAuthenticationStart", 
                  "DRM authentication started for DRM metadata at [" 
                   + drmMetadataInfo.getPrefetchTimestamp() + "].");
   }
   @Override
   public void onAuthenticationError(long majorCode, long minorCode, Exception e) {
        Log.e(LOG_TAG + "#onAuthenticationError", 
           "DRM authentication failed. " + majorCode + " 0x" + Long.toHexString(minorCode));
       handler.post(new Runnable() {
           @Override
           public void run() {
                      showToast(getString(R.string.drmAuthenticationError));
           finish();
           }
       });
   }

   @Override
   public void onAuthenticationComplete(byte[] authenticationToken) {
       Log.i(LOG_TAG + "#onAuthenticationComplete", 
            "Auth successful for DRM metadata at [" 
               + drmMetadataInfo.getPrefetchTimestamp() + "].");
           }
       });
   }
};