rx-player 3.27.0-dev.2022032100 → 3.27.0-dev.2022032500

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +9 -11
  4. package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +16 -6
  5. package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +4 -6
  6. package/dist/_esm5.processed/compat/eme/generate_key_request.js +4 -6
  7. package/dist/_esm5.processed/config.d.ts +0 -3
  8. package/dist/_esm5.processed/core/api/public_api.js +2 -2
  9. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +11 -3
  10. package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +1 -1
  11. package/dist/_esm5.processed/core/decrypt/create_session.d.ts +3 -1
  12. package/dist/_esm5.processed/core/decrypt/create_session.js +15 -5
  13. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +94 -1
  14. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +237 -96
  15. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +4 -3
  16. package/dist/_esm5.processed/default_config.d.ts +0 -27
  17. package/dist/_esm5.processed/default_config.js +0 -27
  18. package/dist/rx-player.js +727 -444
  19. package/dist/rx-player.min.js +1 -1
  20. package/package.json +1 -1
  21. package/sonar-project.properties +1 -1
  22. package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +10 -12
  23. package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +15 -8
  24. package/src/compat/eme/generate_key_request.ts +4 -6
  25. package/src/core/api/public_api.ts +2 -2
  26. package/src/core/decrypt/content_decryptor.ts +15 -4
  27. package/src/core/decrypt/create_or_load_session.ts +4 -1
  28. package/src/core/decrypt/create_session.ts +23 -9
  29. package/src/core/decrypt/utils/loaded_sessions_store.ts +254 -102
  30. package/src/core/stream/representation/append_segment_to_buffer.ts +17 -13
  31. package/src/default_config.ts +0 -30
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## v3.27.0-dev.2022032100 (2022-03-21)
3
+ ## v3.27.0-dev.2022032500 (2022-03-25)
4
4
 
5
5
  ### Features
6
6
 
