Skip to content

Commit 4a524c3

Browse files
authored
Enable key status handling for streams that do not provide DRM information the manifest but rely on the pssh boxes (Dash-Industry-Forum#4734)
1 parent b345e81 commit 4a524c3

File tree

3 files changed

+56
-44
lines changed

3 files changed

+56
-44
lines changed

index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4127,7 +4127,7 @@ declare namespace dashjs {
41274127

41284128
getSupportedKeySystemMetadataFromContentProtection(cps: object[], protDataSet: ProtectionDataSet, sessionType: string): object[];
41294129

4130-
getSupportedKeySystemsFromSegmentPssh(initData: ArrayBuffer, protDataSet: ProtectionDataSet, sessionType: string): object[];
4130+
getSupportedKeySystemMetadataFromSegmentPssh(initData: ArrayBuffer, protDataSet: ProtectionDataSet, sessionType: string): object[];
41314131

41324132
initDataEquals(initData1: ArrayBuffer, initData2: ArrayBuffer): boolean;
41334133

src/streaming/protection/controllers/ProtectionController.js

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,54 +1053,56 @@ function ProtectionController(config) {
10531053
* @private
10541054
*/
10551055
function _onNeedKey(event, retry) {
1056-
if (!settings.get().streaming.protection.ignoreEmeEncryptedEvent) {
1057-
logger.debug('DRM: onNeedKey');
1056+
if (settings.get().streaming.protection.ignoreEmeEncryptedEvent) {
1057+
return
1058+
}
10581059

1059-
// Ignore non-cenc initData
1060-
if (event.key.initDataType !== ProtectionConstants.INITIALIZATION_DATA_TYPE_CENC) {
1061-
logger.warn('DRM: Only \'cenc\' initData is supported! Ignoring initData of type: ' + event.key.initDataType);
1062-
return;
1063-
}
1060+
logger.debug('DRM: onNeedKey');
10641061

1065-
if (mediaInfoArr.length === 0) {
1066-
logger.warn('DRM: onNeedKey called before initializeForMedia, wait until initialized');
1067-
retry = typeof retry === 'undefined' ? 1 : retry + 1;
1068-
if (retry < NEEDKEY_BEFORE_INITIALIZE_RETRIES) {
1069-
needkeyRetries.push(setTimeout(() => {
1070-
_onNeedKey(event, retry);
1071-
}, NEEDKEY_BEFORE_INITIALIZE_TIMEOUT));
1072-
return;
1073-
}
1074-
}
1062+
// Ignore non-cenc initData
1063+
if (event.key.initDataType !== ProtectionConstants.INITIALIZATION_DATA_TYPE_CENC) {
1064+
logger.warn('DRM: Only \'cenc\' initData is supported! Ignoring initData of type: ' + event.key.initDataType);
1065+
return;
1066+
}
10751067

1076-
// Some browsers return initData as Uint8Array (IE), some as ArrayBuffer (Chrome).
1077-
// Convert to ArrayBuffer
1078-
let abInitData = event.key.initData;
1079-
if (ArrayBuffer.isView(abInitData)) {
1080-
abInitData = abInitData.buffer;
1068+
if (mediaInfoArr.length === 0) {
1069+
logger.warn('DRM: onNeedKey called before initializeForMedia, wait until initialized');
1070+
retry = typeof retry === 'undefined' ? 1 : retry + 1;
1071+
if (retry < NEEDKEY_BEFORE_INITIALIZE_RETRIES) {
1072+
needkeyRetries.push(setTimeout(() => {
1073+
_onNeedKey(event, retry);
1074+
}, NEEDKEY_BEFORE_INITIALIZE_TIMEOUT));
1075+
return;
10811076
}
1077+
}
10821078

1083-
// If key system has already been selected and initData already seen, then do nothing
1084-
if (selectedKeySystem) {
1085-
const initDataForKS = CommonEncryption.getPSSHForKeySystem(selectedKeySystem, abInitData);
1086-
if (initDataForKS) {
1087-
// Check for duplicate initData
1088-
if (_isInitDataDuplicate(initDataForKS)) {
1089-
return;
1090-
}
1079+
// Some browsers return initData as Uint8Array (IE), some as ArrayBuffer (Chrome).
1080+
// Convert to ArrayBuffer
1081+
let abInitData = event.key.initData;
1082+
if (ArrayBuffer.isView(abInitData)) {
1083+
abInitData = abInitData.buffer;
1084+
}
1085+
1086+
// If key system has already been selected and initData already seen, then do nothing
1087+
if (selectedKeySystem) {
1088+
const initDataForKS = CommonEncryption.getPSSHForKeySystem(selectedKeySystem, abInitData);
1089+
if (initDataForKS) {
1090+
// Check for duplicate initData
1091+
if (_isInitDataDuplicate(initDataForKS)) {
1092+
return;
10911093
}
10921094
}
1095+
}
10931096

1094-
logger.debug('DRM: initData:', String.fromCharCode.apply(null, new Uint8Array(abInitData)));
1097+
logger.debug('DRM: initData:', String.fromCharCode.apply(null, new Uint8Array(abInitData)));
10951098

1096-
const supportedKs = protectionKeyController.getSupportedKeySystemsFromSegmentPssh(abInitData, applicationProvidedProtectionData, sessionType);
1097-
if (supportedKs.length === 0) {
1098-
logger.debug('DRM: Received needkey event with initData, but we don\'t support any of the key systems!');
1099-
return;
1100-
}
1101-
1102-
_handleKeySystemFromPssh(supportedKs);
1099+
const supportedKeySystemsMetadata = protectionKeyController.getSupportedKeySystemMetadataFromSegmentPssh(abInitData, applicationProvidedProtectionData, sessionType);
1100+
if (supportedKeySystemsMetadata.length === 0) {
1101+
logger.debug('DRM: Received needkey event with initData, but we don\'t support any of the key systems!');
1102+
return;
11031103
}
1104+
1105+
_handleKeySystemFromPssh(supportedKeySystemsMetadata);
11041106
}
11051107

11061108
/**
@@ -1162,7 +1164,7 @@ function ProtectionController(config) {
11621164

11631165
function areKeyIdsUsable(normalizedKeyIds) {
11641166
try {
1165-
if (!_shouldCheckKeyStatusMap(normalizedKeyIds)) {
1167+
if (!_shouldCheckKeyStatusMap(normalizedKeyIds, keyStatusMap)) {
11661168
return true;
11671169
}
11681170

@@ -1178,7 +1180,7 @@ function ProtectionController(config) {
11781180

11791181
function areKeyIdsExpired(normalizedKeyIds) {
11801182
try {
1181-
if (!_shouldCheckKeyStatusMap(normalizedKeyIds)) {
1183+
if (!_shouldCheckKeyStatusMap(normalizedKeyIds, keyStatusMap)) {
11821184
return false;
11831185
}
11841186

@@ -1192,7 +1194,17 @@ function ProtectionController(config) {
11921194
}
11931195
}
11941196

1195-
function _shouldCheckKeyStatusMap(normalizedKeyIds) {
1197+
function _shouldCheckKeyStatusMap(normalizedKeyIds, keyStatusMap) {
1198+
1199+
const allHaveStatus = keyStatusMap.size > 0 && [...normalizedKeyIds].every((normalizedKeyId) => {
1200+
const keyStatus = keyStatusMap.get(normalizedKeyId);
1201+
return typeof keyStatus !== 'undefined' && keyStatus !== '';
1202+
});
1203+
1204+
if (allHaveStatus) {
1205+
return true
1206+
}
1207+
11961208
const sessionTokens = protectionModel.getSessionTokens();
11971209

11981210
if (sessionTokens && sessionTokens.length > 0) {

src/streaming/protection/controllers/ProtectionKeyController.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ function ProtectionKeyController() {
266266
* @memberof module:ProtectionKeyController
267267
* @instance
268268
*/
269-
function getSupportedKeySystemsFromSegmentPssh(initData, protDataSet, sessionType) {
269+
function getSupportedKeySystemMetadataFromSegmentPssh(initData, protDataSet, sessionType) {
270270
let supportedKS = [];
271271
let pssh = CommonEncryption.parsePSSHList(initData);
272272
let ks, keySystemString;
@@ -395,7 +395,7 @@ function ProtectionKeyController() {
395395
getKeySystems,
396396
getLicenseServerModelInstance,
397397
getSupportedKeySystemMetadataFromContentProtection,
398-
getSupportedKeySystemsFromSegmentPssh,
398+
getSupportedKeySystemMetadataFromSegmentPssh,
399399
initDataEquals,
400400
initialize,
401401
isClearKey,

0 commit comments

Comments
 (0)