Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to play ClearKey encrypted DASH #3201

Closed
androidsoni opened this issue Aug 22, 2017 · 21 comments
Closed

How to play ClearKey encrypted DASH #3201

androidsoni opened this issue Aug 22, 2017 · 21 comments

Comments

@androidsoni
Copy link

I have a Widevine DRM based encrypted video. The video is encrypted using bento4 ,

mp4dash --widevine-header provider:widevine_test#content_id:2a --encryption-key 90351951686b5e1ba222439ecec1f12a:0a237b0752cbf1a827e2fecfb87479a2 video-source.mp4 Check this link for more info

Now I am trying to play this video on Android using Exoplayer and I am getting an error

"android.media.MediaCodec$CryptoException: Error decrypting data: requested key has not been loaded"

Error decrypting data: requested key has not been loaded
I have mpd file on my sdcard .I have tried to the simple mpd file (without encryption), it played successfully but I have tried a lot playing the encrypted video with key but I am unable to play .It always display above error in logcat

What is the right way to pass the key ?

@ojw28
Copy link
Contributor

ojw28 commented Aug 22, 2017

If you're encrypting with Widevine you must have a license server of some kind. That error indicates the license response did not include the keys required for decryption.

@androidsoni
Copy link
Author

androidsoni commented Aug 22, 2017

Thank you for the response . Currently I am using license url https://proxy.uat.widevine.com/proxy?provider=widevine_test .
I have the mpd file and the encryption key string on local sd card ...is there any way I can manually pass the encryption key to the player and video will play. Please suggest

@ojw28
Copy link
Contributor

ojw28 commented Aug 22, 2017

I don't think that's how Widevine works. The server is responsible for issuing a license that contains the necessary keys for decryption. If you're using someone else's license server and the response contains different keys than you've encrypted your content with, that's not going to work.

@androidsoni
Copy link
Author

androidsoni commented Aug 22, 2017

ok ..I have gone through the demo app of exoplayer .It has a Widevine secure example. But there is no example which uses MPEG DASH encryption key...can you suggest how I can pass MPEG-DASH encryption key to the player.

@ojw28
Copy link
Contributor

ojw28 commented Aug 22, 2017

The demo app plays Widevine content that was encrypted using the same keys that the Widevine test server provides. If you want to protect content with Widevine then I'm pretty sure you have to have a proper license server. I'm not sure what "pass MPEG-DASH encryption key to the player" means, or what encryption scheme you're referring to when you say this (are you sure it's Widevine)?

@androidsoni
Copy link
Author

androidsoni commented Aug 23, 2017

yes it is Widevine DRM.
If our video is MPEG-DASH encrypted(No Widevine).It has encryption key.Now I want to run this video in exoplayer which requires encryption key at run time .How I can provide the encryption key to the player,so that the file will run. ?

@ojw28
Copy link
Contributor

ojw28 commented Aug 23, 2017

What does "MPEG-DASH encrypted(No Widevine)" mean, exactly? You need to be more precise about the encryption scheme for us to help. Thanks!

@androidsoni
Copy link
Author

I have MPEG-DASH encrypted video .Video have a encryption key .
How can I play this video in Exoplayer ?

@ojw28
Copy link
Contributor

ojw28 commented Aug 24, 2017

As above, "MPEG-DASH encrypted video" is not precise enough. There are multiple schemes that you can use to encrypt DASH content. Are you able to play this content successfully in any other player, in particular any web player? We're just not able to help without precise information, sorry.

@androidsoni
Copy link
Author

androidsoni commented Aug 24, 2017

Its a .MPD file having encryption key .It is working in shaka player implemented in our desktop app.
We have used below code to configure the shaka player .PLease check

player.configure({
    drm: {
      clearKeys: {
        '91341951696b5e1ba232439ecec1f12a': '0a247b0751cbf1a827e2fedfb87479a2'
      }
    }
  });
  
  videoUrl = 'http://localhost:3000/'+ videoPath +'/stream.mpd';

@ojw28 ojw28 changed the title Unable to Play Widevine Encrypted Video in Exoplayer How to play ClearKey encrypted DASH Aug 24, 2017
@ojw28
Copy link
Contributor

ojw28 commented Aug 24, 2017

Got it. This is ClearKey encrypted content (not Widevine encrypted). You need to initialize the DefaultDrmSessionManager instance using C.CLEARKEY_UUID. To provide your locally stored key you'll need to implement a MediaDrmCallback that provides it as the key response. Someone got this working and provided sample code in #3178, so please take a look at that.

@androidsoni
Copy link
Author

Thank you ..I just tried the link you provided .Now the screen is black ...no audio or video is displayed but the video time is visible. It shows a message```

" Media includes video tracks, but none are playable by this device"
" Media includes audio tracks, but none are playable by this device"

@androidsoni
Copy link
Author

the custom MediaDRMCallback``s callback executeKeyRequest `is also not called

@androidsoni
Copy link
Author

you can see this log for more detail

> Tracks [
> Renderer:0 [
>     Group:0, adaptive_supported=N/A [
>    [ ] Track:0, id=video/1, mimeType=video/avc, bitrate=779871, res=1280x720, fps=25.0, supported=?
>    ]
>  ]
>   Renderer:1 [
>    Group:0, adaptive_supported=N/A [
>        [ ] Track:0, id=audio/und, mimeType=audio/mp4a-latm, bitrate=156396, channels=2, sample_rate=48000, supported=?
>      ]
>  ]
>  ]

