How do I get ExoPlayer to play DRM PlayReady content?

1.6k Views Asked by At

I'm unable to get DRM Playready content running through the ExoPlayer framework. I think it has something to do with my drmSessionManager

Both the manifestUrl and LicenseUrl have been tested to work but it's hard to implement my changes as there are no real concrete examples implementing any DRM content(WideVine or PlayReady)

Normal Dash content works with the ExoPlayer but when I try to play any DRM protected content, it fails.

        DataSource.Factory dataSourceFactory =
                new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "ExoPlayerDASHPR"));
        try {
            drmSessionManager = buildDrmSessionManager(C.PLAYREADY_UUID, drmLicenseUrl, true);
        } catch (Exception e) {
            System.out.println(e);
        }

        player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this), new DefaultTrackSelector(), drmSessionManager);
        playerView.setPlayer(player);




        DashMediaSource mediaSource = new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(dataSourceFactory), dataSourceFactory).createMediaSource(manifestUri);
        player.prepare(mediaSource);
        player.setPlayWhenReady(true);
    }

Method to build the actual drmSessionManager (where I think the problem lies)

private DefaultDrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManager(
            UUID uuid, String licenseUrl, boolean multiSession)
            throws UnsupportedDrmException {
        HttpMediaDrmCallback httpMediaDrmCallback =  new HttpMediaDrmCallback(licenseUrl,
                new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "ExoPlayerDASHPR")));
        releaseMediaDrm();
        mediaDrm = FrameworkMediaDrm.newInstance(uuid);
        return new DefaultDrmSessionManager<>(uuid, mediaDrm, httpMediaDrmCallback, null, multiSession);
    }

Expecting it to play the PlayReady content via my WebView in the Android device. I am 100% sure the device supports PlayReady as it's a NVidia Shield.

Error messages below.

2019-10-18 09:56:18.272 31508-31555/com.example.exoplayer_dashpr E/ExoPlayerImplInternal: Playback error.
    com.google.android.exoplayer2.ExoPlaybackException
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.shouldWaitForKeys(MediaCodecRenderer.java:842)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:739)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:574)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:518)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:301)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:193)
        at android.os.HandlerThread.run(HandlerThread.java:65)
     Caused by: com.google.android.exoplayer2.drm.DrmSession$DrmSessionException: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 500
        at com.google.android.exoplayer2.drm.DefaultDrmSession.onError(DefaultDrmSession.java:422)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.onKeysError(DefaultDrmSession.java:417)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.onKeyResponse(DefaultDrmSession.java:379)
        at com.google.android.exoplayer2.drm.DefaultDrmSession.access$100(DefaultDrmSession.java:41)
        at com.google.android.exoplayer2.drm.DefaultDrmSession$PostResponseHandler.handleMessage(DefaultDrmSession.java:472)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193) 
        at android.os.HandlerThread.run(HandlerThread.java:65) 
     Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 500
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:211)
        at com.google.android.exoplayer2.upstream.DataSourceInputStream.checkOpened(DataSourceInputStream.java:102)
        at com.google.android.exoplayer2.upstream.DataSourceInputStream.read(DataSourceInputStream.java:82)
        at com.google.android.exoplayer2.upstream.DataSourceInputStream.read(DataSourceInputStream.java:76)
        at com.google.android.exoplayer2.util.Util.toByteArray(Util.java:128)
        at com.google.android.exoplayer2.drm.HttpMediaDrmCallback.executePost(HttpMediaDrmCallback.java:159)
        at com.google.android.exoplayer2.drm.HttpMediaDrmCallback.executeKeyRequest(HttpMediaDrmCallback.java:134)
        at com.google.android.exoplayer2.drm.DefaultDrmSession$PostRequestHandler.handleMessage(DefaultDrmSession.java:503)
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.os.HandlerThread.run(HandlerThread.java:65) 
1

There are 1 best solutions below

0
On

In this case ExoPlayer appears to be working properly - the request to the license server is being sent and the response is being received.

The problem is that the server is sending a response indicating that there is an error at its end.

This might be because of some internal error, but is much more likely to be because some credentials passed to the server, e.g. a token providing entitlement information, was invalid or missing, or the keyid in the manifest or media stream is incorrect.

DRM servers tend to not give particularly verbose or detailed error message in response, to guard against attacks which send in repeated incorrect requests to try to learn about the servers security mechanisms.