Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for multiple robustness levels in drm #7753

Merged
merged 13 commits into from
Dec 23, 2024
13 changes: 9 additions & 4 deletions demo/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ shakaDemo.Config = class {
.addBoolInput_('Ignore duplicate init data',
'drm.ignoreDuplicateInitData');
const advanced = shakaDemoMain.getConfiguration().drm.advanced || {};
const addDRMAdvancedField = (name, valueName, suggestions) => {
const addDRMAdvancedField = (name, valueName, suggestions,
arrayString = false) => {
// All advanced fields of a given type are set at once.
this.addDatalistInput_(name, suggestions, (input) => {
// Add in any common drmSystem not currently in advanced.
Expand All @@ -150,7 +151,9 @@ shakaDemo.Config = class {
}
// Set the robustness.
for (const drmSystem in advanced) {
advanced[drmSystem][valueName] = input.value;
advanced[drmSystem][valueName] = arrayString ?
input.value.split(',').filter(Boolean) :
input.value;
}
shakaDemoMain.configure('drm.advanced', advanced);
shakaDemoMain.remakeHash();
Expand All @@ -176,9 +179,11 @@ shakaDemo.Config = class {
const sessionTypeSuggestions = ['temporary', 'persistent-license'];

addDRMAdvancedField(
'Video Robustness', 'videoRobustness', robustnessSuggestions);
'Video Robustness', 'videoRobustness', robustnessSuggestions,
/* arrayString= */ true);
addDRMAdvancedField(
'Audio Robustness', 'audioRobustness', robustnessSuggestions);
'Audio Robustness', 'audioRobustness', robustnessSuggestions,
/* arrayString= */ true);
addDRMAdvancedField('Session Type', 'sessionType', sessionTypeSuggestions);

this.addRetrySection_('drm', 'DRM Retry Parameters');
Expand Down
26 changes: 18 additions & 8 deletions demo/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -949,12 +949,18 @@ shakaDemo.Main = class {
advanced[drmSystem] = shakaDemo.Main.defaultAdvancedDrmConfig();
}
if ('videoRobustness' in params) {
advanced[drmSystem].videoRobustness = params['videoRobustness'];
advanced[drmSystem].videoRobustness =
params['videoRobustness'].split(',');
}
if ('audioRobustness' in params) {
advanced[drmSystem].audioRobustness = params['audioRobustness'];
advanced[drmSystem].audioRobustness =
params['audioRobustness'].split(',');
}
}

if ('audioRobustness' in params || 'videoRobustness' in params) {
this.configure('drm.advanced', advanced);
}
}
}
if ('lang' in params) {
Expand Down Expand Up @@ -1499,11 +1505,15 @@ shakaDemo.Main = class {
for (const drmSystem of shakaDemo.Main.commonDrmSystems) {
const advancedFor = advanced[drmSystem];
if (advancedFor) {
if (advancedFor.videoRobustness) {
params.push('videoRobustness=' + advancedFor.videoRobustness);
if (advancedFor.videoRobustness &&
advancedFor.videoRobustness.length) {
params.push('videoRobustness=' +
advancedFor.videoRobustness.join());
}
if (advancedFor.audioRobustness) {
params.push('audioRobustness=' + advancedFor.audioRobustness);
if (advancedFor.audioRobustness &&
advancedFor.audioRobustness.length) {
params.push('audioRobustness=' +
advancedFor.audioRobustness.join());
}
break;
}
Expand Down Expand Up @@ -1933,8 +1943,8 @@ shakaDemo.Main = class {
return {
distinctiveIdentifierRequired: false,
persistentStateRequired: false,
videoRobustness: '',
audioRobustness: '',
videoRobustness: [],
audioRobustness: [],
sessionType: '',
serverCertificate: new Uint8Array(0),
serverCertificateUri: '',
Expand Down
1 change: 1 addition & 0 deletions docs/tutorials/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ application:
`panicThreshold`. (deprecated in v4.10.0)
- `useSafariBehaviorForLive` has been removed.
- `parsePrftBox` has been removed.
- `videoRobustness` and `audioRobustness` are now only an array of strings. (deprecated in v4.13.0)

- Plugin changes:
- `TextDisplayer` plugins must implement the `configure()` method.
Expand Down
26 changes: 14 additions & 12 deletions externs/shaka/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,8 +808,8 @@ shaka.extern.ProducerReferenceTime;
* @typedef {{
* distinctiveIdentifierRequired: boolean,
* persistentStateRequired: boolean,
* videoRobustness: string,
* audioRobustness: string,
* videoRobustness: Array.<string>,
* audioRobustness: Array.<string>,
* serverCertificate: Uint8Array,
* serverCertificateUri: string,
* individualizationServer: string,
Expand All @@ -827,16 +827,18 @@ shaka.extern.ProducerReferenceTime;
* state, e.g., for persistent license storage.
* <br>
* Defaults to <code>false</code>.
* @property {string} videoRobustness
* A key-system-specific string that specifies a required security level for
* video.
* <br>
* Defaults to <code>''</code>, i.e., no specific robustness required.
* @property {string} audioRobustness
* A key-system-specific string that specifies a required security level for
* audio.
* <br>
* Defaults to <code>''</code>, i.e., no specific robustness required.
* @property {Array.<string>} videoRobustness
* A key-system-specific Array of strings that specifies a required security
* level for video. For multiple robustness levels, list items in priority
* order.
* <br>
* Defaults to <code>[]</code>, i.e., no specific robustness required.
* @property {Array.<string>} audioRobustness
* A key-system-specific Array of strings that specifies a required security
* level for audio. For multiple robustness levels, list items in priority
* order.
* <br>
* Defaults to <code>[]</code>, i.e., no specific robustness required.
* @property {Uint8Array} serverCertificate
* <i>An empty certificate (<code>byteLength==0</code>) will be treated as
* <code>null</code>.</i> <br>
Expand Down
60 changes: 53 additions & 7 deletions lib/drm/drm_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,57 @@ shaka.drm.DrmEngine = class {
/** @type {!Map.<string, MediaKeySystemConfiguration>} */
let configsByKeySystem;

/**
* Expand robustness into multiple drm infos if multiple video robustness
* levels were provided.
*
* robustness can be either a single item as a string or multiple items as
* an array of strings.
*/
const expandRobustness = (drmInfos, robustnessType) => {
const newDrmInfos = [];
for (const drmInfo of drmInfos) {
let items = drmInfo[robustnessType] ||
(this.config_.advanced &&
this.config_.advanced[drmInfo.keySystem] &&
this.config_.advanced[drmInfo.keySystem][robustnessType]) || '';
if (typeof items === 'string') {
// if drmInfo's robustness has already been expanded,
// use the drmInfo directly.
newDrmInfos.push(drmInfo);
} else if (Array.isArray(items)) {
if (items.length === 0) {
items = [''];
}
for (const item of items) {
newDrmInfos.push(
Object.assign({}, drmInfo, {[robustnessType]: item}),
);
}
}
}
return newDrmInfos;
};

for (const variant of variants) {
if (variant.video) {
variant.video.drmInfos =
expandRobustness(variant.video.drmInfos,
'videoRobustness');
variant.video.drmInfos =
expandRobustness(variant.video.drmInfos,
'audioRobustness');
}
if (variant.audio) {
variant.audio.drmInfos =
expandRobustness(variant.audio.drmInfos,
'videoRobustness');
variant.audio.drmInfos =
expandRobustness(variant.audio.drmInfos,
'audioRobustness');
}
}

// We should get the decodingInfo results for the variants after we filling
// in the drm infos, and before queryMediaKeys_().
await shaka.util.StreamUtils.getDecodingInfosForVariants(variants,
Expand Down Expand Up @@ -2505,13 +2556,8 @@ shaka.drm.DrmEngine = class {
advancedConfig.persistentStateRequired;
}

if (!drmInfo.videoRobustness) {
drmInfo.videoRobustness = advancedConfig.videoRobustness;
}

if (!drmInfo.audioRobustness) {
drmInfo.audioRobustness = advancedConfig.audioRobustness;
}
// robustness will be filled in with defaults, if needed, in
// expandRobustness

if (!drmInfo.serverCertificate) {
drmInfo.serverCertificate = advancedConfig.serverCertificate;
Expand Down
32 changes: 32 additions & 0 deletions lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -4047,6 +4047,38 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
config['streaming']['autoLowLatencyMode'];
delete config['streaming']['autoLowLatencyMode'];
}

// Deprecate AdvancedDrmConfiguration's videoRobustness and audioRobustness
// as a string. It's now an array of strings.
if (config['drm'] && config['drm']['advanced']) {
let fixedUp = false;
for (const keySystem in config['drm']['advanced']) {
const {videoRobustness, audioRobustness} =
config['drm']['advanced'][keySystem];
if ('videoRobustness' in config['drm']['advanced'][keySystem] &&
!Array.isArray(
config['drm']['advanced'][keySystem]['videoRobustness'])) {
config['drm']['advanced'][keySystem]['videoRobustness'] =
[videoRobustness];
fixedUp = true;
}
if ('audioRobustness' in config['drm']['advanced'][keySystem] &&
!Array.isArray(
config['drm']['advanced'][keySystem]['audioRobustness'])) {
config['drm']['advanced'][keySystem]['audioRobustness'] =
[audioRobustness];
fixedUp = true;
}
}

if (fixedUp) {
shaka.Deprecate.deprecateFeature(5,
'AdvancedDrmConfiguration\'s videoRobustness and audioRobustness',
'These properties are no longer strings but array of strings, ' +
'please update your usage of these properties.');
}
}

const ret = shaka.util.PlayerConfiguration.mergeConfigObjects(
this.config_, config, this.defaultConfig_());

Expand Down
4 changes: 2 additions & 2 deletions lib/util/player_configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,8 @@ shaka.util.PlayerConfiguration = class {
'.drm.advanced': {
distinctiveIdentifierRequired: false,
persistentStateRequired: false,
videoRobustness: '',
audioRobustness: '',
videoRobustness: [],
audioRobustness: [],
sessionType: '',
serverCertificate: new Uint8Array(0),
serverCertificateUri: '',
Expand Down
Loading
Loading