Skip to content

Commit 42ccde4

Browse files
author
Rob Walch
committed
[WIP] Fix EME async errors
1 parent aa2a0df commit 42ccde4

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

src/controller/eme-controller.ts

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,16 @@ class EMEController extends EventHandler {
8383
private _widevineLicenseUrl?: string;
8484
private _licenseXhrSetup?: (xhr: XMLHttpRequest, url: string) => void;
8585
private _emeEnabled: boolean;
86-
private _requestMediaKeySystemAccess: MediaKeyFunc | null
86+
private _requestMediaKeySystemAccess: MediaKeyFunc | null;
8787

8888
private _config: EMEControllerConfig;
8989
private _mediaKeysList: MediaKeysListItem[] = [];
9090
private _media: HTMLMediaElement | null = null;
9191
private _hasSetMediaKeys: boolean = false;
9292
private _requestLicenseFailureCount: number = 0;
9393

94+
private mediaKeysPromise: Promise<MediaKeys> | null = null;
95+
9496
/**
9597
* @constructs
9698
* @param {Hls} hls Our Hls.js instance
@@ -143,13 +145,14 @@ class EMEController extends EventHandler {
143145
logger.log('Requesting encrypted media key-system access');
144146

145147
// expecting interface like window.navigator.requestMediaKeySystemAccess
146-
this.requestMediaKeySystemAccess(keySystem, mediaKeySystemConfigs)
147-
.then((mediaKeySystemAccess) => {
148-
this._onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess);
149-
})
150-
.catch((err) => {
151-
logger.error(`Failed to obtain key-system "${keySystem}" access:`, err);
152-
});
148+
const keySystemAccessPromise = this.requestMediaKeySystemAccess(keySystem, mediaKeySystemConfigs);
149+
150+
this.mediaKeysPromise = keySystemAccessPromise.then((mediaKeySystemAccess) =>
151+
this._onMediaKeySystemAccessObtained(keySystem, mediaKeySystemAccess));
152+
153+
keySystemAccessPromise.catch((err) => {
154+
logger.error(`Failed to obtain key-system "${keySystem}" access:`, err);
155+
});
153156
}
154157

155158
get requestMediaKeySystemAccess () {
@@ -166,7 +169,7 @@ class EMEController extends EventHandler {
166169
* @param {string} keySystem
167170
* @param {MediaKeySystemAccess} mediaKeySystemAccess https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemAccess
168171
*/
169-
private _onMediaKeySystemAccessObtained (keySystem: KeySystems, mediaKeySystemAccess: MediaKeySystemAccess) {
172+
private _onMediaKeySystemAccessObtained (keySystem: KeySystems, mediaKeySystemAccess: MediaKeySystemAccess): Promise<MediaKeys> {
170173
logger.log(`Access for key-system "${keySystem}" obtained`);
171174

172175
const mediaKeysListItem: MediaKeysListItem = {
@@ -177,17 +180,22 @@ class EMEController extends EventHandler {
177180

178181
this._mediaKeysList.push(mediaKeysListItem);
179182

180-
mediaKeySystemAccess.createMediaKeys()
183+
const mediaKeysPromise = mediaKeySystemAccess.createMediaKeys()
181184
.then((mediaKeys) => {
182185
mediaKeysListItem.mediaKeys = mediaKeys;
183186

184187
logger.log(`Media-keys created for key-system "${keySystem}"`);
185188

186189
this._onMediaKeysCreated();
187-
})
188-
.catch((err) => {
189-
logger.error('Failed to create media-keys:', err);
190+
191+
return mediaKeys;
190192
});
193+
194+
mediaKeysPromise.catch((err) => {
195+
logger.error('Failed to create media-keys:', err);
196+
});
197+
198+
return mediaKeysPromise;
191199
}
192200

193201
/**
@@ -235,8 +243,7 @@ class EMEController extends EventHandler {
235243

236244
/**
237245
* @private
238-
* @param {string} initDataType
239-
* @param {ArrayBuffer|null} initData
246+
* @param e {MediaEncryptedEvent}
240247
*/
241248
private _onMediaEncrypted = (e: MediaEncryptedEvent) => {
242249
logger.log(`Media is encrypted using "${e.initDataType}" init data type`);
@@ -254,10 +261,8 @@ class EMEController extends EventHandler {
254261
}
255262

256263
if (!this._hasSetMediaKeys) {
257-
// FIXME: see if we can/want/need-to really to deal with several potential key-sessions?
258-
const keysListItem = this._mediaKeysList[0];
259-
if (!keysListItem || !keysListItem.mediaKeys) {
260-
logger.error('Fatal: Media is encrypted but no CDM access or no keys have been obtained yet');
264+
if (!this.mediaKeysPromise) {
265+
logger.error('Fatal: Media is encrypted but no CDM access or no keys have been requested');
261266
this.hls.trigger(Event.ERROR, {
262267
type: ErrorTypes.KEY_SYSTEM_ERROR,
263268
details: ErrorDetails.KEY_SYSTEM_NO_KEYS,
@@ -266,10 +271,35 @@ class EMEController extends EventHandler {
266271
return;
267272
}
268273

269-
logger.log('Setting keys for encrypted media');
270-
271-
this._media.setMediaKeys(keysListItem.mediaKeys);
272-
this._hasSetMediaKeys = true;
274+
// FIXME: see if we can/want/need-to really to deal with several potential key-sessions?
275+
// const keysListItem = this._mediaKeysList[0];
276+
// if (!keysListItem || !keysListItem.mediaKeys) {
277+
// logger.error('Fatal: Media is encrypted but no CDM access or no keys have been obtained yet' +
278+
// `(keysListItem: ${keysListItem}, mediaKeysList count (${this._mediaKeysList.length})`);
279+
// this.hls.trigger(Event.ERROR, {
280+
// type: ErrorTypes.KEY_SYSTEM_ERROR,
281+
// details: ErrorDetails.KEY_SYSTEM_NO_KEYS,
282+
// fatal: true
283+
// });
284+
// return;
285+
// }
286+
287+
this.mediaKeysPromise.then((mediaKeys) => {
288+
if (!this._media) {
289+
return;
290+
}
291+
logger.log('Setting keys for encrypted media');
292+
this._media.setMediaKeys(mediaKeys);
293+
this._hasSetMediaKeys = true;
294+
}).catch((error) => {
295+
logger.error(`Fatal: Media is encrypted but CDM access failed with error ${error.message}`);
296+
this.hls.trigger(Event.ERROR, {
297+
type: ErrorTypes.KEY_SYSTEM_ERROR,
298+
details: ErrorDetails.KEY_SYSTEM_NO_KEYS,
299+
fatal: true,
300+
error
301+
});
302+
});
273303
}
274304
}
275305

0 commit comments

Comments
 (0)