Skip to content

Commit

Permalink
Fix key system content type checks
Browse files Browse the repository at this point in the history
Some browsers, such as Edge 13, do not report capabilities at all.

Not all encrypted streams have known key IDs, so we should not
use that as a predicate for the encrypted content type filter.

Since not all content has both audio and video, the requested and
reported capabilities may not have both either.  So we should
default capabilities to empty lists if missing.

This also adds an encrypted audio-only asset so that audio-only is
covered by our integration tests.

Closes #342
Closes #360

Change-Id: If5973c4ddea358d96ab305700e027021b1a7b65a
  • Loading branch information
joeyparrish committed May 2, 2016
1 parent 16d64d6 commit bc17162
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 14 deletions.
21 changes: 21 additions & 0 deletions demo/assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {{{
Expand Down
4 changes: 4 additions & 0 deletions externs/shaka/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ shakaExtern.GetSegmentReferenceFunction;
* width: (number|undefined),
* height: (number|undefined),
* kind: (string|undefined),
* encrypted: boolean,
* keyId: ?string,
* allowedByApplication: boolean,
* allowedByKeySystem: boolean
Expand Down Expand Up @@ -322,6 +323,9 @@ shakaExtern.GetSegmentReferenceFunction;
* <i>Text streams only.</i> <br>
* The kind of text stream. For example, 'captions' or 'subtitles'.
* @see https://goo.gl/k1HWA6
* @property {boolean} encrypted
* <i>Defaults to false.</i><br>
* True if the stream is encrypted.
* @property {?string} keyId
* <i>Defaults to null (i.e., unencrypted or key ID unknown).</i> <br>
* The stream's key ID as a lowercase hex string. This key ID identifies the
Expand Down
1 change: 1 addition & 0 deletions lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 14 additions & 7 deletions lib/media/drm_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ shaka.media.DrmEngine = function(networkingEngine, onError, onKeyStatus) {
/** @private {string} */
this.keySystem_ = '';

/** @private {!Array.<string>} */
this.supportedTypes_ = [];
/** @private {Array.<string>} */
this.supportedTypes_ = null;

/** @private {!Array.<shakaExtern.DrmInfo>} */
this.drmInfos_ = [];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.<string>}
* @return {Array.<string>}
*/
shaka.media.DrmEngine.prototype.getSupportedTypes = function() {
return this.supportedTypes_;
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,7 @@ shaka.Player.prototype.addTextTrack = function(
codecs: opt_codec || '',
bandwidth: 0,
kind: kind,
encrypted: false,
keyId: null,
allowedByApplication: true,
allowedByKeySystem: true
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions test/drm_engine_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions test/drm_engine_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions test/util/manifest_generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
*
Expand Down

0 comments on commit bc17162

Please sign in to comment.