Skip to content

Commit

Permalink
feat(dash): Parse ClearKey license URL in MPD (#4066)
Browse files Browse the repository at this point in the history
Example content protection tags parsed: 

```xml
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="<default key id>" />
<ContentProtection value="ClearKey1.0" schemeIdUri="urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e">
    <clearkey:Laurl Lic_type="EME-1.0">License Url</clearkey:Laurl>
```

The player parses the default key id and license url, 
and sends a POST request to license url as per https://w3c.github.io/encrypted-media/#clear-key-request-format to retrieve the decryption key/s.
  • Loading branch information
sr1990 committed Mar 30, 2022
1 parent 4005754 commit 19e24b1
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -67,6 +67,7 @@ Rostislav Hejduk <Ross-cz@users.noreply.github.com>
SameGoal Inc. <*@samegoal.com>
Sanborn Hilland <sanbornh@rogers.com>
Sander Saares <sander@saares.eu>
Sanil Raut <sr1990003@gmail.com>
Swank Motion Pictures Inc. <*@swankmp.com>
TalkTalk Plc <*@talktalkplc.com>
Tatsiana Gelahova <tatsiana.gelahova@gmail.com>
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS
Expand Up @@ -97,6 +97,7 @@ Sam Dutton <dutton@google.com>
Sanborn Hilland <sanbornh@rogers.com>
Sander Saares <sander@saares.eu>
Sandra Lokshina <ismena@google.com>
Sanil Raut <sr1990003@gmail.com>
Satheesh Velmurugan <satheesh@philo.com>
Semih Gokceoglu <semih.gkcoglu@gmail.com>
Seth Madison <seth@philo.com>
Expand Down
32 changes: 31 additions & 1 deletion lib/dash/content_protection.js
Expand Up @@ -180,6 +180,27 @@ shaka.dash.ContentProtection = class {
return '';
}

/**
* Gets a ClearKey license URL from a content protection element
* containing a custom `clearkey::Laurl` element
*
* @param {shaka.dash.ContentProtection.Element} element
* @return {string}
*/
static getClearKeyLicenseUrl(element) {
const clearKeyLaurlNode = shaka.util.XmlUtils.findChildNS(
element.node, shaka.dash.ContentProtection.ClearKeyNamespaceUri_,
'Laurl',
);
if (clearKeyLaurlNode &&
clearKeyLaurlNode.getAttribute('Lic_type') === 'EME-1.0') {
if (clearKeyLaurlNode.textContent) {
return clearKeyLaurlNode.textContent;
}
}
return '';
}

/**
* Parses an Array buffer starting at byteOffset for PlayReady Object Records.
* Each PRO Record is preceded by its PlayReady Record type and length in
Expand Down Expand Up @@ -562,7 +583,9 @@ shaka.dash.ContentProtection.licenseUrlParsers_ = new Map()
.set('com.microsoft.playready.software',
shaka.dash.ContentProtection.getPlayReadyLicenseUrl)
.set('com.microsoft.playready.hardware',
shaka.dash.ContentProtection.getPlayReadyLicenseUrl);
shaka.dash.ContentProtection.getPlayReadyLicenseUrl)
.set('org.w3.clearkey',
shaka.dash.ContentProtection.getClearKeyLicenseUrl);

/**
* @const {string}
Expand All @@ -577,3 +600,10 @@ shaka.dash.ContentProtection.MP4Protection_ =
* @private
*/
shaka.dash.ContentProtection.CencNamespaceUri_ = 'urn:mpeg:cenc:2013';

/**
* @const {string}
* @private
*/
shaka.dash.ContentProtection.ClearKeyNamespaceUri_ =
'http://dashif.org/guidelines/clearKey';
2 changes: 2 additions & 0 deletions lib/util/player_configuration.js
Expand Up @@ -100,6 +100,8 @@ shaka.util.PlayerConfiguration = class {
keySystemsByURI: {
'urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b':
'org.w3.clearkey',
'urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e':
'org.w3.clearkey',
'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed':
'com.widevine.alpha',
'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95':
Expand Down
44 changes: 44 additions & 0 deletions test/dash/dash_parser_content_protection_unit.js
Expand Up @@ -814,6 +814,50 @@ describe('DashParser ContentProtection', () => {
});
});

describe('getClearKeyLicenseUrl', () => {
it('valid clearkey:Laurl node', () => {
const input = {
init: null,
keyId: null,
schemeUri: '',
node: strToXml([
'<test xmlns:clearkey="http://dashif.org/guidelines/clearKey">',
' <clearkey:Laurl ',
' Lic_type="EME-1.0">www.example.com</clearkey:Laurl>',
'</test>',
].join('\n')),
};
const actual = ContentProtection.getClearKeyLicenseUrl(input);
expect(actual).toBe('www.example.com');
});

it('clearkey:Laurl without license url', () => {
const input = {
init: null,
keyId: null,
schemeUri: '',
node: strToXml([
'<test xmlns:clearkey="http://dashif.org/guidelines/clearKey">',
' <clearkey:Laurl Lic_type="EME-1.0"></clearkey:Laurl>',
'</test>',
].join('\n')),
};
const actual = ContentProtection.getClearKeyLicenseUrl(input);
expect(actual).toBe('');
});

it('no clearkey:Laurl node', () => {
const input = {
init: null,
keyId: null,
schemeUri: '',
node: strToXml('<test></test>'),
};
const actual = ContentProtection.getClearKeyLicenseUrl(input);
expect(actual).toBe('');
});
});

describe('getPlayReadyLicenseURL', () => {
it('mspro', () => {
const laurl = [
Expand Down

0 comments on commit 19e24b1

Please sign in to comment.