diff --git a/lib/drm/drm_engine.js b/lib/drm/drm_engine.js index 5271ab91dc..19b680f772 100644 --- a/lib/drm/drm_engine.js +++ b/lib/drm/drm_engine.js @@ -550,6 +550,9 @@ shaka.drm.DrmEngine = class { * @return {!Promise} */ async attach(video) { + if (this.video_ === video) { + return; + } if (!this.mediaKeys_) { // Unencrypted, or so we think. We listen for encrypted events in order // to warn when the stream is encrypted, even though the manifest does diff --git a/lib/media/preload_manager.js b/lib/media/preload_manager.js index 308b3ff219..04929afc16 100644 --- a/lib/media/preload_manager.js +++ b/lib/media/preload_manager.js @@ -23,6 +23,7 @@ goog.require('shaka.util.FakeEvent'); goog.require('shaka.util.FakeEventTarget'); goog.require('shaka.util.IDestroyable'); goog.require('shaka.util.ObjectUtils'); +goog.require('shaka.util.Platform'); goog.require('shaka.util.PlayerConfiguration'); goog.require('shaka.util.PublicPromise'); goog.require('shaka.util.Stats'); @@ -396,8 +397,10 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget { await this.parseManifestInner_(); this.throwIfDestroyed_(); - await this.initializeDrmInner_(); - this.throwIfDestroyed_(); + if (!shaka.util.Platform.isMediaKeysPolyfilled('webkit')) { + await this.initializeDrm(); + this.throwIfDestroyed_(); + } await this.chooseInitialVariantAndPrefetchInner_(); this.throwIfDestroyed_(); @@ -405,8 +408,10 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget { // We don't need the drm keys to load completely for the initial variant // to be chosen, but we won't mark the load as a success until it has // been loaded. So wait for it here, not inside initializeDrmInner_. - await this.drmEngine_.waitForActiveRequests(); - this.throwIfDestroyed_(); + if (this.drmEngine_) { + await this.drmEngine_.waitForActiveRequests(); + this.throwIfDestroyed_(); + } this.successPromise_.resolve(); } catch (error) { @@ -559,13 +564,13 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget { /** * Initializes the DRM engine. - * + * @param {?HTMLMediaElement=} media * @return {!Promise} - * @private */ - async initializeDrmInner_() { - goog.asserts.assert( - this.manifest_, 'The manifest should already be parsed.'); + async initializeDrm(media) { + if (!this.manifest_ || this.drmEngine_) { + return; + } this.makeStateChangeEvent_('drm-engine'); @@ -592,6 +597,10 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget { playableVariants, this.manifest_.offlineSessionIds); this.throwIfDestroyed_(); + if (media) { + await this.drmEngine_.attach(media); + this.throwIfDestroyed_(); + } // Now that we have drm information, filter the manifest (again) so that // we can ensure we only use variants with the selected key system. diff --git a/lib/player.js b/lib/player.js index a1348e3557..ece51312aa 100644 --- a/lib/player.js +++ b/lib/player.js @@ -1822,6 +1822,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget { this.configure('manifest.disableVideo', true); } + // Init DRM engine if it's not created yet (happens on polyfilled EME). + if (!preloadManager.getDrmEngine()) { + await mutexWrapOperation(async () => { + await preloadManager.initializeDrm(this.video_); + }, 'drmEngine_.init'); + } + // Get drm engine from preloader, then finalize it. this.drmEngine_ = preloadManager.receiveDrmEngine(); await mutexWrapOperation(async () => {