Open sr1990 opened 1 year ago
Hi @sr1990 i am also exploring same license server option
@sr1990 that sounds like a reasonable approach, are you planning to implement this?
Hey @cosmin, for the above approach I can think of the following steps:
ABSL_FLAG(std::string,
clear_key_license_url,
"",
"Clear key license url.");
Declare the flag after https://github.com/shaka-project/shaka-packager/blob/84009d82ef1b75ec6dab55e8dc5c888d845a956c/packager/mpd/base/xml/xml_node_unittest.cc#L24
ABSL_DECLARE_FLAG(std::string, clear_key_license_url);
In RepresentationBaseXmlNode::AddContentProtectionElement, if content protection element's scheme_id_uri == "urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b" and clear key license url is available, substitute the raw key's ContentProtection element with clearkey's ContentProtection element. Example:
if (content_protection_element.scheme_id_uri == "urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b" &&
!absl::GetFlag(FLAGS_clear_key_license_url).empty()) {
// Create ContentProtectionElement
ContentProtectionElement temp1;
temp1.value = "ClearKey1.0";
temp1.scheme_id_uri = "urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e";
// Create element Clearkey
Element clearkey;
clearkey.name = "clearkey:Laurl";
clearkey.content = absl::GetFlag(FLAGS_clear_key_license_url);
clearkey.attributes["Lic_type"] = "EME-1.0";
// Push element into contentProtectionElement
temp1.subelements.push_back(clearkey);
// Create ContentProtection node.
XmlNode content_protection_temp("ContentProtection");
// @value is an optional attribute.
if (!temp1.value.empty()) {
RCHECK(content_protection_temp.SetStringAttribute(
"value", temp1.value));
}
RCHECK(content_protection_temp.SetStringAttribute(
"schemeIdUri", temp1.scheme_id_uri));
RCHECK(content_protection_temp.AddElements(
temp1.subelements));
return AddChild(std::move(content_protection_temp));
}
Also a better approach would be to create ClearKeyKeySource similar to WidevineKeySource and add a flag to enable clearkey encryption --enable_clear_key_encryption
When the packager parameters are parsed at https://github.com/shaka-project/shaka-packager/blob/84009d82ef1b75ec6dab55e8dc5c888d845a956c/packager/app/packager_main.cc#L365 in packager_main.cc::GetPackagingParams(), set the key provider to Clearkey. and while creating encryption key source at https://github.com/shaka-project/shaka-packager/blob/84009d82ef1b75ec6dab55e8dc5c888d845a956c/packager/packager.cc#L832 in Packager::Initialize, create and fetch keys using ClearKeyKeySource. For fetching the keys, ClearKeyKeySource needs to send the POST request for each/all variant to the clear key license server as per https://w3c.github.io/encrypted-media/#clear-key-request-format.
I can think of the following scenarios:
Keyid and key same for all the variants - No need to fetch keys from clearkey license server
packager \
'in=Sintel-1280x720.mp4,stream=video,init_segment=h264_1280p/init.mp4,segment_template=h264_1280p/$Number$.m4s' \
'in=Sintel-768x432.mp4,stream=video,init_segment=h264_768p/init.mp4,segment_template=h264_768p/$Number$.m4s' \
'in=Sintel-audio.mp4,stream=audio,init_segment=audioSintel/init.mp4,segment_template=audioSintel/$Number$.m4s' \
--mpd_output h264SintelRaw.mpd --generate_static_live_mpd \
--enable_clear_key_encryption --clear_lead=0 \
-key 2844832a5bfe06350dfd95caff1b6c5c -key_id 444c849e58101486ec19ceb33ec00287 \
--clear_key_license_url "http://xyz/AcquireLicense"
Keyid given and key needs to be fetched from the clearkey license url server
packager \
'in=Sintel-1280x720.mp4,stream=video,init_segment=h264_1280p/init.mp4,segment_template=h264_1280p/$Number$.m4s' \
'in=Sintel-768x432.mp4,stream=video,init_segment=h264_768p/init.mp4,segment_template=h264_768p/$Number$.m4s' \
'in=Sintel-audio.mp4,stream=audio,init_segment=audioSintel/init.mp4,segment_template=audioSintel/$Number$.m4s' \
--mpd_output h264SintelRaw.mpd --generate_static_live_mpd \
--enable_clear_key_encryption --clear_lead=0 \
-key_id 444c849e58101486ec19ceb33ec00287 \
--clear_key_license_url "http://xyz/AcquireLicense"
Using drm_label where key_id and key are given: no need to fetch keys from clearkey license server.
$ packager \
in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4,drm_label=AUDIO \
in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4,drm_label=SD \
in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4,drm_label=SD \
in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4,drm_label=HD \
in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4,drm_label=HD \
--enable_clear_key_encryption --clear_lead=0 \
--keys label=AUDIO:key_id=f3c5e0361e6654b28f8049c778b23946:key=a4631a153a443df9eed0593043db7519,label=SD:key_id=abba271e8bcf552bbd2e86a434a9a5d9:key=69eaa802a6763af979e8d1940fb88392,label=HD:key_id=6d76f25cb17f5e16b8eaef6bbf582d8e:key=cb541084c99731aef4fff74500c12ead \
--clear_key_license_url "http://xyz/AcquireLicense"\
--mpd_output h264.mpd
Using drm_label where keyid is given and key needs to fetched from licence server using ClearKeySource
$ packager \
in=h264_baseline_360p_600.mp4,stream=audio,output=audio.mp4,drm_label=AUDIO \
in=h264_baseline_360p_600.mp4,stream=video,output=h264_360p.mp4,drm_label=SD \
in=h264_main_480p_1000.mp4,stream=video,output=h264_480p.mp4,drm_label=SD \
in=h264_main_720p_3000.mp4,stream=video,output=h264_720p.mp4,drm_label=HD \
in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4,drm_label=HD \
--enable_clear_key_encryption \
--keys label=AUDIO:key_id=f3c5e0361e6654b28f8049c778b23946,label=SD:key_id=abba271e8bcf552bbd2e86a434a9a5d9,label=HD:key_id=6d76f25cb17f5e16b8eaef6bbf582d8e \
--clear_key_license_url "http://xyz/AcquireLicense"\
--mpd_output h264.mpd
We can start with the first approach for users who prefer avoiding the packager's license server request overhead. It's simpler to implement – just substitute the ContentProtection element. I think we may require some time to implement the second approach. However, I'm available to review and test whenever necessary, if someone else takes on the implementation. Please let me know what you think.
As per https://dashif.org/guidelines/iop-v5/#part-6-content-protection-and-security - 8 Use of W3C Clear Key with DASH,
Example: MPD url: https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p_ClearKey.mpd
When player encounters the above ContentProtection elements,it will
This is already supported by shaka player, dash-if player and Android's Exoplayer.
Currently,
will add the following to mpd:
There is no way to indicate license acquisition url.
One possible solution to indicate a licence server of @licenseType EME-1.0 is to add a flag like --clear_key_license_url "https://drm-clearkey-testvectors.axtest.net/AcquireLicense".
Example:
when clear_key_license_url is present, ContentProtection element with schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b" should be skipped and
<ContentProtection value="ClearKey1.0" schemeIdUri="urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e">
should be added.@joeyparrish please let me know what you think.