@ojw28
Copy link
Contributor

ojw28 commented Aug 24, 2017

Are you sure that you're initializing the DefaultDrmSessionManager instance using C.CLEARKEY_UUID?

@androidsoni
Copy link
Author

Yes, This is how I created DRMSessionManager

FrameworkMediaDrm  fmDrm = FrameworkMediaDrm.newInstance(C.CLEARKEY_UUID);
 MyDRMCallBack myDRMCallBack = new MyDRMCallBack();
  DrmSessionManager<FrameworkMediaCrypto> = new DefaultDrmSessionManager<FrameworkMediaCrypto>(C.CLEARKEY_UUID, fmDrm, 
   myDRMCallBack, null, mainHandler, eventLogger);

And this MyDrmCallback class

class MyDRMCallBack implements MediaDrmCallback {

  String keyString;

  @Override
  public byte[] executeProvisionRequest(UUID uuid, ExoMediaDrm.ProvisionRequest request) throws Exception {
    return new byte[0];
  }
  String keyValue="0a247b0751cbf1a827e2fedfb87479a2";
  String keyId = "91341951696b5e1ba232439ecec1f12a";

  public MyDRMCallBack() {
    this.keyString = "{\"keys\":[{\"kty\":\"oct\",\"k\":\""+keyValue+"\",\"kid\":\""+keyId+"\"}],\"type\":\"temporary\"}";;
  }

  @Override
  public byte[] executeKeyRequest(UUID uuid, ExoMediaDrm.KeyRequest request) throws Exception {
    return keyString.getBytes();
  }
}

Player shows an error

"Media includes video tracks , but none are playable by this device ."
"Media includes audio tracks , but none are playable by this device ."

in logcat it shows message like

loading [true]

Tracks [
Renderer:0 [
Group:0, adaptive_supported=N/A [
[ ] Track:0, id=video/1, mimeType=video/avc, bitrate=779871, res=1280x720, fps=25.0, supported=?
]
]
Renderer:1 [
Group:0, adaptive_supported=N/A [
[ ] Track:0, id=audio/und, mimeType=audio/mp4a-latm, bitrate=156396, channels=2, sample_rate=48000, supported=?
]
]
]
loading [false]

@ojw28
Copy link
Contributor

ojw28 commented Aug 25, 2017

I think you're probably quite close to having it working, but the logging you're seeing indicates that the player thinks the content is encrypted with a different DRM scheme than the one for which you've initialized the DrmSessionManager.

If the DrmSessionManager is being initialized correctly (as appears to be the case), then that would indicate that the player doesn't think the content is ClearKey encrypted. This may be a shortcoming that will be addressed as part of #3138, but to diagnose (and also help work out how you'd be able to get this content playing) I think we'd need access to the content itself.

@androidsoni
Copy link
Author

I have mpd file (inside zip) on dropbox .Please download it from here https://www.dropbox.com/s/y20s6a2mm4rfu45/Constitution.zip?dl=0

KID : 91341951696b5e1ba232439ecec1f12a
KEY ; 0a247b0751cbf1a827e2fedfb87479a2

Exoplayer java file is here :
https://www.dropbox.com/s/eb883ajhk2nxk2b/PlayerActivity.java?dl=0

Actually I download the zip file on android sdcard .Than extract the zip which contains mpd file.Than I am passing the uri of .mpd file(present on sd card) to Exoplayer .you can check the content

@ojw28
Copy link
Contributor

ojw28 commented Aug 29, 2017

This will be duplicated to #3138 after a few changes have been submitted.

@ojw28
Copy link
Contributor

ojw28 commented Aug 29, 2017

Good news: I was able to get the sample content working. You need to use the very latest dev-v2 branch, since there are some changes that are required to successfully play this kind of content that haven't made it into a stable release yet. On that branch, you can initialize your DrmSessionManager as follows to play the content:

LocalMediaDrmCallback drmCallback = new LocalMediaDrmCallback(
    "{\"keys\":[{\"kty\":\"oct\",\"k\":\"CiR7B1HL8agn4v7fuHR5og\",\"kid\":\"kTQZUWlrXhuiMkOezsHxKg\"}],\"type\":\"temporary\"}".getBytes());
DrmSessionManager manager = new DefaultDrmSessionManager<>(C.CLEARKEY_UUID,
    FrameworkMediaDrm.newInstance(C.CLEARKEY_UUID), drmCallback, null, mainHandler,
    eventLogger);

Note that CiR7B1HL8agn4v7fuHR5ogand kTQZUWlrXhuiMkOezsHxKg are the base64url encodings of the KID and KEY values you've provided above.

The only remaining work to get ClearKey content working in all cases is to work around a platform issue where it uses base64 rather than base64url encoding for the key request/response. We're tracking this in #3138. For most cases the two encodings will be identical (as is true for the test content in this thread).

@ojw28
Copy link
Contributor

ojw28 commented Aug 29, 2017

Closing, since this is now working in the dev-v2 branch, and the one piece of remaining work is tracked in #3138.

@ojw28 ojw28 closed this as completed Aug 29, 2017
@google google locked and limited conversation to collaborators Dec 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants