Skip to content

Commit c2242dc

Browse files
theodabavelad
authored andcommitted
fix(preload): Wait for drm keys when preloading (#7698)
Closes #7520
1 parent 755e9d2 commit c2242dc

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
}
@@ -1381,6 +1394,14 @@ shaka.media.DrmEngine = class {
13811394
this.video_.paused && !this.initialRequestsSent_);
13821395
}
13831396

1397+
/** @return {!Promise} */
1398+
async waitForActiveRequests() {
1399+
if (this.hasInitData_) {
1400+
await this.allSessionsLoaded_;
1401+
await Promise.all(this.activeRequests_.map((req) => req.promise));
1402+
}
1403+
}
1404+
13841405
/**
13851406
* Sends a license request.
13861407
* @param {!MediaKeyMessageEvent} event
@@ -1440,7 +1461,9 @@ shaka.media.DrmEngine = class {
14401461
try {
14411462
const req = this.playerInterface_.netEngine.request(
14421463
requestType, request, {isPreload: this.isPreload_()});
1464+
this.activeRequests_.push(req);
14431465
response = await req.promise;
1466+
shaka.util.ArrayUtils.remove(this.activeRequests_, req);
14441467
} catch (error) {
14451468
if (this.destroyer_.destroyed()) {
14461469
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)