kaltura / nginx-vod-module

NGINX-based MP4 Repackager
GNU Affero General Public License v3.0
2.01k stars 440 forks source link

dynamically changing DRM key - possible? #1311

Open cc-brian opened 3 years ago

cc-brian commented 3 years ago

Is it possible to dynamically change DRM key without interrupting video service?

I ask, because I can't get it working.

For example:

A user starts a video with widevine DRM and everything loads up initially and starts playing with no issue.

The key is set via a variable which is defined via an nginx map directive. On each request, the nginx map directive might map to a different key. Keep in mind that I've tested all the keys individually and they work.

vod_drm_request_uri $custom_key;

However, once a new key rotates via the nginx map directive the video errors out because the key changed.

This is setup for local mode.

vod_mode local;

The caches are enabled:

vod_metadata_cache example_metadata_cache_videos 4096m; vod_response_cache example_response_cache_videos 128m; vod_drm_info_cache example_drm_info_cache 64m;

Standard vod drm config with single key enabled.

    aio on;
    vod dash;
    vod_drm_enabled on;
    vod_drm_clear_lead_segment_count 1;
    vod_drm_upstream_location drm-keys;
    vod_drm_single_key on;
    vod_drm_request_uri $custom_key;

I was thinking that since single key is enabled that it would NOT need to reload a key until a new video (manifest.mpd) is called, as it should apply the same key to all video segments.

What am I missing here?

Thanks!

erankor commented 3 years ago

This is not supported.

cc-brian commented 3 years ago

@erankor

I appreciate your quick reply and your continued support of this project over the years, greatly valued!

So did I misunderstand how the vod_drm_single_key parameter works?

What I'd like to achieve is that a new DRM key is read from vod_drm_request_uri when a new video (manifest.mpd) is generated and store that into cache (memory) and use that for the rest of the video segments and ignore vod_drm_request_uri until a new video (manifest.mpd) is called.

Therefore, each video would get its own DRM key, so that the keys would rotate efficiently.

Can you think of a way to achieve this?

Thanks! Brian

erankor commented 3 years ago

vod_drm_single_key means a single key-per-mpd, instead of the default key-per-sequence. when enabled, a key will be requested only for the first sequence and copied to the rest. And - the ContentProtection elements will be written under AdaptationSet instead of Representation.

Assuming you do not require more than one key per manifest, and you just want to change the key, I think the easiest is to add some param to the URL that will indicate the key index, e.g. http://example.com/dash/video123/key/456/manifest.mpd. The key index param will propagate to the DRM server (since it's on the URL...) and it can use it to decide which key to return. When you change it, you'll start using new URLs for both the manifest and the segments, and therefore won't use any previously cached content, that can break playback.

cc-brian commented 3 years ago

@erankor

Thanks for your time and the novel approach!

I believe it has potential if I could figure out how to ensure Nginx only serves that URL once, after it's served then it's immediately blocked. As in my case, I don't want to allow the end-user access to the same key again.

Ideally, I'd like to take care of it on the backend. Curious, how much of an undertaking would it be to add something like the following to the codebase?

What I'd like to achieve is that a new DRM key is read from vod_drm_request_uri when a new video (manifest.mpd) is generated and store that into cache (memory) and use that for the rest of the video segments and ignore vod_drm_request_uri until a new video (manifest.mpd) is called.

Is there an option to contract with you or someone on your team for feature requests?

Thanks! Brian