E/DefaultDrmSession: DRM session error java.lang.IllegalArgumentException: Failed to restore keys

Viewed 159

Issue

The DRM protected video downloaded successfully to local storage. When try to play the video from local storage the exo-player throw DRMSession error as mention below. Is there way to debug DRM find why its "Failed to restore keys"

Expected Result

Locally downloaded should player properly

ExoPlayer Version

2.14.2

Devices that reproduce the issue

  • Nokia G20 running Android 11.
  • Realme 5 Pro running Android 10

Exception Log

E/DefaultDrmSession: DRM session error
      java.lang.IllegalArgumentException: Failed to restore keys
        at android.media.MediaDrm.restoreKeys(Native Method)
        at com.google.android.exoplayer2.drm.FrameworkMediaDrm.restoreKeys(FrameworkMediaDrm.java:262)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.restoreKeys(DefaultDrmSession.java:437)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.doLicense(DefaultDrmSession.java:401)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.acquire(DefaultDrmSession.java:294)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSession(DefaultDrmSessionManager.java:775)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSessionWithRetry(DefaultDrmSessionManager.java:684)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:563)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:510)
        at com.google.android.exoplayer2.source.SampleQueue.onFormatResult(SampleQueue.java:918)
        at com.google.android.exoplayer2.source.SampleQueue.peekSampleMetadata(SampleQueue.java:686)
        at com.google.android.exoplayer2.source.SampleQueue.read(SampleQueue.java:412)
        at com.google.android.exoplayer2.source.chunk.ChunkSampleStream.readData(ChunkSampleStream.java:398)
        at com.google.android.exoplayer2.BaseRenderer.readSource(BaseRenderer.java:395)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:996)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:830)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:945)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:478)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)
E/VideoDisplayComponent: onDrmSessionManagerError
    java.lang.IllegalArgumentException: Failed to restore keys
        at android.media.MediaDrm.restoreKeys(Native Method)
        at com.google.android.exoplayer2.drm.FrameworkMediaDrm.restoreKeys(FrameworkMediaDrm.java:262)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.restoreKeys(DefaultDrmSession.java:437)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.doLicense(DefaultDrmSession.java:401)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.acquire(DefaultDrmSession.java:294)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSession(DefaultDrmSessionManager.java:775)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.createAndAcquireSessionWithRetry(DefaultDrmSessionManager.java:684)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:563)
        at com.google.android.exoplayer2.drm.DefaultDrmSessionManager.acquireSession(DefaultDrmSessionManager.java:510)
        at com.google.android.exoplayer2.source.SampleQueue.onFormatResult(SampleQueue.java:918)
        at com.google.android.exoplayer2.source.SampleQueue.peekSampleMetadata(SampleQueue.java:686)
        at com.google.android.exoplayer2.source.SampleQueue.read(SampleQueue.java:412)
        at com.google.android.exoplayer2.source.chunk.ChunkSampleStream.readData(ChunkSampleStream.java:398)
        at com.google.android.exoplayer2.BaseRenderer.readSource(BaseRenderer.java:395)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.readSourceOmittingSampleData(MediaCodecRenderer.java:996)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:830)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:945)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:478)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:223)
        at android.os.HandlerThread.run(HandlerThread.java:67)
1 Answers

One quick note first - you need to make sure your DRM license supports offline playback, or persistence. Your DRM provider should be able to help confirm or configure this.

Assuming this is the case, then ExoPlayer requires you to manage the offline licenses using it's OfflineLicenseHelper.

There is an up to date examples of this in the ExoPlayer demo code on GitHub - look at: https://github.com/google/ExoPlayer/blob/03569f9e6536e6c60cb585115d6d7352a4deab71/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java

(ExoPlayer/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java /)

If you look at the 'WidevineOfflineLicenseFetchTask' you can see the synch fetching of the offline license:

    protected Void doInBackground(Void... voids) {
      OfflineLicenseHelper offlineLicenseHelper =
          OfflineLicenseHelper.newWidevineInstance(
              drmConfiguration.licenseUri.toString(),
              drmConfiguration.forceDefaultLicenseUri,
              dataSourceFactory,
              drmConfiguration.licenseRequestHeaders,
              new DrmSessionEventListener.EventDispatcher());
      try {
        keySetId = offlineLicenseHelper.downloadLicense(format);
      } catch (DrmSession.DrmSessionException e) {
        drmSessionException = e;
      } finally {
        offlineLicenseHelper.release();
      }
      return null;
    }
Related