Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f3884fa

Browse files
committed
Fix MediaKeys cleanup on player destroy and reuse (setMediaKeys(null) never called after #6966)
Address Uint8Array type parameter issues
1 parent 4cc80bf commit f3884fa

File tree

3 files changed

+46
-31
lines changed

3 files changed

+46
-31
lines changed

src/controller/eme-controller.ts

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import { EventEmitter } from 'eventemitter3';
77
import { ErrorDetails, ErrorTypes } from '../errors';
88
import { Events } from '../events';
99
import { LevelKey } from '../loader/level-key';
10+
import {
11+
addEventListener,
12+
removeEventListener,
13+
} from '../utils/event-listener-helper';
1014
import Hex from '../utils/hex';
1115
import { Logger } from '../utils/logger';
1216
import {
@@ -105,10 +109,8 @@ class EMEController extends Logger implements ComponentAPI {
105109
}
106110

107111
public destroy() {
108-
const media = this.media;
109-
this.unregisterListeners();
112+
this.onDestroying();
110113
this.onMediaDetached();
111-
this._clear(media);
112114
// Remove any references that could be held in config options or callbacks
113115
const config = this.config;
114116
config.requestMediaKeySystemAccessFunc = null;
@@ -125,13 +127,15 @@ class EMEController extends Logger implements ComponentAPI {
125127
this.hls.on(Events.MEDIA_DETACHED, this.onMediaDetached, this);
126128
this.hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
127129
this.hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
130+
this.hls.on(Events.DESTROYING, this.onDestroying, this);
128131
}
129132

130133
private unregisterListeners() {
131134
this.hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
132135
this.hls.off(Events.MEDIA_DETACHED, this.onMediaDetached, this);
133136
this.hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
134137
this.hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
138+
this.hls.off(Events.DESTROYING, this.onDestroying, this);
135139
}
136140

137141
private getLicenseServerUrl(keySystem: KeySystems): string | undefined {
@@ -375,7 +379,7 @@ class EMEController extends Logger implements ComponentAPI {
375379

376380
private updateKeySession(
377381
mediaKeySessionContext: MediaKeySessionContext,
378-
data: Uint8Array,
382+
data: Uint8Array<ArrayBuffer>,
379383
): Promise<void> {
380384
const keySession = mediaKeySessionContext.mediaKeysSession;
381385
this.log(
@@ -879,8 +883,9 @@ class EMEController extends Logger implements ComponentAPI {
879883
}
880884
});
881885

882-
context.mediaKeysSession.addEventListener('message', onmessage);
883-
context.mediaKeysSession.addEventListener(
886+
addEventListener(context.mediaKeysSession, 'message', onmessage);
887+
addEventListener(
888+
context.mediaKeysSession,
884889
'keystatuseschange',
885890
onkeystatuseschange,
886891
);
@@ -1108,8 +1113,8 @@ class EMEController extends Logger implements ComponentAPI {
11081113

11091114
private unpackPlayReadyKeyMessage(
11101115
xhr: XMLHttpRequest,
1111-
licenseChallenge: Uint8Array,
1112-
): Uint8Array {
1116+
licenseChallenge: Uint8Array<ArrayBuffer>,
1117+
): Uint8Array<ArrayBuffer> {
11131118
// On Edge, the raw license message is UTF-16-encoded XML. We need
11141119
// to unpack the Challenge element (base64-encoded string containing the
11151120
// actual license request) and any HttpHeader elements (sent as request
@@ -1156,8 +1161,11 @@ class EMEController extends Logger implements ComponentAPI {
11561161
xhr: XMLHttpRequest,
11571162
url: string,
11581163
keysListItem: MediaKeySessionContext,
1159-
licenseChallenge: Uint8Array,
1160-
): Promise<{ xhr: XMLHttpRequest; licenseChallenge: Uint8Array }> {
1164+
licenseChallenge: Uint8Array<ArrayBuffer>,
1165+
): Promise<{
1166+
xhr: XMLHttpRequest;
1167+
licenseChallenge: Uint8Array<ArrayBuffer>;
1168+
}> {
11611169
const licenseXhrSetup = this.config.licenseXhrSetup;
11621170

11631171
if (!licenseXhrSetup) {
@@ -1209,7 +1217,7 @@ class EMEController extends Logger implements ComponentAPI {
12091217

12101218
private requestLicense(
12111219
keySessionContext: MediaKeySessionContext,
1212-
licenseChallenge: Uint8Array,
1220+
licenseChallenge: Uint8Array<ArrayBuffer>,
12131221
): Promise<ArrayBuffer> {
12141222
const keyLoadPolicy = this.config.keyLoadPolicy.default;
12151223
return new Promise((resolve, reject) => {
@@ -1305,6 +1313,11 @@ class EMEController extends Logger implements ComponentAPI {
13051313
});
13061314
}
13071315

1316+
private onDestroying() {
1317+
this.unregisterListeners();
1318+
this._clear();
1319+
}
1320+
13081321
private onMediaAttached(
13091322
event: Events.MEDIA_ATTACHED,
13101323
data: MediaAttachedData,
@@ -1318,30 +1331,32 @@ class EMEController extends Logger implements ComponentAPI {
13181331
// keep reference of media
13191332
this.media = media;
13201333

1321-
media.removeEventListener('encrypted', this.onMediaEncrypted);
1322-
media.removeEventListener('waitingforkey', this.onWaitingForKey);
1323-
media.addEventListener('encrypted', this.onMediaEncrypted);
1324-
media.addEventListener('waitingforkey', this.onWaitingForKey);
1334+
addEventListener(media, 'encrypted', this.onMediaEncrypted);
1335+
addEventListener(media, 'waitingforkey', this.onWaitingForKey);
13251336
}
13261337

13271338
private onMediaDetached() {
13281339
const media = this.media;
13291340

13301341
if (media) {
1331-
media.removeEventListener('encrypted', this.onMediaEncrypted);
1332-
media.removeEventListener('waitingforkey', this.onWaitingForKey);
1342+
removeEventListener(media, 'encrypted', this.onMediaEncrypted);
1343+
removeEventListener(media, 'waitingforkey', this.onWaitingForKey);
13331344
this.media = null;
13341345
this.mediaKeys = null;
13351346
}
13361347
}
13371348

1338-
private _clear(media) {
1339-
const mediaKeysList = this.mediaKeySessions;
1349+
private _clear() {
13401350
this._requestLicenseFailureCount = 0;
1341-
this.mediaKeys = null;
1342-
this.setMediaKeysQueue = [];
1343-
this.mediaKeySessions = [];
13441351
this.keyIdToKeySessionPromise = {};
1352+
if (!this.mediaKeys && !this.mediaKeySessions.length) {
1353+
return;
1354+
}
1355+
const media = this.media;
1356+
const mediaKeysList = this.mediaKeySessions.slice();
1357+
this.mediaKeySessions = [];
1358+
this.mediaKeys = null;
1359+
13451360
LevelKey.clearKeyUriToKeyIdMap();
13461361

13471362
// Close all sessions and remove media keys from the video element.
@@ -1363,12 +1378,6 @@ class EMEController extends Logger implements ComponentAPI {
13631378
}),
13641379
),
13651380
)
1366-
.then(() => {
1367-
if (keySessionCount) {
1368-
this.log('finished closing key sessions and clearing media keys');
1369-
mediaKeysList.length = 0;
1370-
}
1371-
})
13721381
.catch((error) => {
13731382
this.log(`Could not close sessions and clear media keys: ${error}`);
13741383
this.hls?.trigger(Events.ERROR, {
@@ -1379,6 +1388,12 @@ class EMEController extends Logger implements ComponentAPI {
13791388
`Could not close sessions and clear media keys: ${error}`,
13801389
),
13811390
});
1391+
})
1392+
1393+
.then(() => {
1394+
if (keySessionCount) {
1395+
this.log('finished closing key sessions and clearing media keys');
1396+
}
13821397
});
13831398
}
13841399

src/utils/event-listener-helper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export function addEventListener(
2-
el: HTMLElement,
2+
el: EventTarget,
33
type: string,
44
listener: EventListenerOrEventListenerObject,
55
) {
@@ -8,7 +8,7 @@ export function addEventListener(
88
}
99

1010
export function removeEventListener(
11-
el: HTMLElement,
11+
el: EventTarget,
1212
type: string,
1313
listener: EventListenerOrEventListenerObject,
1414
) {

src/utils/utf8-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export type Frame = DecodedFrame<ArrayBuffer | string>;
1111
* This library is free. You can redistribute it and/or modify it.
1212
*/
1313

14-
export function strToUtf8array(str: string): Uint8Array {
14+
export function strToUtf8array(str: string) {
1515
return Uint8Array.from(unescape(encodeURIComponent(str)), (c) =>
1616
c.charCodeAt(0),
1717
);

0 commit comments

Comments
 (0)