Adding Widevine encrypted playback

To add playback of Widevine protected content to the player:

  1. Add the dependency com.google.protobuf:protobuf-java:3.9.2:

    dependencies {
       implementation fileTree(dir: 'libs', include: ['*.aar'])
       implementation 'androidx.appcompat:appcompat:1.0.2'
       implementation 'com.google.protobuf:protobuf-java:3.9.2'
    }
    
  2. In the MainActivity.java file, add the following imports:

    import java.util.HashMap;
    import java.util.Map;
    import nagra.otv.sdk.OTVVideoView;
    import nagra.otv.sdk.drm.OTVHttpMediaDrmCallback;
    
  3. Replace the following code:

    static final String TAG = "MainActivity";
       private OTVVideoView mOTVVideoView = null;
       private int mPausePos = 0;
       private String mVideoURI = "https://d3bqrzf9w11pn3.cloudfront.net/basic_dash_bbb_clear/bbb_public.mpd";
    
       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           OTVSDK.load(this);
           setContentView(R.layout.activity_main);
           mOTVVideoView = findViewById(R.id.otvVideoView);
       }
    
       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
           // Inflate the menu; this adds items to the action bar if it is present.
           getMenuInflater().inflate(R.menu.menu_main, menu);
           return true;
       }
    

    With:

    private OTVVideoView mOTVVideoView = null;
    private int mPausePos = 0;
    private final String STREAM_URI = "https://d3bqrzf9w11pn3.cloudfront.net/basic_dash_bbb_encrypted/bbb_public_android.mpd";
    private final String STREAM_TOKEN = "eyJraWQiOiI4MTI0MjUiLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXIiOiIxLjAiLCJ0eXAiOiJDb250ZW50QXV0aFoiLCJjb250ZW50UmlnaHRzIjpbeyJkdXJhdGlvbiI6NzIwMCwiZGVmYXVsdEtjSWRzIjpbIjAyMDgxMTNlLWU2ZTgtNDI0Mi04NjdjLWQ5NjNmNWQ3ODkyMyJdLCJjb250ZW50SWQiOiI0NjgyZjFkNi05ODIwLTQwNmEtOWJhMC03YzAzZGJjZjE5NmMiLCJzdG9yYWJsZSI6dHJ1ZSwiZW5jcnlwdGlvbk1ldGhvZCI6IlJBV19BRVNfMTI4X0NUUl9DRU5DIiwiZGVmYXVsdFVzYWdlUnVsZXMiOnsibWluTGV2ZWwiOjAsIndhdGVybWFya2luZ0VuYWJsZWQiOnRydWUsImltYWdlQ29uc3RyYWludCI6dHJ1ZSwiaGRjcFR5cGUiOiJUWVBFXzEiLCJ1bmNvbXByZXNzZWREaWdpdGFsQ2FwcGluZ1Jlc29sdXRpb24iOiJOT19SRVNUUklDVElPTlMiLCJ1bnByb3RlY3RlZEFuYWxvZ091dHB1dCI6dHJ1ZSwiYW5hbG9nQ2FwcGluZ1Jlc29sdXRpb24iOiJOT19SRVNUUklDVElPTlMiLCJoZGNwIjp0cnVlLCJkZXZpY2VDYXBwaW5nUmVzb2x1dGlvbiI6Ik5PX1JFU1RSSUNUSU9OUyIsImRpZ2l0YWxPbmx5IjpmYWxzZSwidW5wcm90ZWN0ZWREaWdpdGFsT3V0cHV0Ijp0cnVlfX1dfQ.fZpotjTjiddueE_nPVcON0FnJwBO4FecTcYIoMmocnw,eyJrY0lkcyI6WyIwMjA4MTEzZS1lNmU4LTQyNDItODY3Yy1kOTYzZjVkNzg5MjMiXSwidHlwIjoiSldUIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImFsZyI6ImRpciIsImtpZCI6IjgxMjQyNSJ9..ntJUOAc-g8sXrGLjZhx-MQ.nHnm-aciNeCz6kwUZEjOQgg-1PsLN1Uc8eYihUv_OUK8EaBoFH7JcdIyB9igEFfR9Cufau_5H-EvTdrmws20_ViWKjUTOZmUn7xPQOmwSftb99-rgd3g4QZO0quHIDB5qiBoKmksts8qDbcMZbr_aKMFIOlzNUUcBwiOvmrGyzo.-zTh5sY7tmbe7Ow94EQT9A";
    
    private final String DRM_URI = "https://vsd02fy1.anycast.nagra.com/VSD02FY1/wvls/contentlicenseservice/v1/licenses";
    private final Map<String, String> DRM_HEADERS = new HashMap<>();
    {
     // Server headers
     DRM_HEADERS.put("Accept", "application/octet-stream");
     DRM_HEADERS.put("Content-Type", "application/octet-stream");
     DRM_HEADERS.put("nv-tenant-id", "UEX3XJ0I");
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     OTVSDK.load(this);
     setContentView(R.layout.activity_main);
     mOTVVideoView = findViewById(R.id.otvVideoView);
     mOTVVideoView.setMediaDrmCallback(mDrmCallback);
     mOTVVideoView.setVideoPath(STREAM_URI);
    
    }
    
    private OTVHttpMediaDrmCallback mDrmCallback = new OTVHttpMediaDrmCallback(DRM_URI);
    {
     for (Map.Entry<String, String> pair : DRM_HEADERS.entrySet()) {
       mDrmCallback.setKeyRequestProperty(pair.getKey(), pair.getValue());
     }
    
     mDrmCallback.setKeyRequestProperty("nv-authorizations", STREAM_TOKEN);
    }
    

Next step: Run the app