Skip to content

Commit

Permalink
feat: Add keySystemsMapping to drm config (shaka-project#4254)
Browse files Browse the repository at this point in the history
This allows, for example, users to use com.microsoft.playready.recommendation
instead of com.microsoft.playready.

Closes shaka-project#4243
  • Loading branch information
Álvaro Velad Galván committed May 31, 2022
1 parent dc88fe0 commit 5e107d5
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 10 deletions.
16 changes: 16 additions & 0 deletions docs/tutorials/drm-config.md
Expand Up @@ -75,6 +75,22 @@ player.configure({
If the browser supports it and you configured a license server URL for it, we'll
use it.

Alternative there are a config for make a mapping of keysystem if you know that
is broadly supported. For example, `com.microsoft.playready.recommendation`:

```js
player.configure({
drm: {
keySystemsMapping: {
'com.microsoft.playready': 'com.microsoft.playready.recommendation',
}
}
});
```

With the previous configuration you will choose the `recommendation` keySystem
when your manifest (HLS or DASH) uses PlayReady.


#### Clear Key

Expand Down
5 changes: 4 additions & 1 deletion externs/shaka/player.js
Expand Up @@ -623,7 +623,8 @@ shaka.extern.AdvancedDrmConfiguration;
* undefined),
* logLicenseExchange: boolean,
* updateExpirationTime: number,
* preferredKeySystems: !Array.<string>
* preferredKeySystems: !Array.<string>,
* keySystemsMapping: !Object.<string, string>
* }}
*
* @property {shaka.extern.RetryParameters} retryParameters
Expand Down Expand Up @@ -664,6 +665,8 @@ shaka.extern.AdvancedDrmConfiguration;
* @property {!Array.<string>} preferredKeySystems
* <i>Defaults to an empty array. </i> <br>
* Specifies the priorties of available DRM key systems.
* @property {Object.<string, string>} keySystemsMapping
* A map of key system name to key system name.
*
* @exportDoc
*/
Expand Down
25 changes: 17 additions & 8 deletions lib/media/drm_engine.js
Expand Up @@ -355,7 +355,8 @@ shaka.media.DrmEngine = class {
shaka.media.DrmEngine.fillInDrmInfoDefaults_(
info,
shaka.util.MapUtils.asMap(this.config_.servers),
shaka.util.MapUtils.asMap(this.config_.advanced || {}));
shaka.util.MapUtils.asMap(this.config_.advanced || {}),
this.config_.keySystemsMapping);
}
}

Expand Down Expand Up @@ -2224,16 +2225,20 @@ shaka.media.DrmEngine = class {
* that the parser left blank. Before working with any drmInfo, it should be
* passed through here as it is uncommon for drmInfo to be complete when
* fetched from a manifest because most manifest formats do not have the
* required information.
* required information. Also applies the key systems mapping.
*
* @param {shaka.extern.DrmInfo} drmInfo
* @param {!Map.<string, string>} servers
* @param {!Map.<string, shaka.extern.AdvancedDrmConfiguration>}
* advancedConfigs
* @param {!Object.<string, string>} keySystemsMapping
* @private
*/
static fillInDrmInfoDefaults_(drmInfo, servers, advancedConfigs) {
if (!drmInfo.keySystem) {
static fillInDrmInfoDefaults_(drmInfo, servers, advancedConfigs,
keySystemsMapping) {
const originalKeySystem = drmInfo.keySystem;

if (!originalKeySystem) {
// This is a placeholder from the manifest parser for an unrecognized key
// system. Skip this entry, to avoid logging nonsensical errors.
return;
Expand All @@ -2254,14 +2259,14 @@ shaka.media.DrmEngine = class {
// The only way to get license servers from the manifest is not to specify
// any in your player config.

if (drmInfo.keySystem == 'org.w3.clearkey' && drmInfo.licenseServerUri) {
if (originalKeySystem == 'org.w3.clearkey' && drmInfo.licenseServerUri) {
// Preference 1: Clear Key with pre-configured keys will have a data URI
// assigned as its license server. Don't change anything.
return;
} else if (servers.size) {
// Preference 2: If anything is configured at the application level,
// override whatever was in the manifest.
const server = servers.get(drmInfo.keySystem) || '';
const server = servers.get(originalKeySystem) || '';

drmInfo.licenseServerUri = server;
} else {
Expand All @@ -2273,7 +2278,7 @@ shaka.media.DrmEngine = class {
drmInfo.keyIds = new Set();
}

const advancedConfig = advancedConfigs.get(drmInfo.keySystem);
const advancedConfig = advancedConfigs.get(originalKeySystem);

if (advancedConfig) {
if (!drmInfo.distinctiveIdentifierRequired) {
Expand Down Expand Up @@ -2307,6 +2312,10 @@ shaka.media.DrmEngine = class {
}
}

if (keySystemsMapping[originalKeySystem]) {
drmInfo.keySystem = keySystemsMapping[originalKeySystem];
}

// Chromecast has a variant of PlayReady that uses a different key
// system ID. Since manifest parsers convert the standard PlayReady
// UUID to the standard PlayReady key system ID, here we will switch
Expand All @@ -2315,7 +2324,7 @@ shaka.media.DrmEngine = class {
// player config uses the standard PlayReady ID for license server
// configuration.
if (window.cast && window.cast.__platform__) {
if (drmInfo.keySystem == 'com.microsoft.playready') {
if (originalKeySystem == 'com.microsoft.playready') {
drmInfo.keySystem = 'com.chromecast.playready';
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/util/player_configuration.js
Expand Up @@ -74,6 +74,7 @@ shaka.util.PlayerConfiguration = class {
logLicenseExchange: false,
updateExpirationTime: 1,
preferredKeySystems: [],
keySystemsMapping: {},
};

const manifest = {
Expand Down
3 changes: 2 additions & 1 deletion test/demo/demo_unit.js
Expand Up @@ -94,7 +94,8 @@ describe('Demo', () => {
.add('playRangeStart')
.add('playRangeEnd')
.add('manifest.dash.keySystemsByURI')
.add('manifest.hls.mediaPlaylistFullMimeType');
.add('manifest.hls.mediaPlaylistFullMimeType')
.add('drm.keySystemsMapping');

/**
* @param {!Object} section
Expand Down

0 comments on commit 5e107d5

Please sign in to comment.