Search code examples
androidazureexoplayerazure-media-servicesexoplayer2.x

Widevine Offline License Fetch with token from azure media services using exoplayer


I'm trying to implement offline playback for my android app using exoplayer, I'm using azure media services to do so.

I'm able to play, download, fetch offline widevine licenses and playback in offline without a problem.

my problem comes in when I need an authorization token, my content plays as intended when I add the token, but it fails to fetch an offline DRM license when I want to download it.

I'm using this function to do so in exoplayer

    OfflineLicenseHelper offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(
                     null,
                     false,
                     httpDataSourceFactory,
                     requestHeaders,
                     new DrmSessionEventListener.EventDispatcher());

keep in mind I'm setting null and false, based on the documentation because azure media services provides it's own license server in the manifest.

and this is the function's doc in the offline license helper

 /**
   * Instantiates a new instance which uses Widevine CDM. Call {@link #release()} when the instance
   * is no longer required.
   *
   * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
   *     their own license URL.
   * @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that
   *     include their own license URL.
   * @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
   *     to {@link MediaDrm#getKeyRequest}. May be null.
   * @param eventDispatcher A {@link DrmSessionEventListener.EventDispatcher} used to distribute
   *     DRM-related events.
   * @return A new instance which uses Widevine CDM.
   * @see DefaultDrmSessionManager.Builder
   */
  public static OfflineLicenseHelper newWidevineInstance(
      String defaultLicenseUrl,
      boolean forceDefaultLicenseUrl,
      HttpDataSource.Factory httpDataSourceFactory,
      @Nullable Map<String, String> optionalKeyRequestParameters,
      DrmSessionEventListener.EventDispatcher eventDispatcher) 

I'm sure my header is passing fine since I'm logging everything.

and this is the result of my request :

2020-10-13 09:44:19.143 29964-29964/com.videoplayer E/DownloadTracker: Failed to fetch offline DRM license
      com.google.android.exoplayer2.drm.DrmSession$DrmSessionException: com.google.android.exoplayer2.drm.MediaDrmCallbackException: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 401
        at com.google.android.exoplayer2.drm.DefaultDrmSession.onError(DefaultDrmSession.java:518)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.onKeysError(DefaultDrmSession.java:513)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.onKeyResponse(DefaultDrmSession.java:476)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.access$100(DefaultDrmSession.java:57)
        at com.google.android.exoplayer2.drm.DefaultDrmSession$ResponseHandler.handleMessage(DefaultDrmSession.java:557)

It's an authorization problem, but I'm not sure is it because of me passing the wrong data or it's because of azure media services?

if it's from azure, then how I'm able to play the stream with the exact same token ( which doesn't work if I change the token ) and not receive an offline license with the exact same token??

Any replies can be helpful, thank you.


Solution

  • Well , for anyone who is encountering the same problem, i solved it by setting the headers directly into the the httpDataSourceFactory , so here's the code that fixed it :

    httpDataSourceFactory.getDefaultRequestProperties().set("Authorization","Bearer=yourtokenhere");
          OfflineLicenseHelper offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(
              null,
                  false,
                         httpDataSourceFactory,
                         requestHeaders,
                          new DrmSessionEventListener.EventDispatcher());
          android.util.Log.d(TAG, "doInBackground rh : "+requestHeaders);
    

    Not sure why the request headers didn't work for me, but I would love to know why.