diff --git a/AUTHORS b/AUTHORS index 739f47e495..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 diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 4111f067ba..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 diff --git a/demo/assets.js b/demo/assets.js index 1f604ca862..23f3720871 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, + keyIds: [] }); } } diff --git a/externs/shaka/manifest.js b/externs/shaka/manifest.js index 6e93b30f1d..03f89b8ea6 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., + * keyIds: Array. * }} * * @description @@ -174,7 +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 {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 4012cab341..48cde99594 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 || [], + keyIds: [] }; }; diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index 7663127433..9beb7cfadf 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -429,6 +429,13 @@ shaka.media.DrmEngine.prototype.prepareMediaKeyConfigs_ = fullMimeType += '; codecs="' + stream.codecs + '"'; } + // 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.keyIds.push(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 @@ -585,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) { @@ -660,7 +671,8 @@ shaka.media.DrmEngine.prototype.configureClearKey_ = function() { audioRobustness: '', videoRobustness: '', serverCertificate: null, - initData: initDatas + initData: initDatas, + keyIds: [] }; }; @@ -685,7 +697,11 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( /** @type {!Array.} */ var initDatas = []; - this.processDrmInfos_(drmInfos, licenseServers, serverCerts, initDatas); + /** @type {!Array.} */ + var keyIds = []; + + this.processDrmInfos_(drmInfos, licenseServers, serverCerts, initDatas, + keyIds); if (serverCerts.length > 1) { shaka.log.warning('Multiple unique server certificates found! ' + @@ -710,7 +726,8 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( audioRobustness: audioRobustness, videoRobustness: videoRobustness, serverCertificate: serverCerts[0], - initData: initDatas + initData: initDatas, + keyIds: keyIds }; }; @@ -723,10 +740,11 @@ shaka.media.DrmEngine.prototype.createCurrentDrmInfo_ = function( * @param {!Array.} licenseServers * @param {!Array.} serverCerts * @param {!Array.} initDatas + * @param {!Array.} keyIds * @private */ shaka.media.DrmEngine.prototype.processDrmInfos_ = - function(drmInfos, licenseServers, serverCerts, initDatas) { + function(drmInfos, licenseServers, serverCerts, initDatas, keyIds) { /** * @param {shakaExtern.InitDataOverride} a * @param {shakaExtern.InitDataOverride} b @@ -764,6 +782,14 @@ shaka.media.DrmEngine.prototype.processDrmInfos_ = } }); } + + if (drmInfo.keyIds) { + for (var i = 0; i < drmInfo.keyIds.length; ++i) { + if (keyIds.indexOf(drmInfo.keyIds[i]) == -1) { + keyIds.push(drmInfo.keyIds[i]); + } + } + } }); }; diff --git a/test/media/drm_engine_unit.js b/test/media/drm_engine_unit.js index f2a38ae884..3c54305aa4 100644 --- a/test/media/drm_engine_unit.js +++ b/test/media/drm_engine_unit.js @@ -1440,6 +1440,9 @@ 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 +1463,8 @@ describe('DrmEngine', function() { audioRobustness: 'good', videoRobustness: 'really_really_ridiculously_good', serverCertificate: undefined, - initData: [] + initData: [], + keyIds: ['deadbeefdeadbeefdeadbeefdeadbeef'] }); }).catch(fail).then(done); }); diff --git a/test/test/util/manifest_generator.js b/test/test/util/manifest_generator.js index 3dc2ea4521..564916ec86 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, + keyIds: [] }); return this; };