Skip to content

Commit 8fa766e

Browse files
committed
Fix "sinf" type argumet in request generated from "encrypted" event
1 parent a015a10 commit 8fa766e

File tree

4 files changed

+54
-9
lines changed

4 files changed

+54
-9
lines changed

api-extractor/report/hls.js.api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3452,6 +3452,8 @@ export class LevelKey implements DecryptData {
34523452
// (undocumented)
34533453
pssh: Uint8Array<ArrayBuffer> | null;
34543454
// (undocumented)
3455+
scheme?: string;
3456+
// (undocumented)
34553457
static setKeyIdForUri(uri: string, keyId: Uint8Array<ArrayBuffer>): void;
34563458
// (undocumented)
34573459
readonly uri: string;
@@ -4091,6 +4093,11 @@ export type MediaKeySessionContext = {
40914093
keyRequests: KeyRequests;
40924094
keyStatuses: KeyStatuses;
40934095
keyStatusTimeouts?: KeyTimeouts;
4096+
createdFor: {
4097+
levelKey: LevelKey;
4098+
reason: LicenseRequestReason;
4099+
};
4100+
initialized: boolean;
40944101
};
40954102

40964103
// Warning: (ae-missing-release-tag) "MediaOverrides" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)

src/controller/eme-controller.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ export type MediaKeySessionContext = {
9494
keyRequests: KeyRequests;
9595
keyStatuses: KeyStatuses;
9696
keyStatusTimeouts?: KeyTimeouts;
97+
createdFor: { levelKey: LevelKey; reason: LicenseRequestReason };
98+
initialized: boolean;
9799
};
98100

99101
export class EMEKeyError extends Error {
@@ -340,20 +342,32 @@ class EMEController extends Logger implements ComponentAPI {
340342
levelKey: LevelKey,
341343
reason: LicenseRequestReason,
342344
): MediaKeySessionContext {
343-
this.log(
344-
`Creating key-system session "${keySystem}" keyId: ${arrayToHex(
345-
levelKey.keyId || ([] as number[]),
346-
)} keyUri: ${levelKey.uri} for "${reason}"`,
347-
);
345+
const { mediaKeySessions } = this;
346+
const message = ` key-system session "${keySystem}" keyId: ${arrayToHex(
347+
levelKey.keyId || ([] as number[]),
348+
)} keyUri: ${levelKey.uri} for "${reason}"`;
349+
for (let i = 0; i < mediaKeySessions.length; i++) {
350+
const context = mediaKeySessions[i];
351+
if (
352+
!context.initialized &&
353+
context.createdFor.levelKey.uri === levelKey.uri
354+
) {
355+
this.log(`Retrieved${message}`);
356+
return context;
357+
}
358+
}
359+
this.log(`Creating${message}`);
348360
const mediaKeysSession = mediaKeys.createSession();
349361
const mediaKeySessionContext: MediaKeySessionContext = {
350362
keySystem,
351363
mediaKeys,
352364
mediaKeysSession,
353365
keyRequests: {},
354366
keyStatuses: {},
367+
createdFor: { levelKey, reason },
368+
initialized: false,
355369
};
356-
this.mediaKeySessions.push(mediaKeySessionContext);
370+
mediaKeySessions.push(mediaKeySessionContext);
357371
return mediaKeySessionContext;
358372
}
359373

@@ -600,7 +614,7 @@ class EMEController extends Logger implements ComponentAPI {
600614
.then((keySessionContext) => {
601615
this.throwIfDestroyed();
602616
// Create key-request, session message event listener, key-status listeners
603-
const scheme = 'cenc';
617+
const scheme = levelKey.scheme || 'cenc';
604618
const initData = levelKey.pssh ? levelKey.pssh.buffer : null;
605619
return this.generateRequestWithPreferredKeySession(
606620
keySessionContext,
@@ -757,6 +771,7 @@ class EMEController extends Logger implements ComponentAPI {
757771
decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1)
758772
) {
759773
if (!decryptdata.pssh) {
774+
decryptdata.scheme = initDataType;
760775
decryptdata.pssh = new Uint8Array(initData);
761776
decryptdata.keyId = keyId;
762777
LevelKey.setKeyIdForUri(decryptdata.uri, keyId);
@@ -771,6 +786,7 @@ class EMEController extends Logger implements ComponentAPI {
771786
}
772787
if (!keySessionContextPromise) {
773788
if (levelKeys.length) {
789+
levelKeys[0].scheme ||= initDataType;
774790
levelKeys[0].pssh ||= new Uint8Array(initData);
775791
return this.getSessionForKey(
776792
levelKeys[0],
@@ -863,6 +879,9 @@ class EMEController extends Logger implements ComponentAPI {
863879
'Invalid response from configured generateRequest filter',
864880
);
865881
}
882+
levelKey.scheme = mappedInitData.initDataType
883+
? mappedInitData.initDataType
884+
: 'cenc';
866885
const pssh = mappedInitData.initData ? mappedInitData.initData : null;
867886
levelKey.pssh = pssh ? new Uint8Array(pssh) : null;
868887
return mappedInitData;
@@ -894,6 +913,12 @@ class EMEController extends Logger implements ComponentAPI {
894913
initDataType = mappedInitData.initDataType;
895914
}
896915

916+
if (!reason.startsWith('encrypted-event')) {
917+
this.log(`Skipping key-session request for "${reason}" (no initData)`);
918+
// resolve key so that media is appended and initData is received in "encrypted" event
919+
return Promise.resolve(context);
920+
}
921+
897922
if (initData === null) {
898923
if (reason.startsWith('encrypted-event')) {
899924
return Promise.reject(
@@ -1099,6 +1124,7 @@ class EMEController extends Logger implements ComponentAPI {
10991124
);
11001125

11011126
requestEmitter.status = 'started';
1127+
context.initialized = true;
11021128
return context.mediaKeysSession
11031129
.generateRequest(initDataType, initData)
11041130
.then(() => {

src/loader/level-key.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class LevelKey implements DecryptData {
3333
public key: Uint8Array<ArrayBuffer> | null = null;
3434
public keyId: Uint8Array<ArrayBuffer> | null = null;
3535
public pssh: Uint8Array<ArrayBuffer> | null = null;
36+
public scheme?: string;
3637

3738
static clearKeyUriToKeyIdMap() {
3839
keyUriToKeyIdMap = {};
@@ -221,9 +222,8 @@ export class LevelKey implements DecryptData {
221222
if (keyId) {
222223
this.keyId = keyId;
223224
LevelKey.setKeyIdForUri(this.uri, keyId);
224-
} else {
225-
this.keyId = LevelKey.addKeyIdForUri(this.uri);
226225
}
226+
// else if the key id could not be identified from the playlist, wait for the init segment
227227
}
228228

229229
return this;

tests/unit/controller/eme-controller.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,15 @@ describe('EMEController', function () {
387387
});
388388

389389
const keySession = new MediaKeySessionMock2();
390+
const levelKey = getParsedLevelKey();
390391
const mockMediaKeySessionContext: MediaKeySessionContext = {
391392
keySystem: KeySystems.FAIRPLAY,
392393
mediaKeys: new MediaKeysMock(),
393394
mediaKeysSession: keySession,
394395
keyRequests: {},
395396
keyStatuses: {},
397+
createdFor: { levelKey, reason: 'playlist-key' },
398+
initialized: false,
396399
};
397400

398401
const keyStatuses = emeController.getKeyStatuses(
@@ -610,12 +613,15 @@ describe('EMEController', function () {
610613
});
611614

612615
const keySession = new MediaKeySessionMock();
616+
const levelKey = getParsedLevelKey();
613617
const mockMediaKeySessionContext: MediaKeySessionContext = {
614618
keySystem: KeySystems.FAIRPLAY,
615619
mediaKeys: new MediaKeysMock(),
616620
mediaKeysSession: keySession,
617621
keyRequests: {},
618622
keyStatuses: {},
623+
createdFor: { levelKey, reason: 'playlist-key' },
624+
initialized: false,
619625
};
620626

621627
emeController.mediaKeySessions = [mockMediaKeySessionContext];
@@ -655,12 +661,15 @@ describe('EMEController', function () {
655661
});
656662

657663
const keySession = new MediaKeySessionMock();
664+
const levelKey = getParsedLevelKey();
658665
const mockMediaKeySessionContext: MediaKeySessionContext = {
659666
keySystem: KeySystems.FAIRPLAY,
660667
mediaKeys: new MediaKeysMock(),
661668
mediaKeysSession: keySession,
662669
keyRequests: {},
663670
keyStatuses: {},
671+
createdFor: { levelKey, reason: 'playlist-key' },
672+
initialized: false,
664673
};
665674
const keySessionCloseSpy = sinon.spy(keySession, 'close');
666675

@@ -712,12 +721,15 @@ describe('EMEController', function () {
712721
});
713722

714723
const keySession = new MediaKeySessionMock();
724+
const levelKey = getParsedLevelKey();
715725
const mockMediaKeySessionContext: MediaKeySessionContext = {
716726
keySystem: KeySystems.FAIRPLAY,
717727
mediaKeys: new MediaKeysMock(),
718728
mediaKeysSession: keySession,
719729
keyRequests: {},
720730
keyStatuses: {},
731+
createdFor: { levelKey, reason: 'playlist-key' },
732+
initialized: false,
721733
};
722734
const keySessionCloseSpy = sinon.spy(keySession, 'close');
723735

0 commit comments

Comments
 (0)