@@ -19,6 +19,7 @@
19
19
  - avoid unnecessary warning logs when loading some initialization segments [#1049]
20
20
  - TypeScript: Add forgotten TypeScript types in the exposed segment and manifest loader APIs [#1057]
21
21
  - DRM: Avoid decryption issues when a license is persisted in a `singleLicensePer` `"init-data"` mode but loaded in a `"content"` mode [#1031, #1042]
22
+ - DRM: Totally avoid the theoretical possibility of leaking MediaKeySessions when a `generateRequest` or `load` call takes multiple seconds [#1093]
22
23
 
23
24
  ### Other improvements
24
25
 
@@ -27,6 +28,7 @@
27
28
  - DASH: Prioritize selectionPriority attribute over a "main" Role when ordering AdaptationSets [#1082]
28
29
  - directfile/Safari: use the `getStartDate` method in `getWallClockTime` when available to obtain true offseted times when playing HLS contents on Safari [#1055]
29
30
  - DRM: Improve DRM Session caches performance when `singleLicensePer` is set to `"content"`
31
+ - DRM: Stop retrying closing MediaKeySessions multiple times when it fails, instead doing it only once when it should work [#1093]
30
32
  - TypeScript: Add IBitrateEstimate, IPositionUpdate and IPlayerState types to the exported types [#1084]
31
33
  - Remove dependency on pinkie's promise ponyfill [#1058, #1090]
32
34
  - tests: add performance tests, to better catch and avoid performance regressions [#1053, #1062]
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.27.0-dev.2022032100
1
+ 3.27.0-dev.2022032500
@@ -56,16 +56,20 @@ var OldWebkitMediaKeySession = /** @class */ (function (_super) {
56
56
  _this._key = keySystem;
57
57
  _this.sessionId = "";
58
58
  _this._closeSession = noop; // Just here to make TypeScript happy
59
- _this.closed = new Promise(function (resolve) {
60
- _this._closeSession = resolve;
61
- });
62
59
  _this.keyStatuses = new Map();
63
60
  _this.expiration = NaN;
64
- _this._onSessionRelatedEvent = function (evt) {
61
+ var onSessionRelatedEvent = function (evt) {
65
62
  _this.trigger(evt.type, evt);
66
63
  };
64
+ _this.closed = new Promise(function (resolve) {
65
+ _this._closeSession = function () {
66
+ ["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
67
+ .forEach(function (evt) { return mediaElement.removeEventListener(evt, onSessionRelatedEvent); });
68
+ resolve();
69
+ };
70
+ });
67
71
  ["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
68
- .forEach(function (evt) { return mediaElement.addEventListener(evt, _this._onSessionRelatedEvent); });
72
+ .forEach(function (evt) { return mediaElement.addEventListener(evt, onSessionRelatedEvent); });
69
73
  return _this;
70
74
  }
71
75
  OldWebkitMediaKeySession.prototype.update = function (license) {
@@ -105,7 +109,6 @@ var OldWebkitMediaKeySession = /** @class */ (function (_super) {
105
109
  OldWebkitMediaKeySession.prototype.close = function () {
106
110
  var _this = this;
107
111
  return new Promise(function (resolve) {
108
- _this._unbindSession();
109
112
  _this._closeSession();
110
113
  resolve();
111
114
  });
@@ -122,11 +125,6 @@ var OldWebkitMediaKeySession = /** @class */ (function (_super) {
122
125
  OldWebkitMediaKeySession.prototype.remove = function () {
123
126
  return Promise.resolve();
124
127
  };
125
- OldWebkitMediaKeySession.prototype._unbindSession = function () {
126
- var _this = this;
127
- ["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
128
- .forEach(function (evt) { return _this._vid.removeEventListener(evt, _this._onSessionRelatedEvent); });
129
- };
130
128
  return OldWebkitMediaKeySession;
131
129
  }(EventEmitter));
132
130
  var OldWebKitCustomMediaKeys = /** @class */ (function () {
@@ -81,9 +81,6 @@ var WebkitMediaKeySession = /** @class */ (function (_super) {
81
81
  });
82
82
  _this.keyStatuses = new Map();
83
83
  _this.expiration = NaN;
84
- _this._onEvent = function (evt) {
85
- _this.trigger(evt.type, evt);
86
- };
87
84
  return _this;
88
85
  }
89
86
  WebkitMediaKeySession.prototype.update = function (license) {
@@ -96,9 +93,19 @@ var WebkitMediaKeySession = /** @class */ (function (_super) {
96
93
  return reject("Unavailable WebKit key session.");
97
94
  }
98
95
  try {
96
+ var uInt8Arraylicense = void 0;
97
+ if (license instanceof ArrayBuffer) {
98
+ uInt8Arraylicense = new Uint8Array(license);
99
+ }
100
+ else if (license instanceof Uint8Array) {
101
+ uInt8Arraylicense = license;
102
+ }
103
+ else {
104
+ uInt8Arraylicense = new Uint8Array(license.buffer);
105
+ }
99
106
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
100
107
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
101
- resolve(_this._nativeSession.update(license));
108
+ resolve(_this._nativeSession.update(uInt8Arraylicense));
102
109
  /* eslint-enable @typescript-eslint/no-unsafe-member-access */
103
110
  }
104
111
  catch (err) {
@@ -171,14 +178,17 @@ var WebkitMediaKeySession = /** @class */ (function (_super) {
171
178
  WebkitMediaKeySession.prototype._listenEvent = function (session) {
172
179
  var _this = this;
173
180
  this._unbindSession(); // If previous session was linked
181
+ var onEvent = function (evt) {
182
+ _this.trigger(evt.type, evt);
183
+ };
174
184
  /* eslint-disable @typescript-eslint/no-unsafe-call */
175
185
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
176
186
  /* eslint-disable @typescript-eslint/no-unsafe-return */
177
187
  ["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
178
- .forEach(function (evt) { return session.addEventListener(evt, _this._onEvent); });
188
+ .forEach(function (evt) { return session.addEventListener(evt, onEvent); });
179
189
  this._unbindSession = function () {
180
190
  ["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
181
- .forEach(function (evt) { return session.removeEventListener(evt, _this._onEvent); });
191
+ .forEach(function (evt) { return session.removeEventListener(evt, onEvent); });
182
192
  };
183
193
  /* eslint-disable @typescript-eslint/no-unsafe-return */
184
194
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
@@ -45,12 +45,10 @@ export declare function patchInitData(initData: Uint8Array): Uint8Array;
45
45
  * Generate a request from session.
46
46
  * @param {MediaKeySession} session - MediaKeySession on which the request will
47
47
  * be done.
48
- * @param {Uint8Array} initData - Initialization data given e.g. by the
49
- * "encrypted" event for the corresponding request.
50
- * @param {string} initDataType - Initialization data type given e.g. by the
51
- * "encrypted" event for the corresponding request.
52
- * @param {string} sessionType - Type of session you want to generate. Consult
53
- * EME Specification for more information on session types.
48
+ * @param {string} initializationDataType - Initialization data type given e.g.
49
+ * by the "encrypted" event for the corresponding request.
50
+ * @param {Uint8Array} initializationData - Initialization data given e.g. by
51
+ * the "encrypted" event for the corresponding request.
54
52
  * @returns {Promise} - Emit when done. Errors if fails.
55
53
  */
56
54
  export default function generateKeyRequest(session: MediaKeySession | ICustomMediaKeySession, initializationDataType: string | undefined, initializationData: Uint8Array): Promise<unknown>;
@@ -114,12 +114,10 @@ export function patchInitData(initData) {
114
114
  * Generate a request from session.
115
115
  * @param {MediaKeySession} session - MediaKeySession on which the request will
116
116
  * be done.
117
- * @param {Uint8Array} initData - Initialization data given e.g. by the
118
- * "encrypted" event for the corresponding request.
119
- * @param {string} initDataType - Initialization data type given e.g. by the
120
- * "encrypted" event for the corresponding request.
121
- * @param {string} sessionType - Type of session you want to generate. Consult
122
- * EME Specification for more information on session types.
117
+ * @param {string} initializationDataType - Initialization data type given e.g.
118
+ * by the "encrypted" event for the corresponding request.
119
+ * @param {Uint8Array} initializationData - Initialization data given e.g. by
120
+ * the "encrypted" event for the corresponding request.
123
121
  * @returns {Promise} - Emit when done. Errors if fails.
124
122
  */
125
123
  export default function generateKeyRequest(session, initializationDataType, initializationData) {
@@ -145,9 +145,6 @@ declare class ConfigHandler {
145
145
  DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0: number;
146
146
  EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS: number;
147
147
  EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION: number;
148
- EME_SESSION_CLOSING_MAX_RETRY: number;
149
- EME_SESSION_CLOSING_INITIAL_DELAY: number;
150
- EME_SESSION_CLOSING_MAX_DELAY: number;
151
148
  EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES: number;
152
149
  FORCED_ENDED_THRESHOLD: number;
153
150
  ADAPTATION_SWITCH_BUFFER_PADDINGS: {
@@ -87,7 +87,7 @@ var Player = /** @class */ (function (_super) {
87
87
  // Workaround to support Firefox autoplay on FF 42.
88
88
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
89
89
  videoElement.preload = "auto";
90
- _this.version = /* PLAYER_VERSION */ "3.27.0-dev.2022032100";
90
+ _this.version = /* PLAYER_VERSION */ "3.27.0-dev.2022032500";
91
91
  _this.log = log;
92
92
  _this.state = "STOPPED";
93
93
  _this.videoElement = videoElement;
@@ -2302,5 +2302,5 @@ var Player = /** @class */ (function (_super) {
2302
2302
  };
2303
2303
  return Player;
2304
2304
  }(EventEmitter));
2305
- Player.version = /* PLAYER_VERSION */ "3.27.0-dev.2022032100";
2305
+ Player.version = /* PLAYER_VERSION */ "3.27.0-dev.2022032500";
2306
2306
  export default Player;
@@ -84,7 +84,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
84
84
  }
85
85
  return to.concat(ar || Array.prototype.slice.call(from));
86
86
  };
87
- import { events, generateKeyRequest, getInitData, } from "../../compat/";
87
+ import { events, getInitData, } from "../../compat/";
88
88
  import config from "../../config";
89
89
  import { EncryptedMediaError, OtherError, } from "../../errors";
90
90
  import log from "../../log";
@@ -318,7 +318,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
318
318
  */
319
319
  ContentDecryptor.prototype._processInitializationData = function (initializationData, mediaKeysData) {
320
320
  return __awaiter(this, void 0, void 0, function () {
321
- var mediaKeySystemAccess, stores, options, firstCreatedSession, keyIds, hexKids, period, createdSessions, periodKeys, _i, createdSessions_1, createdSess, periodKeysArr, _a, periodKeysArr_1, kid, _b, periodKeysArr_2, innerKid, wantedSessionType, _c, EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION, maxSessionCacheSize, sessionRes, sessionInfo, _d, mediaKeySession, sessionType, isSessionPersisted, sub, requestData, error_1;
321
+ var mediaKeySystemAccess, stores, options, firstCreatedSession, keyIds, hexKids, period, createdSessions, periodKeys, _i, createdSessions_1, createdSess, periodKeysArr, _a, periodKeysArr_1, kid, _b, periodKeysArr_2, innerKid, wantedSessionType, _c, EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION, maxSessionCacheSize, sessionRes, sessionInfo, _d, mediaKeySession, sessionType, isSessionPersisted, sub, requestData, error_1, entry, indexInCurrent;
322
322
  var _this = this;
323
323
  return __generator(this, function (_e) {
324
324
  switch (_e.label) {
@@ -486,12 +486,20 @@ var ContentDecryptor = /** @class */ (function (_super) {
486
486
  _e.label = 2;
487
487
  case 2:
488
488
  _e.trys.push([2, 4, , 5]);
489
- return [4 /*yield*/, generateKeyRequest(mediaKeySession, initializationData.type, requestData)];
489
+ return [4 /*yield*/, stores.loadedSessionsStore.generateLicenseRequest(mediaKeySession, initializationData.type, requestData)];
490
490
  case 3:
491
491
  _e.sent();
492
492
  return [3 /*break*/, 5];
493
493
  case 4:
494
494
  error_1 = _e.sent();
495
+ entry = stores.loadedSessionsStore.getEntryForSession(mediaKeySession);
496
+ if (entry === null || entry.closingStatus.type !== "none") {
497
+ indexInCurrent = this._currentSessions.indexOf(sessionInfo);
498
+ if (indexInCurrent >= 0) {
499
+ this._currentSessions.splice(indexInCurrent, 1);
500
+ }
501
+ return [2 /*return*/, Promise.resolve()];
502
+ }
495
503
  throw new EncryptedMediaError("KEY_GENERATE_REQUEST_ERROR", error_1 instanceof Error ? error_1.toString() :
496
504
  "Unknown error");
497
505
  case 5: return [2 /*return*/, Promise.resolve()];
@@ -111,7 +111,7 @@ export default function createOrLoadSession(initializationData, stores, wantedSe
111
111
  if (cancelSignal.cancellationError !== null) {
112
112
  throw cancelSignal.cancellationError; // stop here if cancelled since
113
113
  }
114
- return [4 /*yield*/, createSession(stores, initializationData, wantedSessionType)];
114
+ return [4 /*yield*/, createSession(stores, initializationData, wantedSessionType, cancelSignal)];
115
115
  case 4:
116
116
  evt = _a.sent();
117
117
  return [2 /*return*/, { type: evt.type,
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { ICustomMediaKeySession } from "../../compat";
17
+ import { CancellationSignal } from "../../utils/task_canceller";
17
18
  import { IProcessedProtectionData, IMediaKeySessionStores, MediaKeySessionLoadingType } from "./types";
18
19
  import KeySessionRecord from "./utils/key_session_record";
19
20
  /**
@@ -29,9 +30,10 @@ import KeySessionRecord from "./utils/key_session_record";
29
30
  * @param {Object} stores
30
31
  * @param {Object} initData
31
32
  * @param {string} wantedSessionType
33
+ * @param {Object} cancelSignal
32
34
  * @returns {Promise}
33
35
  */
34
- export default function createSession(stores: IMediaKeySessionStores, initData: IProcessedProtectionData, wantedSessionType: MediaKeySessionType): Promise<ICreateSessionEvent>;
36
+ export default function createSession(stores: IMediaKeySessionStores, initData: IProcessedProtectionData, wantedSessionType: MediaKeySessionType, cancelSignal: CancellationSignal): Promise<ICreateSessionEvent>;
35
37
  export interface INewSessionCreatedEvent {
36
38
  type: MediaKeySessionLoadingType.Created;
37
39
  value: {
@@ -49,7 +49,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
49
49
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
50
  }
51
51
  };
52
- import { loadSession, } from "../../compat";
53
52
  import log from "../../log";
54
53
  import isSessionUsable from "./utils/is_session_usable";
55
54
  /**
@@ -65,9 +64,10 @@ import isSessionUsable from "./utils/is_session_usable";
65
64
  * @param {Object} stores
66
65
  * @param {Object} initData
67
66
  * @param {string} wantedSessionType
67
+ * @param {Object} cancelSignal
68
68
  * @returns {Promise}
69
69
  */
70
- export default function createSession(stores, initData, wantedSessionType) {
70
+ export default function createSession(stores, initData, wantedSessionType, cancelSignal) {
71
71
  var loadedSessionsStore = stores.loadedSessionsStore, persistentSessionsStore = stores.persistentSessionsStore;
72
72
  if (wantedSessionType === "temporary") {
73
73
  return createTemporarySession(loadedSessionsStore, initData);
@@ -77,7 +77,7 @@ export default function createSession(stores, initData, wantedSessionType) {
77
77
  "PersistentSessionsStore not created.");
78
78
  return createTemporarySession(loadedSessionsStore, initData);
79
79
  }
80
- return createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData);
80
+ return createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData, cancelSignal);
81
81
  }
82
82
  /**
83
83
  * Create a new temporary MediaKeySession linked to the given initData and
@@ -98,9 +98,10 @@ function createTemporarySession(loadedSessionsStore, initData) {
98
98
  * @param {Object} loadedSessionsStore
99
99
  * @param {Object} persistentSessionsStore
100
100
  * @param {Object} initData
101
+ * @param {Object} cancelSignal
101
102
  * @returns {Promise}
102
103
  */
103
- function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData) {
104
+ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData, cancelSignal) {
104
105
  return __awaiter(this, void 0, void 0, function () {
105
106
  /**
106
107
  * Helper function to close and restart the current persistent session
@@ -113,6 +114,9 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
113
114
  return __generator(this, function (_a) {
114
115
  switch (_a.label) {
115
116
  case 0:
117
+ if (cancelSignal.cancellationError !== null) {
118
+ throw cancelSignal.cancellationError;
119
+ }
116
120
  log.info("DRM: Removing previous persistent session.");
117
121
  persistentEntry = persistentSessionsStore.get(initData);
118
122
  if (persistentEntry !== null) {
@@ -121,6 +125,9 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
121
125
  return [4 /*yield*/, loadedSessionsStore.closeSession(entry.mediaKeySession)];
122
126
  case 1:
123
127
  _a.sent();
128
+ if (cancelSignal.cancellationError !== null) {
129
+ throw cancelSignal.cancellationError;
130
+ }
124
131
  newEntry = loadedSessionsStore.createSession(initData, "persistent-license");
125
132
  return [2 /*return*/, { type: "created-session" /* Created */,
126
133
  value: newEntry }];
@@ -132,6 +139,9 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
132
139
  return __generator(this, function (_a) {
133
140
  switch (_a.label) {
134
141
  case 0:
142
+ if (cancelSignal.cancellationError !== null) {
143
+ throw cancelSignal.cancellationError;
144
+ }
135
145
  log.info("DRM: Creating persistent MediaKeySession");
136
146
  entry = loadedSessionsStore.createSession(initData, "persistent-license");
137
147
  storedEntry = persistentSessionsStore.getAndReuse(initData);
@@ -142,7 +152,7 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
142
152
  _a.label = 1;
143
153
  case 1:
144
154
  _a.trys.push([1, 3, , 4]);
145
- return [4 /*yield*/, loadSession(entry.mediaKeySession, storedEntry.sessionId)];
155
+ return [4 /*yield*/, loadedSessionsStore.loadPersistentSession(entry.mediaKeySession, storedEntry.sessionId)];
146
156
  case 2:
147
157
  hasLoadedSession = _a.sent();
148
158
  if (!hasLoadedSession) {
@@ -37,7 +37,7 @@ export default class LoadedSessionsStore {
37
37
  constructor(mediaKeys: MediaKeys | ICustomMediaKeys);
38
38
  /**
39
39
  * Create a new MediaKeySession and store it in this store.
40
- * @param {Object} initializationData
40
+ * @param {Object} initData
41
41
  * @param {string} sessionType
42
42
  * @returns {Object}
43
43
  */
@@ -55,6 +55,32 @@ export default class LoadedSessionsStore {
55
55
  * @returns {Object|null}
56
56
  */
57
57
  reuse(initializationData: IProcessedProtectionData): IStoredSessionEntry | null;
58
+ /**
59
+ * Get `LoadedSessionsStore`'s entry for a given MediaKeySession.
60
+ * Returns `null` if the given MediaKeySession is not stored in the
61
+ * `LoadedSessionsStore`.
62
+ * @param {MediaKeySession} mediaKeySession
63
+ * @returns {Object|null}
64
+ */
65
+ getEntryForSession(mediaKeySession: MediaKeySession | ICustomMediaKeySession): IStoredSessionEntry | null;
66
+ /**
67
+ * Generate a license request on the given MediaKeySession, while indicating
68
+ * to the LoadedSessionsStore that a license-request is pending so
69
+ * session-closing orders are properly scheduled after it is done.
70
+ * @param {Object} mediaKeySession
71
+ * @param {string} initializationDataType - Initialization data type given
72
+ * e.g. by the "encrypted" event for the corresponding request.
73
+ * @param {Uint8Array} initializationData - Initialization data given e.g. by
74
+ * the "encrypted" event for the corresponding request.
75
+ * @returns {Promise}
76
+ */
77
+ generateLicenseRequest(mediaKeySession: MediaKeySession | ICustomMediaKeySession, initializationDataType: string | undefined, initializationData: Uint8Array): Promise<unknown>;
78
+ /**
79
+ * @param {Object} mediaKeySession
80
+ * @param {string} sessionId
81
+ * @returns {Promise}
82
+ */
83
+ loadPersistentSession(mediaKeySession: MediaKeySession | ICustomMediaKeySession, sessionId: string): Promise<boolean>;
58
84
  /**
59
85
  * Close a MediaKeySession and remove its related stored information from the
60
86
  * `LoadedSessionsStore`.
@@ -80,7 +106,23 @@ export default class LoadedSessionsStore {
80
106
  * @returns {Promise}
81
107
  */
82
108
  closeAllSessions(): Promise<void>;
109
+ /**
110
+ * Get the index of a stored MediaKeySession entry based on its
111
+ * `KeySessionRecord`.
112
+ * Returns -1 if not found.
113
+ * @param {Object} record
114
+ * @returns {number}
115
+ */
83
116
  private getIndex;
117
+ /**
118
+ * Prepare the closure of a `MediaKeySession` stored as an entry of the
119
+ * `LoadedSessionsStore`.
120
+ * Allows to postpone the closure action if another MediaKeySession action
121
+ * is already pending.
122
+ * @param {Object} entry
123
+ * @returns {Promise.<boolean>}
124
+ */
125
+ private _closeEntry;
84
126
  }
85
127
  /** Information linked to a `MediaKeySession` created by the `LoadedSessionsStore`. */
86
128
  export interface IStoredSessionEntry {
@@ -105,4 +147,55 @@ export interface IStoredSessionEntry {
105
147
  * which the MediaKeySession was created.
106
148
  */
107
149
  sessionType: MediaKeySessionType;
150
+ /**
151
+ * Set to `true` while a `generateRequest` call is pending.
152
+ * This information might be useful as it is one of the operation we have to
153
+ * wait for before closing a MediaKeySession.
154
+ */
155
+ isGeneratingRequest: boolean;
156
+ /**
157
+ * Set to `true` while a `load` call is pending.
158
+ * This information might be useful as it is one of the operation we have to
159
+ * wait for before closing a MediaKeySession.
160
+ */
161
+ isLoadingPersistentSession: boolean;
162
+ /**
163
+ * The status of a potential `MediaKeySession`'s close request.
164
+ * Closing a MediaKeySession could be made complex as it normally cannot
165
+ * happen until `generateRequest` or `load` has been called.
166
+ *
167
+ * To avoid problems while still staying compatible to the most devices
168
+ * possible - which may have strange implementation of the specification -
169
+ * we're adding the `closingStatus` property allowing to perform multiple
170
+ * type of interaction while a close operation is either pending or is
171
+ * awaited.
172
+ */
173
+ closingStatus:
174
+ /** Status when the MediaKeySession is currently being closed. */
175
+ {
176
+ type: "pending";
177
+ } |
178
+ /** Status when the MediaKeySession has been closed. */
179
+ {
180
+ type: "done";
181
+ } |
182
+ /** Status when the MediaKeySession failed to close. */
183
+ {
184
+ type: "failed";
185
+ } |
186
+ /**
187
+ * Status when a close order has been received for this MediaKeySession
188
+ * while some sensitive operation (examples are `generateRequest` and `load`
189
+ * calls).
190
+ * The `LoadedSessionsStore` should call `start` once it has finished those
191
+ * operations.
192
+ */
193
+ {
194
+ type: "awaiting";
195
+ start: () => void;
196
+ } |
197
+ /** Status when the MediaKeySession failed to close. */
198
+ {
199
+ type: "none";
200
+ };
108
201
  }