diff --git a/demo/assets.js b/demo/assets.js index 5f3fb4c68c..d881f6561e 100644 --- a/demo/assets.js +++ b/demo/assets.js @@ -319,6 +319,27 @@ shakaAssets.testAssets = [ shakaAssets.Feature.WEBM ] }, + { + name: '"Dig the Uke" by Stefan Kartenberg (audio only, multicodec, Widevine)', // gjslint: disable=110 + // From: http://dig.ccmixter.org/files/JeffSpeed68/53327 + // Licensed under Creative Commons BY-NC 3.0. + // Free for non-commercial use with attribution. + // http://creativecommons.org/licenses/by-nc/3.0/ + manifestUri: '//storage.googleapis.com/shaka-demo-assets/dig-the-uke/dash.mpd', // gjslint: disable=110 + + encoder: shakaAssets.Encoder.EDASH_PACKAGER, + source: shakaAssets.Source.SHAKA, + drm: [shakaAssets.KeySystem.WIDEVINE], + features: [ + shakaAssets.Feature.MP4, + shakaAssets.Feature.SEGMENT_BASE, + shakaAssets.Feature.WEBM + ], + + licenseServers: { + 'com.widevine.alpha': '//widevine-proxy.appspot.com/proxy' + } + }, // }}} // YouTube assets {{{ diff --git a/externs/shaka/manifest.js b/externs/shaka/manifest.js index 562ecd456b..7a911fc680 100644 --- a/externs/shaka/manifest.js +++ b/externs/shaka/manifest.js @@ -264,6 +264,7 @@ shakaExtern.GetSegmentReferenceFunction; * width: (number|undefined), * height: (number|undefined), * kind: (string|undefined), + * encrypted: boolean, * keyId: ?string, * allowedByApplication: boolean, * allowedByKeySystem: boolean @@ -322,6 +323,9 @@ shakaExtern.GetSegmentReferenceFunction; * Text streams only.
* The kind of text stream. For example, 'captions' or 'subtitles'. * @see https://goo.gl/k1HWA6 + * @property {boolean} encrypted + * Defaults to false.
+ * True if the stream is encrypted. * @property {?string} keyId * Defaults to null (i.e., unencrypted or key ID unknown).
* The stream's key ID as a lowercase hex string. This key ID identifies the diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js index 750d305d33..e2ac9085af 100644 --- a/lib/dash/dash_parser.js +++ b/lib/dash/dash_parser.js @@ -783,6 +783,7 @@ shaka.dash.DashParser.prototype.parseRepresentation_ = function( width: context.representation.width, height: context.representation.height, kind: kind, + encrypted: contentProtection.drmInfos.length > 0, keyId: keyId, allowedByApplication: true, allowedByKeySystem: true diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index f031da62b9..fc88cbe76f 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -43,8 +43,8 @@ shaka.media.DrmEngine = function(networkingEngine, onError, onKeyStatus) { /** @private {string} */ this.keySystem_ = ''; - /** @private {!Array.} */ - this.supportedTypes_ = []; + /** @private {Array.} */ + this.supportedTypes_ = null; /** @private {!Array.} */ this.drmInfos_ = []; @@ -125,7 +125,7 @@ shaka.media.DrmEngine.prototype.destroy = function() { } this.drmInfos_ = []; - this.supportedTypes_ = []; + this.supportedTypes_ = null; this.mediaKeys_ = null; this.video_ = null; this.eventManager_ = null; @@ -290,7 +290,7 @@ shaka.media.DrmEngine.prototype.keySystem = function() { * Returns an array of the media types supported by the current key system. * These will be full mime types (e.g. 'video/webm; codecs="vp8"'). * - * @return {!Array.} + * @return {Array.} */ shaka.media.DrmEngine.prototype.getSupportedTypes = function() { return this.supportedTypes_; @@ -438,9 +438,16 @@ shaka.media.DrmEngine.prototype.queryMediaKeys_ = // Store the capabilities of the key system. var realConfig = mediaKeySystemAccess.getConfiguration(); - var caps = - realConfig.audioCapabilities.concat(realConfig.videoCapabilities); + var audioCaps = realConfig.audioCapabilities || []; + var videoCaps = realConfig.videoCapabilities || []; + var caps = audioCaps.concat(videoCaps); this.supportedTypes_ = caps.map(function(c) { return c.contentType; }); + if (this.supportedTypes_.length == 0) { + // Edge 13 does not report capabilities. To work around this, set the + // supported types to null, which Player will use as a signal that the + // information is not available. + this.supportedTypes_ = null; + } var originalConfig = configsByKeySystem[mediaKeySystemAccess.keySystem]; this.drmInfos_ = originalConfig.drmInfos; @@ -462,7 +469,7 @@ shaka.media.DrmEngine.prototype.queryMediaKeys_ = // We failed to create MediaKeys. This generally shouldn't happen. this.keySystem_ = ''; this.drmInfos_ = []; - this.supportedTypes_ = []; + this.supportedTypes_ = null; return Promise.reject(new shaka.util.Error( shaka.util.Error.Category.DRM, shaka.util.Error.Code.FAILED_TO_CREATE_CDM, diff --git a/lib/player.js b/lib/player.js index a78439dca9..199f022d58 100644 --- a/lib/player.js +++ b/lib/player.js @@ -930,6 +930,7 @@ shaka.Player.prototype.addTextTrack = function( codecs: opt_codec || '', bandwidth: 0, kind: kind, + encrypted: false, keyId: null, allowedByApplication: true, allowedByKeySystem: true @@ -1338,7 +1339,7 @@ shaka.Player.prototype.filterPeriod_ = function(period) { continue; } - if (supportedMimeTypes && stream.keyId && + if (supportedMimeTypes && stream.encrypted && supportedMimeTypes.indexOf(fullMimeType) < 0) { streamSet.streams.splice(j, 1); --j; diff --git a/test/drm_engine_integration.js b/test/drm_engine_integration.js index 7971b5fe96..350cde1492 100644 --- a/test/drm_engine_integration.js +++ b/test/drm_engine_integration.js @@ -119,11 +119,11 @@ describe('DrmEngine', function() { .addStreamSet('video') .addDrmInfo('com.widevine.alpha') .addDrmInfo('com.microsoft.playready') - .addStream(1).mime('video/mp4', 'avc1.640015') + .addStream(1).mime('video/mp4', 'avc1.640015').encrypted(true) .addStreamSet('audio') .addDrmInfo('com.widevine.alpha') .addDrmInfo('com.microsoft.playready') - .addStream(1).mime('audio/mp4', 'mp4a.40.2') + .addStream(1).mime('audio/mp4', 'mp4a.40.2').encrypted(true) .build(); eventManager = new shaka.util.EventManager(); @@ -316,11 +316,11 @@ describe('DrmEngine', function() { 'SwBJAEQAPgBvAE4ATQB3AEYAUQBSAHAAYQBrAFMAUgBvAFQATwBoAEYA' + 'YQBxAE0AUQBRAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwA' + 'LwBXAFIATQBIAEUAQQBEAEUAUgA+AA==') - .addStream(1).mime('video/mp4', 'avc1.640015') + .addStream(1).mime('video/mp4', 'avc1.640015').encrypted(true) .addStreamSet('audio') .addDrmInfo('com.widevine.alpha') .addDrmInfo('com.microsoft.playready') - .addStream(1).mime('audio/mp4', 'mp4a.40.2') + .addStream(1).mime('audio/mp4', 'mp4a.40.2').encrypted(true) .build(); networkingEngine.clearAllRequestFilters(); diff --git a/test/drm_engine_unit.js b/test/drm_engine_unit.js index 7bcb60145f..99c7c8ab39 100644 --- a/test/drm_engine_unit.js +++ b/test/drm_engine_unit.js @@ -60,10 +60,10 @@ describe('DrmEngine', function() { .addPeriod(0) .addStreamSet('video') .addDrmInfo('drm.abc') - .addStream(0).mime('video/foo', 'vbar') + .addStream(0).mime('video/foo', 'vbar').encrypted(true) .addStreamSet('audio') .addDrmInfo('drm.def') - .addStream(1).mime('audio/foo', 'abar') + .addStream(1).mime('audio/foo', 'abar').encrypted(true) .build(); // Reset spies. diff --git a/test/util/manifest_generator.js b/test/util/manifest_generator.js index 4ed3365520..dd174193c0 100644 --- a/test/util/manifest_generator.js +++ b/test/util/manifest_generator.js @@ -289,6 +289,7 @@ shaka.test.ManifestGenerator.prototype.addStream = function(id) { width: undefined, height: undefined, kind: undefined, + encrypted: false, keyId: null, allowedByApplication: true, allowedByKeySystem: true @@ -434,6 +435,19 @@ shaka.test.ManifestGenerator.prototype.kind = function(kind) { }; +/** + * Sets the encrypted flag of the current stream. + * + * @param {boolean} encrypted + * @return {!shaka.test.ManifestGenerator} + */ +shaka.test.ManifestGenerator.prototype.encrypted = function(encrypted) { + var stream = this.currentStream_(); + stream.encrypted = encrypted; + return this; +}; + + /** * Sets the key ID of the current stream. *