Day by day OTT platforms are getting popular and along with that, it is increasing the fear of content security breaches. Ever amazed at

  • How do these platforms secure streaming content from piracy or content leakage?
  • How the content distributions are being controlled?

Initially, I had all these doubts and after diving deep I got introduced to DRM.

What is DRM?

DRM stands for Digital Rights Management. It is a system that uses various licenses, keys and encryption techniques to protect the digital contents and also ensures that only an authorized user can decrypt the file with the help of a decryption key. It allows the content providers to set different business rules and control who can consume their content. Check "How Netflix protects its content — Part 1 and Part 2" blogs added in the reference to understand the use and working of DRM in detail.
Before jumping to the DRM setup in native ExoPlayer, let me shed some light on the backend DRM setup.

Overview of backend setup for DRM:

We used Microsoft Azure Media Services(AMS) and their .NET APIs for the setup and to deliver MPEG-DASH media streams which are protected with Widevine DRM.
Note: Microsoft's PlayReady, Google's Widevine, and Apple's FairPlay are the trusted DRM technologies used on different platforms.
As displayed in the below image, when a user requests DRM-protected content, the player application requests a license from the AMS license service. The AMS first authenticates the request and then issues a license for the authorized player. The client player uses the decryption key present in the Widevine license to decrypt and stream the content. This entire process is encrypted and authorized.


Hence to play the DRM-protected video in ExoPlayer, I need the below URLs from the backend setup:

  1. Manifest URL (Media file URL)
  2. Widevine license URL
  3. JWT token (A way of authorizing users who make a decryption key request)

Enough talks! Let's set up the ExoPlayer to play the DRM-protected video.

DRM setup in Android ExoPlayer:

  1. Add ExoPlayer dependency in build.gradle:

    implementation 'com.google.android.exoplayer:exoplayer:2.10.1'
    
  2. Add PlayerView in the layout:

    <com.google.android.exoplayer2.ui.PlayerView
       android:id="@+id/player_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
    
  3. ExoPlayer supports different streaming methods, including MPEG-DASH, HLS, SmoothStreaming. As I'm performing DASH implementation in the project, hence I need to use DashMediaSource class and pass the manifestURL.

    MediaSourceFactory mediaSrcFactory = new DashMediaSource.Factory(this::newDefaultHttpDataSource);
    MediaSource targetMediaSource = mediaSrcFactory.createMediaSource(manifestURL);
    
  4. Before creating a media source we need to instantiate HttpMediaDrmCallback by adding the widevineURL in its constructor.
    HttpMediaDrmCallback helps to perform the Widevine license exchange.

    HttpMediaDrmCallback mediaDrmCallback = new HttpMediaDrmCallback(widevineURL, new DefaultHttpDataSourceFactory(userAgentString));
    DrmSessionManager drmSessionManager = new DefaultDrmSessionManager.Builder().build(mediaDrmCallback);
    mediaSrcFactory.setDrmSessionManager(drmSessionManager);
    
  5. The license server needs an authentication token before issuing the license. Hence while requesting a DRM license, we need to append the token authorization header in the request. Here I will be sending the jwtToken in the request with the help of HttpMediaDrmCallback instance.

    mediaDrmCallback.setKeyRequestProperty("Authorization", "Bearer="+jwtToken);
    

That's it!
Run the code and watch the DRM-protected video in the native ExoPlayer.

To play downloaded DRM encrypted video offline, the license needs to be cached or persisted in the player. Refer to the blog added in the reference to know more about utilizing offline licenses.

I have pushed a demo project on Github. I hope this article and demo project is helpful.
Thank you!

References: