androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.65k stars 391 forks source link

DRM Key-caching for Streaming Licenses #394

Closed carlosmesquita closed 1 year ago

carlosmesquita commented 1 year ago

Hello,

I'll try to be as concise as possible:

I am trying to cache streaming/playback DRM keys, for Widevine specifically, so I don't have to request a new key everytime new media is requested. Imagine an IPTV scenario, where everytime the user swaps channel, a new license is being requested at the moment, but it is not needed, because the same license should be used!

I have tried reimplementing the DrmSessionManager and MediaDrmCallback, but without success.

I have also tried using the OfflineLicenseHelper, but it only works for offline licenses, and my DRM server doesn't allow fetching offline licenses for streaming content, which makes total sense to me. I tried reimplementing the OfflineLicenseHelper, and calling the blockingKeyRequest method passing MODE_PLAYBACK as parameter, but it didn't work... I assume it's some kind of security mechanism?

Does anyone have a use case similar to this? Can anyone help me understanding how can i get the current DRM Key being used, so i can store in the local KeyStore, and use it later for new streaming content, so the Player doesn't request a new DRM Key?

Best regards, and thanks in advance.

icbaker commented 1 year ago

Streaming keys can be re-used by using the same 'session'. In ExoPlayer that generally means using the same DrmSession instance. ExoPlayer's DefaultDrmSessionManager will aim to re-use session in two ways:

When switching between different MediaItems in the playlist (which it sounds like what you're doing with 'swapping channel'?) then this re-use can only work if the same DefaultDrmSessionManager instance is used for both items. This re-use is decided based on the equality of MediaItem.drmConfiguration here: https://github.com/androidx/media/blob/3c01488f8d478caaa54038431ee6339444ea6e04/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/drm/DefaultDrmSessionManagerProvider.java#L83-L87

I suggest you spend some time debugging (and maybe add some logging) in order to determine whether:


Offline licenses are completely different (used for playing downloaded content).

It's not possible for you to extract the keys from the CDM (by design) so you can't store them yourself.

carlosmesquita commented 1 year ago

Thanks for your time @icbaker!

I am actually not using MediaItems in Playlists, i am calling the setMediaItems method everytime i need to change content. I think with some rework it's possible to use Playlists ofc, but not sure if it makes any difference! I am using the same DrmSessionManager (not the Default one, a Custom one based on the Default, so shouldn't be an issue) for all Media.

Thing here is, our use case is a little different, because we need to be able to use the same license even after restarting the application, or even restarting the device... or even in a different day. Imagine the "license expiration" to be like 1 month, so the same license should be valid for 1 month. Given this, the DrmSession won't be the same for obvious reasons I think, and the license won't be reused.

As you mention, it is not possible to extract the keys from the CDM, which I was already expecting, so I am kind of stuck here... either our use case doesn't make sense, or we are missing some details!

icbaker commented 1 year ago

Thing here is, our use case is a little different, because we need to be able to use the same license even after restarting the application, or even restarting the device... or even in a different day. Imagine the "license expiration" to be like 1 month, so the same license should be valid for 1 month. Given this, the DrmSession won't be the same for obvious reasons I think, and the license won't be reused.

This doesn't sound like a valid use of streaming widevine DRM licenses - I believe the assumption is that you will request a license for each 'playback' (but ofc if you play two streams one after the other and both can use the same license, then it can be re-used - but not after the app or device has been restarted). If this is something you need to make work and you're a Widevine partner I suggest you ask them directly for support with this use-case (it's not really on topic for this issue tracker): https://www.widevine.com/contact.

carlosmesquita commented 1 year ago

@icbaker, thanks for your time on this topic, and for your helpful insight.