@@ -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