Skip to content

Commit a1e2f0a

Browse files
authored
fix(preload): Wait for drm keys when preloading (#7698)
Closes #7520
1 parent d00ea51 commit a1e2f0a

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

lib/media/drm_engine.js

+23
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ goog.provide('shaka.media.DrmEngine');
99
goog.require('goog.asserts');
1010
goog.require('shaka.log');
1111
goog.require('shaka.net.NetworkingEngine');
12+
goog.require('shaka.util.ArrayUtils');
1213
goog.require('shaka.util.BufferUtils');
1314
goog.require('shaka.util.Destroyer');
1415
goog.require('shaka.util.DrmUtils');
@@ -67,12 +68,18 @@ shaka.media.DrmEngine = class {
6768
*/
6869
this.activeSessions_ = new Map();
6970

71+
/** @private {!Array.<!shaka.net.NetworkingEngine.PendingRequest>} */
72+
this.activeRequests_ = [];
73+
7074
/**
7175
* @private {!Map<string,
7276
* {initData: ?Uint8Array, initDataType: ?string}>}
7377
*/
7478
this.storedPersistentSessions_ = new Map();
7579

80+
/** @private {boolean} */
81+
this.hasInitData_ = false;
82+
7683
/** @private {!shaka.util.PublicPromise} */
7784
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
7885

@@ -706,6 +713,7 @@ shaka.media.DrmEngine = class {
706713

707714
// Reset the promise for the next sessions to come if key needs aren't
708715
// satisfied with persistent sessions
716+
this.hasInitData_ = false;
709717
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
710718
this.allSessionsLoaded_.catch(() => {});
711719
}
@@ -767,11 +775,16 @@ shaka.media.DrmEngine = class {
767775
}
768776
}
769777

778+
// Mark that there is init data, so that the preloader will know to wait
779+
// for sessions to be loaded.
780+
this.hasInitData_ = true;
781+
770782
// If there are pre-existing sessions that have all been loaded
771783
// then reset the allSessionsLoaded_ promise, which can now be
772784
// used to wait for new sesssions to be loaded
773785
if (this.activeSessions_.size > 0 && this.areAllSessionsLoaded_()) {
774786
this.allSessionsLoaded_.resolve();
787+
this.hasInitData_ = false;
775788
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
776789
this.allSessionsLoaded_.catch(() => {});
777790
}
@@ -1387,6 +1400,14 @@ shaka.media.DrmEngine = class {
13871400
this.video_.paused && !this.initialRequestsSent_);
13881401
}
13891402

1403+
/** @return {!Promise} */
1404+
async waitForActiveRequests() {
1405+
if (this.hasInitData_) {
1406+
await this.allSessionsLoaded_;
1407+
await Promise.all(this.activeRequests_.map((req) => req.promise));
1408+
}
1409+
}
1410+
13901411
/**
13911412
* Sends a license request.
13921413
* @param {!MediaKeyMessageEvent} event
@@ -1446,7 +1467,9 @@ shaka.media.DrmEngine = class {
14461467
try {
14471468
const req = this.playerInterface_.netEngine.request(
14481469
requestType, request, {isPreload: this.isPreload_()});
1470+
this.activeRequests_.push(req);
14491471
response = await req.promise;
1472+
shaka.util.ArrayUtils.remove(this.activeRequests_, req);
14501473
} catch (error) {
14511474
if (this.destroyer_.destroyed()) {
14521475
return;

lib/media/preload_manager.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,13 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
398398
await this.initializeDrmInner_();
399399
this.throwIfDestroyed_();
400400

401-
await this.chooseInitialVariantInner_();
401+
await this.chooseInitialVariantAndPrefetchInner_();
402+
this.throwIfDestroyed_();
403+
404+
// We don't need the drm keys to load completely for the initial variant
405+
// to be chosen, but we won't mark the load as a success until it has
406+
// been loaded. So wait for it here, not inside initializeDrmInner_.
407+
await this.drmEngine_.waitForActiveRequests();
402408
this.throwIfDestroyed_();
403409

404410
this.successPromise_.resolve();
@@ -610,12 +616,12 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
610616

611617
/**
612618
* Performs a final filtering of the manifest, and chooses the initial
613-
* variant.
619+
* variant. Also prefetches segments.
614620
*
615621
* @return {!Promise}
616622
* @private
617623
*/
618-
async chooseInitialVariantInner_() {
624+
async chooseInitialVariantAndPrefetchInner_() {
619625
goog.asserts.assert(
620626
this.manifest_, 'The manifest should already be parsed.');
621627

test/test/util/fake_drm_engine.js

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ shaka.test.FakeDrmEngine = class {
4646
this.offlineSessions_.push('session-' + num);
4747
});
4848

49+
/** @type {!jasmine.Spy} */
50+
this.waitForActiveRequests = jasmine.createSpy('waitForActiveRequests');
51+
this.waitForActiveRequests.and.returnValue(Promise.resolve());
52+
4953
/** @type {!jasmine.Spy} */
5054
this.getExpiration = jasmine.createSpy('getExpiration');
5155
this.getExpiration.and.returnValue(Infinity);

0 commit comments

Comments
 (0)