From fd38a069a0bc70aba84fbbf3340317ba7e58554a Mon Sep 17 00:00:00 2001 From: birme Date: Tue, 20 Sep 2016 13:48:56 +0200 Subject: [PATCH 1/9] Include default KID in drm info struct as some DRM providers require that a default KID is provided in the wrapped license request --- externs/shaka/manifest.js | 6 ++++-- lib/dash/content_protection.js | 3 ++- lib/media/drm_engine.js | 25 +++++++++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/externs/shaka/manifest.js b/externs/shaka/manifest.js index 6e93b30f1d..9afe264415 100644 --- a/externs/shaka/manifest.js +++ b/externs/shaka/manifest.js @@ -136,7 +136,8 @@ shakaExtern.InitDataOverride; * audioRobustness: string, * videoRobustness: string, * serverCertificate: Uint8Array, - * initData: Array. + * initData: Array., + * defaultKID: string * }} * * @description @@ -174,7 +175,8 @@ shakaExtern.InitDataOverride; * Defaults to [], e.g., no override.
* A list of initialization data which override any initialization data found * in the content. See also shakaExtern.InitDataOverride. - * + * @property {string} defaultKID + * Default Key ID * @exportDoc */ shakaExtern.DrmInfo; diff --git a/lib/dash/content_protection.js b/lib/dash/content_protection.js index 4012cab341..fc89279742 100644 --- a/lib/dash/content_protection.js +++ b/lib/dash/content_protection.js @@ -247,7 +247,8 @@ shaka.dash.ContentProtection.createDrmInfo_ = function(keySystem, initData) { audioRobustness: '', videoRobustness: '', serverCertificate: null, - initData: initData || [] + initData: initData || [], + defaultKID: '' }; }; diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index 7663127433..3347d31a22 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -429,6 +429,12 @@ shaka.media.DrmEngine.prototype.prepareMediaKeyConfigs_ = fullMimeType += '; codecs="' + stream.codecs + '"'; } + // Some DRM license provides requires that we have default + // KID from manifest in the wrapped license request + if (stream.keyId) { + drmInfo.defaultKeyID = stream.keyId; + } + // Edge 13 fails this negotiation with NotSupportedError if more than // one entry is given, even if each entry individually would be // supported. Bug filed: https://goo.gl/vr2Vle @@ -660,7 +666,8 @@ shaka.media.DrmEngine.prototype.configureClearKey_ = function() { audioRobustness: '', videoRobustness: '', serverCertificate: null, - initData: initDatas + initData: initDatas, + defaultKID: '' }; }; @@ -685,7 +692,11 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( /** @type {!Array.} */ var initDatas = []; - this.processDrmInfos_(drmInfos, licenseServers, serverCerts, initDatas); + /** @type {!Array.} */ + var defaultKeys = []; + + this.processDrmInfos_(drmInfos, licenseServers, serverCerts, initDatas, + defaultKeys); if (serverCerts.length > 1) { shaka.log.warning('Multiple unique server certificates found! ' + @@ -710,7 +721,8 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( audioRobustness: audioRobustness, videoRobustness: videoRobustness, serverCertificate: serverCerts[0], - initData: initDatas + initData: initDatas, + defaultKID: defaultKeys[0] }; }; @@ -723,10 +735,11 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( * @param {!Array.} licenseServers * @param {!Array.} serverCerts * @param {!Array.} initDatas + * @param {!Array.} defaultKeys * @private */ shaka.media.DrmEngine.prototype.processDrmInfos_ = - function(drmInfos, licenseServers, serverCerts, initDatas) { + function(drmInfos, licenseServers, serverCerts, initDatas, defaultKeys) { /** * @param {shakaExtern.InitDataOverride} a * @param {shakaExtern.InitDataOverride} b @@ -764,6 +777,10 @@ shaka.media.DrmEngine.prototype.processDrmInfos_ = } }); } + + if (drmInfo.defaultKeyID) { + defaultKeys.push(drmInfo.defaultKeyID); + } }); }; From 42fa9d9fe6e7ee0c2b8dbde98b60837cd8878a48 Mon Sep 17 00:00:00 2001 From: birme Date: Tue, 20 Sep 2016 15:14:28 +0200 Subject: [PATCH 2/9] Make defaultKID default to null --- demo/assets.js | 3 ++- lib/dash/content_protection.js | 2 +- lib/media/drm_engine.js | 5 +++-- test/test/util/manifest_generator.js | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/demo/assets.js b/demo/assets.js index 1f604ca862..c17f1f7f80 100644 --- a/demo/assets.js +++ b/demo/assets.js @@ -253,7 +253,8 @@ shakaAssets.YouTubeCallback = function(node) { audioRobustness: '', videoRobustness: '', serverCertificate: null, - initData: null + initData: null, + defaultKID: null }); } } diff --git a/lib/dash/content_protection.js b/lib/dash/content_protection.js index fc89279742..73473f0b56 100644 --- a/lib/dash/content_protection.js +++ b/lib/dash/content_protection.js @@ -248,7 +248,7 @@ shaka.dash.ContentProtection.createDrmInfo_ = function(keySystem, initData) { videoRobustness: '', serverCertificate: null, initData: initData || [], - defaultKID: '' + defaultKID: null }; }; diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index 3347d31a22..63090410c3 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -429,8 +429,9 @@ shaka.media.DrmEngine.prototype.prepareMediaKeyConfigs_ = fullMimeType += '; codecs="' + stream.codecs + '"'; } - // Some DRM license provides requires that we have default + // Some DRM license providers requires that we have a default // KID from manifest in the wrapped license request + // and needs to be accessible in a request filter if (stream.keyId) { drmInfo.defaultKeyID = stream.keyId; } @@ -667,7 +668,7 @@ shaka.media.DrmEngine.prototype.configureClearKey_ = function() { videoRobustness: '', serverCertificate: null, initData: initDatas, - defaultKID: '' + defaultKID: null }; }; diff --git a/test/test/util/manifest_generator.js b/test/test/util/manifest_generator.js index 3dc2ea4521..503b3eea97 100644 --- a/test/test/util/manifest_generator.js +++ b/test/test/util/manifest_generator.js @@ -166,7 +166,8 @@ shaka.test.ManifestGenerator.prototype.addDrmInfo = function(keySystem) { audioRobustness: '', videoRobustness: '', serverCertificate: null, - initData: null + initData: null, + defaultKID: null }); return this; }; From aa693af6c5f14a367a83adb2e5429265f2437c9f Mon Sep 17 00:00:00 2001 From: birme Date: Tue, 20 Sep 2016 15:14:46 +0200 Subject: [PATCH 3/9] Make defaultKID default to null --- externs/shaka/manifest.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/externs/shaka/manifest.js b/externs/shaka/manifest.js index 9afe264415..e4511fba8d 100644 --- a/externs/shaka/manifest.js +++ b/externs/shaka/manifest.js @@ -137,7 +137,7 @@ shakaExtern.InitDataOverride; * videoRobustness: string, * serverCertificate: Uint8Array, * initData: Array., - * defaultKID: string + * defaultKID: ?string * }} * * @description @@ -175,8 +175,9 @@ shakaExtern.InitDataOverride; * Defaults to [], e.g., no override.
* A list of initialization data which override any initialization data found * in the content. See also shakaExtern.InitDataOverride. - * @property {string} defaultKID - * Default Key ID + * @property {?string} defaultKID + * Defaults to null
+ * If available, contains the default key ID for this key system. * @exportDoc */ shakaExtern.DrmInfo; From 68f36abbc3c9d8f78144c8ef3ee1d5dd5bd1cce6 Mon Sep 17 00:00:00 2001 From: birme Date: Tue, 20 Sep 2016 15:15:17 +0200 Subject: [PATCH 4/9] Updated authors and contributors files --- AUTHORS | 1 + CONTRIBUTORS | 1 + 2 files changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 739f47e495..a1f0db74f1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -31,3 +31,4 @@ SameGoal Inc. <*@samegoal.com> Sanborn Hilland TalkTalk Plc <*@talktalkplc.com> uStudio Inc. <*@ustudio.com> +Jonas Birmé diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 4111f067ba..efa603372b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -48,3 +48,4 @@ Thomas Stephens Timothy Drews Vasanth Polipelli Vignesh Venkatasubramanian +Jonas Birmé From b9d76e31a5872d3b93c991d0079f995ec9e54b3c Mon Sep 17 00:00:00 2001 From: birme Date: Fri, 23 Sep 2016 10:16:58 +0200 Subject: [PATCH 5/9] Keep list alphabetized --- AUTHORS | 2 +- CONTRIBUTORS | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index a1f0db74f1..f7e9ad3936 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,6 +20,7 @@ Itay Kinnrot Jason Palmer Jesper Haug Karsrud Johan Sundström +Jonas Birmé JW Player <*@jwplayer.com> Mattias Wadman Nick Desaulniers @@ -31,4 +32,3 @@ SameGoal Inc. <*@samegoal.com> Sanborn Hilland TalkTalk Plc <*@talktalkplc.com> uStudio Inc. <*@ustudio.com> -Jonas Birmé diff --git a/CONTRIBUTORS b/CONTRIBUTORS index efa603372b..1dd5445ba9 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -33,6 +33,7 @@ Jason Palmer Jesper Haug Karsrud Joey Parrish Johan Sundström +Jonas Birmé Jono Ward Mattias Wadman Natalie Harris @@ -48,4 +49,3 @@ Thomas Stephens Timothy Drews Vasanth Polipelli Vignesh Venkatasubramanian -Jonas Birmé From 72dba5ce0c0dd68d32a0b2f714ca921b542f4936 Mon Sep 17 00:00:00 2001 From: birme Date: Fri, 23 Sep 2016 11:16:38 +0200 Subject: [PATCH 6/9] Correction based on feedback for PR to handle multiple key IDs in a single manifest --- demo/assets.js | 2 +- externs/shaka/manifest.js | 8 ++++---- lib/dash/content_protection.js | 2 +- lib/media/drm_engine.js | 18 +++++++++++++----- test/test/util/manifest_generator.js | 2 +- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/demo/assets.js b/demo/assets.js index c17f1f7f80..23f3720871 100644 --- a/demo/assets.js +++ b/demo/assets.js @@ -254,7 +254,7 @@ shakaAssets.YouTubeCallback = function(node) { videoRobustness: '', serverCertificate: null, initData: null, - defaultKID: null + keyIds: [] }); } } diff --git a/externs/shaka/manifest.js b/externs/shaka/manifest.js index e4511fba8d..03f89b8ea6 100644 --- a/externs/shaka/manifest.js +++ b/externs/shaka/manifest.js @@ -137,7 +137,7 @@ shakaExtern.InitDataOverride; * videoRobustness: string, * serverCertificate: Uint8Array, * initData: Array., - * defaultKID: ?string + * keyIds: Array. * }} * * @description @@ -175,9 +175,9 @@ shakaExtern.InitDataOverride; * Defaults to [], e.g., no override.
* A list of initialization data which override any initialization data found * in the content. See also shakaExtern.InitDataOverride. - * @property {?string} defaultKID - * Defaults to null
- * If available, contains the default key ID for this key system. + * @property {Array.} keyIds + * Defaults to []
+ * If not empty, contains the default key IDs for this key system. * @exportDoc */ shakaExtern.DrmInfo; diff --git a/lib/dash/content_protection.js b/lib/dash/content_protection.js index 73473f0b56..48cde99594 100644 --- a/lib/dash/content_protection.js +++ b/lib/dash/content_protection.js @@ -248,7 +248,7 @@ shaka.dash.ContentProtection.createDrmInfo_ = function(keySystem, initData) { videoRobustness: '', serverCertificate: null, initData: initData || [], - defaultKID: null + keyIds: [] }; }; diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index 63090410c3..e2fa95a653 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -433,7 +433,7 @@ shaka.media.DrmEngine.prototype.prepareMediaKeyConfigs_ = // KID from manifest in the wrapped license request // and needs to be accessible in a request filter if (stream.keyId) { - drmInfo.defaultKeyID = stream.keyId; + drmInfo.keyIds.push(stream.keyId); } // Edge 13 fails this negotiation with NotSupportedError if more than @@ -592,6 +592,10 @@ shaka.media.DrmEngine.prototype.fillInDrmInfoDefaults_ = function(drmInfo) { } } + if (!drmInfo.keyIds) { + drmInfo.keyIds = []; + } + var advanced = this.config_.advanced[keySystem]; if (advanced) { if (!drmInfo.distinctiveIdentifierRequired) { @@ -668,7 +672,7 @@ shaka.media.DrmEngine.prototype.configureClearKey_ = function() { videoRobustness: '', serverCertificate: null, initData: initDatas, - defaultKID: null + keyIds: [] }; }; @@ -723,7 +727,7 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( videoRobustness: videoRobustness, serverCertificate: serverCerts[0], initData: initDatas, - defaultKID: defaultKeys[0] + keyIds: defaultKeys }; }; @@ -779,8 +783,12 @@ shaka.media.DrmEngine.prototype.processDrmInfos_ = }); } - if (drmInfo.defaultKeyID) { - defaultKeys.push(drmInfo.defaultKeyID); + if (drmInfo.keyIds) { + for (var i = 0; i < drmInfo.keyIds.length; ++i) { + if (defaultKeys.indexOf(drmInfo.keyIds[i]) == -1) { + defaultKeys.push(drmInfo.keyIds[i]); + } + } } }); }; diff --git a/test/test/util/manifest_generator.js b/test/test/util/manifest_generator.js index 503b3eea97..564916ec86 100644 --- a/test/test/util/manifest_generator.js +++ b/test/test/util/manifest_generator.js @@ -167,7 +167,7 @@ shaka.test.ManifestGenerator.prototype.addDrmInfo = function(keySystem) { videoRobustness: '', serverCertificate: null, initData: null, - defaultKID: null + keyIds: [] }); return this; }; From de005a67267004e915365cfea0cb88cf04d30ada Mon Sep 17 00:00:00 2001 From: birme Date: Fri, 23 Sep 2016 20:40:27 +0200 Subject: [PATCH 7/9] Renaming variable defaultKeys to keyIds for consistency --- lib/media/drm_engine.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index e2fa95a653..9beb7cfadf 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -697,11 +697,11 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( /** @type {!Array.} */ var initDatas = []; - /** @type {!Array.} */ - var defaultKeys = []; + /** @type {!Array.} */ + var keyIds = []; this.processDrmInfos_(drmInfos, licenseServers, serverCerts, initDatas, - defaultKeys); + keyIds); if (serverCerts.length > 1) { shaka.log.warning('Multiple unique server certificates found! ' + @@ -727,7 +727,7 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( videoRobustness: videoRobustness, serverCertificate: serverCerts[0], initData: initDatas, - keyIds: defaultKeys + keyIds: keyIds }; }; @@ -740,11 +740,11 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( * @param {!Array.} licenseServers * @param {!Array.} serverCerts * @param {!Array.} initDatas - * @param {!Array.} defaultKeys + * @param {!Array.} keyIds * @private */ shaka.media.DrmEngine.prototype.processDrmInfos_ = - function(drmInfos, licenseServers, serverCerts, initDatas, defaultKeys) { + function(drmInfos, licenseServers, serverCerts, initDatas, keyIds) { /** * @param {shakaExtern.InitDataOverride} a * @param {shakaExtern.InitDataOverride} b @@ -785,8 +785,8 @@ shaka.media.DrmEngine.prototype.processDrmInfos_ = if (drmInfo.keyIds) { for (var i = 0; i < drmInfo.keyIds.length; ++i) { - if (defaultKeys.indexOf(drmInfo.keyIds[i]) == -1) { - defaultKeys.push(drmInfo.keyIds[i]); + if (keyIds.indexOf(drmInfo.keyIds[i]) == -1) { + keyIds.push(drmInfo.keyIds[i]); } } } From b4b04108c8e977f073d5a7049e2df0a0a989f3ec Mon Sep 17 00:00:00 2001 From: birme Date: Sat, 24 Sep 2016 07:38:21 +0200 Subject: [PATCH 8/9] Updated unit test for drmInfo struct to include keyIds --- test/media/drm_engine_unit.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/media/drm_engine_unit.js b/test/media/drm_engine_unit.js index f2a38ae884..bd81bf1cfe 100644 --- a/test/media/drm_engine_unit.js +++ b/test/media/drm_engine_unit.js @@ -1440,6 +1440,8 @@ describe('DrmEngine', function() { fakeRequestMediaKeySystemAccess.bind(null, ['drm.abc'])); // Both audio and video with the same key system now: manifest.periods[0].streamSets[1].drmInfos[0].keySystem = 'drm.abc'; + // Key IDs in manifest + manifest.periods[0].streamSets[1].drmInfos[0].keyIds[0] = 'deadbeefdeadbeefdeadbeefdeadbeef'; config.advanced['drm.abc'] = { audioRobustness: 'good', @@ -1460,7 +1462,8 @@ describe('DrmEngine', function() { audioRobustness: 'good', videoRobustness: 'really_really_ridiculously_good', serverCertificate: undefined, - initData: [] + initData: [], + keyIds: ['deadbeefdeadbeefdeadbeefdeadbeef'] }); }).catch(fail).then(done); }); From f5f0d47eaa7f67ca97ba2cbe60c362cd1695be4c Mon Sep 17 00:00:00 2001 From: birme Date: Mon, 26 Sep 2016 20:50:21 +0200 Subject: [PATCH 9/9] Fixed line to long error --- test/media/drm_engine_unit.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/media/drm_engine_unit.js b/test/media/drm_engine_unit.js index bd81bf1cfe..3c54305aa4 100644 --- a/test/media/drm_engine_unit.js +++ b/test/media/drm_engine_unit.js @@ -1441,7 +1441,8 @@ describe('DrmEngine', function() { // Both audio and video with the same key system now: manifest.periods[0].streamSets[1].drmInfos[0].keySystem = 'drm.abc'; // Key IDs in manifest - manifest.periods[0].streamSets[1].drmInfos[0].keyIds[0] = 'deadbeefdeadbeefdeadbeefdeadbeef'; + manifest.periods[0].streamSets[1].drmInfos[0].keyIds[0] = + 'deadbeefdeadbeefdeadbeefdeadbeef'; config.advanced['drm.abc'] = { audioRobustness: 'good',