diff --git a/lib/media/drm_engine.js b/lib/media/drm_engine.js index b760ab3099..024383c515 100644 --- a/lib/media/drm_engine.js +++ b/lib/media/drm_engine.js @@ -501,6 +501,9 @@ shaka.media.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 058e9c501a..85845a30f6 100644 --- a/lib/media/preload_manager.js +++ b/lib/media/preload_manager.js @@ -28,6 +28,7 @@ goog.require('shaka.util.ConfigUtils'); goog.require('shaka.util.FakeEvent'); goog.require('shaka.util.FakeEventTarget'); goog.require('shaka.util.ObjectUtils'); +goog.require('shaka.util.Platform'); goog.require('shaka.util.PlayerConfiguration'); /** @@ -395,8 +396,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_(); @@ -404,8 +407,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) { @@ -545,13 +550,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'); @@ -578,6 +583,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 1f7bceaffb..737e5462db 100644 --- a/lib/player.js +++ b/lib/player.js @@ -1766,6 +1766,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 () => {