Skip to content

Commit ac5fc47

Browse files
committed
EME key-status cleanup (Multi-key handling #7517)
Get KEYID from init segment 'tenc' when not found elsewhere Fixes #7541 Remove key-loader promise caching for EME keys Add MediaKeySessionClosedReason result to eme-controller removeSession (fixes close spy on MediaKeysSessionMock)
1 parent b3addd9 commit ac5fc47

File tree

10 files changed

+860
-806
lines changed

10 files changed

+860
-806
lines changed

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

Lines changed: 66 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
55
```ts
66

7+
import { EventEmitter } from 'eventemitter3';
8+
79
// Warning: (ae-missing-release-tag) "AbrComponentAPI" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
810
//
911
// @public (undocumented)
@@ -1138,10 +1140,9 @@ export const enum DecrypterAesMode {
11381140
export type DRMSystemConfiguration = {
11391141
licenseUrl: string;
11401142
serverCertificateUrl?: string;
1141-
generateRequest?: (this: Hls, initDataType: string, initData: ArrayBuffer | null, keyContext: MediaKeySessionContextAndLevelKey) => {
1142-
initDataType: string;
1143-
initData: ArrayBuffer | null;
1144-
} | undefined | never;
1143+
generateRequest?: (this: Hls, initDataType: string, initData: ArrayBuffer | null, keyContext: MediaKeySessionContext & {
1144+
decryptdata: LevelKey;
1145+
}) => GenerateRequestFilterResult;
11451146
};
11461147

11471148
// Warning: (ae-missing-release-tag) "DRMSystemOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -1206,15 +1207,13 @@ export class EMEController extends Logger implements ComponentAPI {
12061207
// (undocumented)
12071208
destroy(): void;
12081209
// (undocumented)
1209-
getKeyStatus(decryptdata: LevelKey): MediaKeyStatus | undefined;
1210-
// (undocumented)
1211-
getKeySystemAccess(keySystemsToAttempt: KeySystems[]): Promise<void>;
1212-
// (undocumented)
1213-
getSelectedKeySystemFormats(): KeySystemFormats[];
1210+
loadClear(loadingFrag: Fragment, encryptedFragments: Fragment[], startFragRequested: boolean): Promise<void> | null;
1211+
// Warning: (ae-forgotten-export) The symbol "EncryptedFragment" needs to be exported by the entry point hls.d.ts
1212+
//
12141213
// (undocumented)
1215-
loadKey(data: KeyLoadedData): Promise<MediaKeySessionContext>;
1214+
loadKey(frag: EncryptedFragment): Promise<LevelKey>;
12161215
// (undocumented)
1217-
selectKeySystem(keySystemsToAttempt: KeySystems[]): Promise<KeySystemFormats>;
1216+
renewKeySession(levelKey: LevelKey): void;
12181217
// (undocumented)
12191218
selectKeySystemFormat(frag: Fragment): Promise<KeySystemFormats>;
12201219
}
@@ -1223,8 +1222,12 @@ export class EMEController extends Logger implements ComponentAPI {
12231222
//
12241223
// @public (undocumented)
12251224
export type EMEControllerConfig = {
1226-
licenseXhrSetup?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContextAndLevelKey, licenseChallenge: Uint8Array) => void | Uint8Array | Promise<Uint8Array | void>;
1227-
licenseResponseCallback?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContextAndLevelKey) => ArrayBuffer;
1225+
licenseXhrSetup?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext & {
1226+
decryptdata: LevelKey;
1227+
}, licenseChallenge: Uint8Array) => void | Uint8Array | Promise<Uint8Array | void>;
1228+
licenseResponseCallback?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext & {
1229+
decryptdata: LevelKey;
1230+
}) => ArrayBuffer;
12281231
emeEnabled: boolean;
12291232
widevineLicenseUrl?: string;
12301233
drmSystems: DRMSystemsConfiguration | undefined;
@@ -2054,6 +2057,14 @@ export type GapControllerConfig = {
20542057
skipBufferHolePadding: number;
20552058
};
20562059

2060+
// Warning: (ae-missing-release-tag) "GenerateRequestFilterResult" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
2061+
//
2062+
// @public (undocumented)
2063+
export type GenerateRequestFilterResult = {
2064+
initDataType: string;
2065+
initData: ArrayBuffer | null;
2066+
} | undefined | never;
2067+
20572068
// Warning: (ae-missing-release-tag) "HdcpLevel" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
20582069
//
20592070
// @public (undocumented)
@@ -3038,28 +3049,13 @@ export class KeyLoader extends Logger implements ComponentAPI {
30383049
// (undocumented)
30393050
abort(type?: PlaylistLevelType): void;
30403051
// (undocumented)
3041-
createKeyLoadError(frag: Fragment, details: ErrorDetails | undefined, error: Error, networkDetails?: NullableNetworkDetails, response?: {
3042-
url: string;
3043-
data: undefined;
3044-
code: number;
3045-
text: string;
3046-
}): LoadError;
3047-
// (undocumented)
30483052
destroy(): void;
30493053
// (undocumented)
3050-
detach(): void;
3051-
// (undocumented)
30523054
emeController: EMEController | null;
30533055
// (undocumented)
30543056
load(frag: Fragment): Promise<KeyLoadedData>;
30553057
// (undocumented)
3056-
loadClear(loadingFrag: Fragment, encryptedFragments: Fragment[], startFragRequested: boolean): null | Promise<void>;
3057-
// (undocumented)
3058-
loadInternal(frag: Fragment, keySystemFormat?: KeySystemFormats): Promise<KeyLoadedData>;
3059-
// (undocumented)
3060-
loadKeyEME(keyInfo: KeyLoaderInfo, frag: Fragment): Promise<KeyLoadedData>;
3061-
// (undocumented)
3062-
loadKeyHTTP(keyInfo: KeyLoaderInfo, frag: Fragment): Promise<KeyLoadedData>;
3058+
loadClear(loadingFrag: Fragment, encryptedFragments: Fragment[], startFragRequested: boolean): Promise<void> | null;
30633059
}
30643060

30653061
// Warning: (ae-missing-release-tag) "KeyLoaderContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -3079,11 +3075,9 @@ export interface KeyLoaderInfo {
30793075
// (undocumented)
30803076
decryptdata: LevelKey;
30813077
// (undocumented)
3082-
keyLoadPromise: Promise<KeyLoadedData> | null;
3078+
keyLoadPromise?: Promise<KeyLoadedData> | null;
30833079
// (undocumented)
3084-
loader: Loader<KeyLoaderContext> | null;
3085-
// (undocumented)
3086-
mediaKeySessionContext: MediaKeySessionContext | null;
3080+
loader?: Loader<KeyLoaderContext> | null;
30873081
}
30883082

30893083
// Warning: (ae-missing-release-tag) "KeyLoadingData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -3094,6 +3088,20 @@ export interface KeyLoadingData {
30943088
frag: Fragment;
30953089
}
30963090

3091+
// Warning: (ae-missing-release-tag) "KeyRequests" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
3092+
//
3093+
// @public (undocumented)
3094+
export type KeyRequests = {
3095+
[uri: string]: LicenseAndKeysRequest | undefined;
3096+
};
3097+
3098+
// Warning: (ae-missing-release-tag) "KeyStatuses" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
3099+
//
3100+
// @public (undocumented)
3101+
export type KeyStatuses = {
3102+
[keyId: string]: MediaKeyStatus;
3103+
};
3104+
30973105
// Warning: (ae-missing-release-tag) "KeySystemFormats" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
30983106
//
30993107
// @public (undocumented)
@@ -3122,6 +3130,13 @@ export const enum KeySystems {
31223130
WIDEVINE = "com.widevine.alpha"
31233131
}
31243132

3133+
// Warning: (ae-missing-release-tag) "KeyTimeouts" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
3134+
//
3135+
// @public (undocumented)
3136+
export type KeyTimeouts = {
3137+
[keyId: string]: number;
3138+
};
3139+
31253140
// Warning: (ae-missing-release-tag) "LatencyControllerConfig" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
31263141
//
31273142
// @public (undocumented)
@@ -3605,6 +3620,20 @@ export interface LevelUpdatedData {
36053620
level: number;
36063621
}
36073622

3623+
// Warning: (ae-missing-release-tag) "LicenseAndKeysRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
3624+
//
3625+
// @public (undocumented)
3626+
export type LicenseAndKeysRequest = EventEmitter & {
3627+
status: 'initialized' | 'started' | 'generated' | MediaKeyMessageType;
3628+
licenseXhr?: XMLHttpRequest;
3629+
requestErrors: {
3630+
status: number;
3631+
message: string;
3632+
}[];
3633+
onmessage?: (this: MediaKeySession, ev: MediaKeyMessageEvent) => any;
3634+
onkeystatuseschange?: (this: MediaKeySession, ev: Event) => any;
3635+
};
3636+
36083637
// Warning: (ae-missing-release-tag) "LiveBackBufferData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
36093638
//
36103639
// @public @deprecated (undocumented)
@@ -4044,47 +4073,13 @@ export type MediaKeyFunc = (keySystem: KeySystems, supportedConfigurations: Medi
40444073
// Warning: (ae-missing-release-tag) "MediaKeySessionContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
40454074
//
40464075
// @public (undocumented)
4047-
export interface MediaKeySessionContext {
4048-
// (undocumented)
4049-
keyStatuses: {
4050-
[keyId: string]: MediaKeyStatus;
4051-
};
4052-
// (undocumented)
4053-
keyStatusTimeouts?: {
4054-
[keyId: string]: number;
4055-
};
4056-
// (undocumented)
4057-
keySystem: KeySystems;
4058-
// (undocumented)
4059-
levelKeys: LevelKey[];
4060-
// (undocumented)
4061-
licenseXhr?: XMLHttpRequest;
4062-
// (undocumented)
4063-
mediaKeys: MediaKeys;
4064-
// (undocumented)
4065-
mediaKeysSession: MediaKeySession;
4066-
// (undocumented)
4067-
_onkeystatuseschange?: (this: MediaKeySession, ev: Event) => any;
4068-
// (undocumented)
4069-
_onmessage?: (this: MediaKeySession, ev: MediaKeyMessageEvent) => any;
4070-
}
4071-
4072-
// Warning: (ae-missing-release-tag) "MediaKeySessionContextAndLevelKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
4073-
//
4074-
// @public (undocumented)
4075-
export type MediaKeySessionContextAndLevelKey = {
4076-
decryptdata: LevelKey;
4076+
export type MediaKeySessionContext = {
40774077
keySystem: KeySystems;
4078-
levelKeys: LevelKey[];
40794078
mediaKeys: MediaKeys;
40804079
mediaKeysSession: MediaKeySession;
4081-
keyStatuses: {
4082-
[keyId: string]: MediaKeyStatus;
4083-
};
4084-
keyStatusTimeouts?: {
4085-
[keyId: string]: number;
4086-
};
4087-
licenseXhr?: XMLHttpRequest;
4080+
keyRequests: KeyRequests;
4081+
keyStatuses: KeyStatuses;
4082+
keyStatusTimeouts?: KeyTimeouts;
40884083
};
40894084

40904085
// 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/config.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ import { requestMediaKeySystemAccess } from './utils/mediakeys-helper';
1818
import { clamp } from './utils/number';
1919
import { stringify } from './utils/safe-json-stringify';
2020
import XhrLoader from './utils/xhr-loader';
21-
import type { MediaKeySessionContextAndLevelKey } from './controller/eme-controller';
21+
import type {
22+
GenerateRequestFilterResult,
23+
MediaKeySessionContext,
24+
} from './controller/eme-controller';
2225
import type Hls from './hls';
26+
import type { LevelKey } from './loader/level-key';
2327
import type {
2428
FragmentLoaderContext,
2529
Loader,
@@ -95,11 +99,8 @@ export type DRMSystemConfiguration = {
9599
this: Hls,
96100
initDataType: string,
97101
initData: ArrayBuffer | null,
98-
keyContext: MediaKeySessionContextAndLevelKey,
99-
) =>
100-
| { initDataType: string; initData: ArrayBuffer | null }
101-
| undefined
102-
| never;
102+
keyContext: MediaKeySessionContext & { decryptdata: LevelKey },
103+
) => GenerateRequestFilterResult;
103104
};
104105

105106
export type DRMSystemsConfiguration = Partial<
@@ -111,14 +112,14 @@ export type EMEControllerConfig = {
111112
this: Hls,
112113
xhr: XMLHttpRequest,
113114
url: string,
114-
keyContext: MediaKeySessionContextAndLevelKey,
115+
keyContext: MediaKeySessionContext & { decryptdata: LevelKey },
115116
licenseChallenge: Uint8Array,
116117
) => void | Uint8Array | Promise<Uint8Array | void>;
117118
licenseResponseCallback?: (
118119
this: Hls,
119120
xhr: XMLHttpRequest,
120121
url: string,
121-
keyContext: MediaKeySessionContextAndLevelKey,
122+
keyContext: MediaKeySessionContext & { decryptdata: LevelKey },
122123
) => ArrayBuffer;
123124
emeEnabled: boolean;
124125
widevineLicenseUrl?: string;

src/controller/base-stream-controller.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,6 @@ export default class BaseStreamController
349349
removeEventListener(media, 'seeking', this.onMediaSeeking);
350350
removeEventListener(media, 'ended', this.onMediaEnded);
351351

352-
if (this.keyLoader && !transferringMedia) {
353-
this.keyLoader.detach();
354-
}
355352
this.media = this.mediaBuffer = null;
356353
this.loopSn = undefined;
357354
if (transferringMedia) {

0 commit comments

Comments
 (0)