rx-player 4.3.1-dev.2025041002 → 4.4.0-dev.2025041400

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 (77) hide show
  1. package/CHANGELOG.md +10 -5
  2. package/VERSION +1 -1
  3. package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
  4. package/dist/commonjs/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
  5. package/dist/commonjs/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
  6. package/dist/commonjs/__GENERATED_CODE/embedded_worker.js +1 -1
  7. package/dist/commonjs/errors/encrypted_media_error.d.ts +17 -2
  8. package/dist/commonjs/errors/encrypted_media_error.d.ts.map +1 -1
  9. package/dist/commonjs/errors/encrypted_media_error.js +5 -3
  10. package/dist/commonjs/main_thread/api/public_api.js +2 -2
  11. package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  12. package/dist/commonjs/main_thread/decrypt/content_decryptor.js +7 -3
  13. package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts.map +1 -1
  14. package/dist/commonjs/main_thread/decrypt/find_key_system.js +5 -1
  15. package/dist/commonjs/main_thread/decrypt/get_media_keys.js +5 -1
  16. package/dist/commonjs/main_thread/decrypt/session_events_listener.d.ts +4 -3
  17. package/dist/commonjs/main_thread/decrypt/session_events_listener.d.ts.map +1 -1
  18. package/dist/commonjs/main_thread/decrypt/session_events_listener.js +37 -12
  19. package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts +9 -3
  20. package/dist/commonjs/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
  21. package/dist/commonjs/main_thread/decrypt/set_server_certificate.js +19 -5
  22. package/dist/commonjs/main_thread/decrypt/utils/check_key_statuses.d.ts +4 -3
  23. package/dist/commonjs/main_thread/decrypt/utils/check_key_statuses.d.ts.map +1 -1
  24. package/dist/commonjs/main_thread/decrypt/utils/check_key_statuses.js +24 -7
  25. package/dist/commonjs/main_thread/decrypt/utils/media_keys_attacher.js +5 -1
  26. package/dist/commonjs/main_thread/init/multi_thread_content_initializer.d.ts.map +1 -1
  27. package/dist/commonjs/main_thread/init/multi_thread_content_initializer.js +13 -10
  28. package/dist/commonjs/main_thread/init/utils/initialize_content_decryption.d.ts.map +1 -1
  29. package/dist/commonjs/main_thread/init/utils/initialize_content_decryption.js +5 -1
  30. package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.d.ts.map +1 -1
  31. package/dist/es2017/__GENERATED_CODE/embedded_dash_wasm.js +1 -1
  32. package/dist/es2017/__GENERATED_CODE/embedded_worker.d.ts.map +1 -1
  33. package/dist/es2017/__GENERATED_CODE/embedded_worker.js +1 -1
  34. package/dist/es2017/errors/encrypted_media_error.d.ts +17 -2
  35. package/dist/es2017/errors/encrypted_media_error.d.ts.map +1 -1
  36. package/dist/es2017/errors/encrypted_media_error.js +5 -3
  37. package/dist/es2017/main_thread/api/public_api.js +2 -2
  38. package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  39. package/dist/es2017/main_thread/decrypt/content_decryptor.js +7 -3
  40. package/dist/es2017/main_thread/decrypt/find_key_system.d.ts.map +1 -1
  41. package/dist/es2017/main_thread/decrypt/find_key_system.js +5 -1
  42. package/dist/es2017/main_thread/decrypt/get_media_keys.js +5 -1
  43. package/dist/es2017/main_thread/decrypt/session_events_listener.d.ts +4 -3
  44. package/dist/es2017/main_thread/decrypt/session_events_listener.d.ts.map +1 -1
  45. package/dist/es2017/main_thread/decrypt/session_events_listener.js +35 -12
  46. package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts +9 -3
  47. package/dist/es2017/main_thread/decrypt/set_server_certificate.d.ts.map +1 -1
  48. package/dist/es2017/main_thread/decrypt/set_server_certificate.js +19 -5
  49. package/dist/es2017/main_thread/decrypt/utils/check_key_statuses.d.ts +4 -3
  50. package/dist/es2017/main_thread/decrypt/utils/check_key_statuses.d.ts.map +1 -1
  51. package/dist/es2017/main_thread/decrypt/utils/check_key_statuses.js +24 -7
  52. package/dist/es2017/main_thread/decrypt/utils/media_keys_attacher.js +5 -1
  53. package/dist/es2017/main_thread/init/multi_thread_content_initializer.d.ts.map +1 -1
  54. package/dist/es2017/main_thread/init/multi_thread_content_initializer.js +13 -10
  55. package/dist/es2017/main_thread/init/utils/initialize_content_decryption.d.ts.map +1 -1
  56. package/dist/es2017/main_thread/init/utils/initialize_content_decryption.js +5 -1
  57. package/dist/mpd-parser.wasm +0 -0
  58. package/dist/rx-player.js +120 -35
  59. package/dist/rx-player.min.js +3 -3
  60. package/dist/worker.js +1 -1
  61. package/package.json +1 -1
  62. package/src/__GENERATED_CODE/embedded_dash_wasm.ts +1 -1
  63. package/src/__GENERATED_CODE/embedded_worker.ts +1 -1
  64. package/src/errors/__tests__/encrypted_media_error.test.ts +16 -3
  65. package/src/errors/__tests__/is_known_error.test.ts +9 -1
  66. package/src/errors/encrypted_media_error.ts +41 -9
  67. package/src/main_thread/api/public_api.ts +2 -2
  68. package/src/main_thread/decrypt/content_decryptor.ts +11 -2
  69. package/src/main_thread/decrypt/find_key_system.ts +5 -0
  70. package/src/main_thread/decrypt/get_media_keys.ts +5 -1
  71. package/src/main_thread/decrypt/session_events_listener.ts +49 -10
  72. package/src/main_thread/decrypt/set_server_certificate.ts +27 -3
  73. package/src/main_thread/decrypt/utils/check_key_statuses.ts +31 -8
  74. package/src/main_thread/decrypt/utils/media_keys_attacher.ts +5 -0
  75. package/src/main_thread/init/multi_thread_content_initializer.ts +13 -8
  76. package/src/main_thread/init/utils/initialize_content_decryption.ts +5 -1
  77. package/.vscode/settings.json +0 -1
@@ -4,13 +4,21 @@ import EncryptedMediaError from "../encrypted_media_error";
4
4
  describe("errors - EncryptedMediaError", () => {
5
5
  it("should format an EncryptedMediaError", () => {
6
6
  const reason = "test";
7
- const encryptedMediaError = new EncryptedMediaError("KEY_LOAD_TIMEOUT", reason);
7
+ const encryptedMediaError = new EncryptedMediaError(
8
+ "MEDIA_IS_ENCRYPTED_ERROR",
9
+ reason,
10
+ {
11
+ keyStatuses: undefined,
12
+ keySystemConfiguration: undefined,
13
+ keySystem: undefined,
14
+ },
15
+ );
8
16
  expect(encryptedMediaError).toBeInstanceOf(Error);
9
17
  expect(encryptedMediaError.name).toBe("EncryptedMediaError");
10
18
  expect(encryptedMediaError.type).toBe("ENCRYPTED_MEDIA_ERROR");
11
- expect(encryptedMediaError.code).toBe("KEY_LOAD_TIMEOUT");
19
+ expect(encryptedMediaError.code).toBe("MEDIA_IS_ENCRYPTED_ERROR");
12
20
  expect(encryptedMediaError.fatal).toBe(false);
13
- expect(encryptedMediaError.message).toBe("KEY_LOAD_TIMEOUT: test");
21
+ expect(encryptedMediaError.message).toBe("MEDIA_IS_ENCRYPTED_ERROR: test");
14
22
  });
15
23
 
16
24
  it("should be able to set it as fatal", () => {
@@ -18,6 +26,11 @@ describe("errors - EncryptedMediaError", () => {
18
26
  const encryptedMediaError = new EncryptedMediaError(
19
27
  "INCOMPATIBLE_KEYSYSTEMS",
20
28
  reason,
29
+ {
30
+ keyStatuses: undefined,
31
+ keySystemConfiguration: undefined,
32
+ keySystem: undefined,
33
+ },
21
34
  );
22
35
  encryptedMediaError.fatal = true;
23
36
  expect(encryptedMediaError).toBeInstanceOf(Error);
@@ -33,7 +33,15 @@ describe("Errors - isKnownError", () => {
33
33
  });
34
34
 
35
35
  it("should return true for an EncryptedMediaError", () => {
36
- const encryptedMediaError = new EncryptedMediaError("KEY_UPDATE_ERROR", "toto");
36
+ const encryptedMediaError = new EncryptedMediaError(
37
+ "INCOMPATIBLE_KEYSYSTEMS",
38
+ "toto",
39
+ {
40
+ keyStatuses: undefined,
41
+ keySystemConfiguration: undefined,
42
+ keySystem: undefined,
43
+ },
44
+ );
37
45
  expect(isKnownError(encryptedMediaError)).toBe(true);
38
46
  });
39
47
  });
@@ -29,7 +29,9 @@ export default class EncryptedMediaError extends Error {
29
29
  public readonly name: "EncryptedMediaError";
30
30
  public readonly type: "ENCRYPTED_MEDIA_ERROR";
31
31
  public readonly code: IEncryptedMediaErrorCode;
32
- public readonly keyStatuses?: IEncryptedMediaErrorKeyStatusObject[];
32
+ public readonly keyStatuses: IEncryptedMediaErrorKeyStatusObject[] | undefined;
33
+ public readonly keySystemConfiguration: MediaKeySystemConfiguration | undefined;
34
+ public readonly keySystem: string | undefined;
33
35
  public fatal: boolean;
34
36
  private _originalMessage: string;
35
37
 
@@ -40,18 +42,44 @@ export default class EncryptedMediaError extends Error {
40
42
  constructor(
41
43
  code: "KEY_STATUS_CHANGE_ERROR",
42
44
  reason: string,
43
- supplementaryInfos: { keyStatuses: IEncryptedMediaErrorKeyStatusObject[] },
45
+ supplementaryInfos: {
46
+ keyStatuses: IEncryptedMediaErrorKeyStatusObject[];
47
+ keySystemConfiguration: MediaKeySystemConfiguration;
48
+ keySystem: string;
49
+ },
44
50
  );
45
51
  constructor(
46
- code: Omit<IEncryptedMediaErrorCode, "KEY_STATUS_CHANGE_ERROR">,
52
+ code: Omit<
53
+ IEncryptedMediaErrorCode,
54
+ | "KEY_STATUS_CHANGE_ERROR"
55
+ | "INCOMPATIBLE_KEYSYSTEMS"
56
+ | "INVALID_KEY_SYSTEM"
57
+ | "MEDIA_IS_ENCRYPTED_ERROR"
58
+ >,
47
59
  reason: string,
60
+ supplementaryInfos: {
61
+ keyStatuses: undefined;
62
+ keySystemConfiguration: MediaKeySystemConfiguration;
63
+ keySystem: string;
64
+ },
65
+ );
66
+ constructor(
67
+ code: "INCOMPATIBLE_KEYSYSTEMS" | "INVALID_KEY_SYSTEM" | "MEDIA_IS_ENCRYPTED_ERROR",
68
+ reason: string,
69
+ supplementaryInfos: {
70
+ keyStatuses: undefined;
71
+ keySystemConfiguration: undefined;
72
+ keySystem: undefined;
73
+ },
48
74
  );
49
75
  constructor(
50
76
  code: IEncryptedMediaErrorCode,
51
77
  reason: string,
52
- supplementaryInfos?:
53
- | { keyStatuses?: IEncryptedMediaErrorKeyStatusObject[] | undefined }
54
- | undefined,
78
+ supplementaryInfos: {
79
+ keyStatuses: IEncryptedMediaErrorKeyStatusObject[] | undefined;
80
+ keySystemConfiguration: MediaKeySystemConfiguration | undefined;
81
+ keySystem: string | undefined;
82
+ },
55
83
  ) {
56
84
  super(errorMessage(code, reason));
57
85
  // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
@@ -64,9 +92,9 @@ export default class EncryptedMediaError extends Error {
64
92
  this._originalMessage = reason;
65
93
  this.fatal = false;
66
94
 
67
- if (typeof supplementaryInfos?.keyStatuses === "string") {
68
- this.keyStatuses = supplementaryInfos.keyStatuses;
69
- }
95
+ this.keyStatuses = supplementaryInfos.keyStatuses;
96
+ this.keySystemConfiguration = supplementaryInfos.keySystemConfiguration;
97
+ this.keySystem = supplementaryInfos.keySystem;
70
98
  }
71
99
 
72
100
  /**
@@ -81,6 +109,8 @@ export default class EncryptedMediaError extends Error {
81
109
  code: this.code,
82
110
  reason: this._originalMessage,
83
111
  keyStatuses: this.keyStatuses,
112
+ keySystemConfiguration: this.keySystemConfiguration,
113
+ keySystem: this.keySystem,
84
114
  };
85
115
  }
86
116
  }
@@ -95,4 +125,6 @@ export interface ISerializedEncryptedMediaError {
95
125
  keyId: ArrayBuffer;
96
126
  }>
97
127
  | undefined;
128
+ keySystemConfiguration: MediaKeySystemConfiguration | undefined;
129
+ keySystem: string | undefined;
98
130
  }
@@ -408,7 +408,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
408
408
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
409
409
  videoElement.preload = "auto";
410
410
 
411
- this.version = /* PLAYER_VERSION */ "4.3.1-dev.2025041002";
411
+ this.version = /* PLAYER_VERSION */ "4.4.0-dev.2025041400";
412
412
  this.log = log;
413
413
  this.state = "STOPPED";
414
414
  this.videoElement = videoElement;
@@ -3415,7 +3415,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
3415
3415
  }
3416
3416
  }
3417
3417
  }
3418
- Player.version = /* PLAYER_VERSION */ "4.3.1-dev.2025041002";
3418
+ Player.version = /* PLAYER_VERSION */ "4.4.0-dev.2025041400";
3419
3419
 
3420
3420
  /** Every events sent by the RxPlayer's public API. */
3421
3421
  interface IPublicAPIEvent {
@@ -300,7 +300,11 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
300
300
 
301
301
  const { serverCertificate } = options;
302
302
  if (!isNullOrUndefined(serverCertificate)) {
303
- const resSsc = await setServerCertificate(mediaKeys, serverCertificate);
303
+ const resSsc = await setServerCertificate(
304
+ mediaKeys,
305
+ serverCertificate,
306
+ mediaKeySystemAccess,
307
+ );
304
308
  if (resSsc.type === "error") {
305
309
  this.trigger("warning", resSsc.value);
306
310
  }
@@ -584,7 +588,7 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
584
588
  SessionEventsListener(
585
589
  mediaKeySession,
586
590
  options,
587
- mediaKeySystemAccess.keySystem,
591
+ mediaKeySystemAccess,
588
592
  {
589
593
  onKeyUpdate: (value: IKeyUpdateValue): void => {
590
594
  const linkedKeys = getKeyIdsLinkedToSession(
@@ -715,6 +719,11 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
715
719
  throw new EncryptedMediaError(
716
720
  "KEY_GENERATE_REQUEST_ERROR",
717
721
  error instanceof Error ? error.toString() : "Unknown error",
722
+ {
723
+ keyStatuses: undefined,
724
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
725
+ keySystem: mediaKeySystemAccess.keySystem,
726
+ },
718
727
  );
719
728
  }
720
729
  }
@@ -463,6 +463,11 @@ export default function getMediaKeySystemAccess(
463
463
  "No key system compatible with your wanted " +
464
464
  "configuration has been found in the current " +
465
465
  "browser.",
466
+ {
467
+ keyStatuses: undefined,
468
+ keySystemConfiguration: undefined,
469
+ keySystem: undefined,
470
+ },
466
471
  );
467
472
  }
468
473
 
@@ -157,6 +157,10 @@ async function createMediaKeys(
157
157
  } catch (error) {
158
158
  const message =
159
159
  error instanceof Error ? error.message : "Unknown error when creating MediaKeys.";
160
- throw new EncryptedMediaError("CREATE_MEDIA_KEYS_ERROR", message);
160
+ throw new EncryptedMediaError("CREATE_MEDIA_KEYS_ERROR", message, {
161
+ keyStatuses: undefined,
162
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
163
+ keySystem: mediaKeySystemAccess.keySystem,
164
+ });
161
165
  }
162
166
  }
@@ -14,7 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import type { IMediaKeySession } from "../../compat/browser_compatibility_types";
17
+ import type {
18
+ IMediaKeySession,
19
+ IMediaKeySystemAccess,
20
+ } from "../../compat/browser_compatibility_types";
18
21
  import {
19
22
  onKeyError,
20
23
  onKeyMessage,
@@ -35,14 +38,15 @@ import checkKeyStatuses from "./utils/check_key_statuses";
35
38
  * depending on the configuration given.
36
39
  * @param {MediaKeySession} session - The MediaKeySession concerned.
37
40
  * @param {Object} keySystemOptions - The key system options.
38
- * @param {String} keySystem - The configuration keySystem used for deciphering
41
+ * @param {MediaKeySystemAccess} mediaKeySystemAccess - The
42
+ * `MediaKeySystemAccess` that produced the linked `MediaKeys` instance.
39
43
  * @param {Object} callbacks
40
44
  * @param {Object} cancelSignal
41
45
  */
42
46
  export default function SessionEventsListener(
43
47
  session: IMediaKeySession,
44
48
  keySystemOptions: IKeySystemOption,
45
- keySystem: string,
49
+ mediaKeySystemAccess: IMediaKeySystemAccess,
46
50
  callbacks: ISessionEventListenerCallbacks,
47
51
  cancelSignal: CancellationSignal,
48
52
  ): void {
@@ -70,7 +74,13 @@ export default function SessionEventsListener(
70
74
  session,
71
75
  (evt) => {
72
76
  manualCanceller.cancel();
73
- callbacks.onError(new EncryptedMediaError("KEY_ERROR", (evt as Event).type));
77
+ callbacks.onError(
78
+ new EncryptedMediaError("KEY_ERROR", (evt as Event).type, {
79
+ keyStatuses: undefined,
80
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
81
+ keySystem: mediaKeySystemAccess.keySystem,
82
+ }),
83
+ );
74
84
  },
75
85
  manualCanceller.signal,
76
86
  );
@@ -120,7 +130,11 @@ export default function SessionEventsListener(
120
130
  log.info("DRM: No license given, skipping session.update");
121
131
  } else {
122
132
  try {
123
- await updateSessionWithMessage(session, licenseObject);
133
+ await updateSessionWithMessage(
134
+ session,
135
+ licenseObject,
136
+ mediaKeySystemAccess,
137
+ );
124
138
  } catch (err) {
125
139
  manualCanceller.cancel();
126
140
  callbacks.onError(err);
@@ -132,7 +146,7 @@ export default function SessionEventsListener(
132
146
  return;
133
147
  }
134
148
  manualCanceller.cancel();
135
- const formattedError = formatGetLicenseError(err);
149
+ const formattedError = formatGetLicenseError(err, mediaKeySystemAccess);
136
150
 
137
151
  if (!isNullOrUndefined(err)) {
138
152
  const { fallbackOnLastTry } = err as {
@@ -170,7 +184,7 @@ export default function SessionEventsListener(
170
184
  const { warning, blacklistedKeyIds, whitelistedKeyIds } = checkKeyStatuses(
171
185
  session,
172
186
  keySystemOptions,
173
- keySystem,
187
+ mediaKeySystemAccess,
174
188
  );
175
189
  if (warning !== undefined) {
176
190
  callbacks.onWarning(warning);
@@ -237,7 +251,8 @@ export default function SessionEventsListener(
237
251
  error instanceof GetLicenseTimeoutError ||
238
252
  isNullOrUndefined(error) ||
239
253
  (error as { noRetry?: boolean }).noRetry !== true,
240
- onRetry: (error: unknown) => callbacks.onWarning(formatGetLicenseError(error)),
254
+ onRetry: (error: unknown) =>
255
+ callbacks.onWarning(formatGetLicenseError(error, mediaKeySystemAccess)),
241
256
  };
242
257
  }
243
258
  }
@@ -257,19 +272,35 @@ export interface ISessionEventListenerCallbacks {
257
272
  * Format an error returned by a `getLicense` call to a proper form as defined
258
273
  * by the RxPlayer's API.
259
274
  * @param {*} error
275
+ * @param {MediaKeySystemAccess} mediaKeySystemAccess - The
276
+ * `MediaKeySystemAccess` that produced the linked `MediaKeys` instance.
277
+ * This parameter is mainly useful for error generation.
260
278
  * @returns {Error}
261
279
  */
262
- function formatGetLicenseError(error: unknown): IPlayerError {
280
+ function formatGetLicenseError(
281
+ error: unknown,
282
+ mediaKeySystemAccess: IMediaKeySystemAccess,
283
+ ): IPlayerError {
263
284
  if (error instanceof GetLicenseTimeoutError) {
264
285
  return new EncryptedMediaError(
265
286
  "KEY_LOAD_TIMEOUT",
266
287
  "The license server took too much time to " + "respond.",
288
+ {
289
+ keyStatuses: undefined,
290
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
291
+ keySystem: mediaKeySystemAccess.keySystem,
292
+ },
267
293
  );
268
294
  }
269
295
 
270
296
  const err = new EncryptedMediaError(
271
297
  "KEY_LOAD_ERROR",
272
298
  "An error occured when calling `getLicense`.",
299
+ {
300
+ keyStatuses: undefined,
301
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
302
+ keySystem: mediaKeySystemAccess.keySystem,
303
+ },
273
304
  );
274
305
  if (
275
306
  !isNullOrUndefined(error) &&
@@ -284,18 +315,26 @@ function formatGetLicenseError(error: unknown): IPlayerError {
284
315
  * Call MediaKeySession.update with the given `message`, if defined.
285
316
  * @param {MediaKeySession} session
286
317
  * @param {ArrayBuffer|TypedArray|null} message
318
+ * @param {MediaKeySystemAccess} mediaKeySystemAccess - The
319
+ * `MediaKeySystemAccess` that produced the linked `MediaKeys` instance.
320
+ * This parameter is mainly useful for error generation.
287
321
  * @returns {Promise}
288
322
  */
289
323
  async function updateSessionWithMessage(
290
324
  session: IMediaKeySession,
291
325
  message: BufferSource,
326
+ mediaKeySystemAccess: IMediaKeySystemAccess,
292
327
  ): Promise<void> {
293
328
  log.info("DRM: Updating MediaKeySession with message");
294
329
  try {
295
330
  await session.update(message);
296
331
  } catch (error) {
297
332
  const reason = error instanceof Error ? error.toString() : "`session.update` failed";
298
- throw new EncryptedMediaError("KEY_UPDATE_ERROR", reason);
333
+ throw new EncryptedMediaError("KEY_UPDATE_ERROR", reason, {
334
+ keyStatuses: undefined,
335
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
336
+ keySystem: mediaKeySystemAccess.keySystem,
337
+ });
299
338
  }
300
339
  log.info("DRM: MediaKeySession update succeeded.");
301
340
  }
@@ -14,7 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import type { IMediaKeys } from "../../compat/browser_compatibility_types";
17
+ import type {
18
+ IMediaKeys,
19
+ IMediaKeySystemAccess,
20
+ } from "../../compat/browser_compatibility_types";
18
21
  import { EncryptedMediaError, isKnownError } from "../../errors";
19
22
  import log from "../../log";
20
23
  import type { IPlayerError } from "../../public_types";
@@ -32,11 +35,15 @@ import ServerCertificateStore from "./utils/server_certificate_store";
32
35
  *
33
36
  * @param {MediaKeys} mediaKeys
34
37
  * @param {ArrayBuffer} serverCertificate
38
+ * @param {MediaKeySystemAccess} mediaKeySystemAccess - The
39
+ * `MediaKeySystemAccess` that produced the `MediaKeys` instance provided.
40
+ * This parameter is mainly useful for error generation.
35
41
  * @returns {Promise}
36
42
  */
37
43
  async function setServerCertificate(
38
44
  mediaKeys: IMediaKeys,
39
45
  serverCertificate: BufferSource,
46
+ mediaKeySystemAccess: IMediaKeySystemAccess,
40
47
  ): Promise<unknown> {
41
48
  try {
42
49
  const res = await mediaKeys.setServerCertificate(serverCertificate);
@@ -51,7 +58,11 @@ async function setServerCertificate(
51
58
  );
52
59
  const reason =
53
60
  error instanceof Error ? error.toString() : "`setServerCertificate` error";
54
- throw new EncryptedMediaError("LICENSE_SERVER_CERTIFICATE_ERROR", reason);
61
+ throw new EncryptedMediaError("LICENSE_SERVER_CERTIFICATE_ERROR", reason, {
62
+ keyStatuses: undefined,
63
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
64
+ keySystem: mediaKeySystemAccess.keySystem,
65
+ });
55
66
  }
56
67
  }
57
68
 
@@ -60,11 +71,15 @@ async function setServerCertificate(
60
71
  * and complete.
61
72
  * @param {MediaKeys} mediaKeys
62
73
  * @param {ArrayBuffer} serverCertificate
74
+ * @param {MediaKeySystemAccess} mediaKeySystemAccess - The
75
+ * `MediaKeySystemAccess` that produced the `MediaKeys` instance provided.
76
+ * This parameter is mainly useful for error generation.
63
77
  * @returns {Promise.<Object>}
64
78
  */
65
79
  export default async function trySettingServerCertificate(
66
80
  mediaKeys: IMediaKeys,
67
81
  serverCertificate: BufferSource,
82
+ mediaKeySystemAccess: IMediaKeySystemAccess,
68
83
  ): Promise<
69
84
  | { type: "success"; value: unknown }
70
85
  | { type: "already-has-one" }
@@ -90,7 +105,11 @@ export default async function trySettingServerCertificate(
90
105
  // Calling `prepare` allow to invalidate temporarily that status.
91
106
  ServerCertificateStore.prepare(mediaKeys);
92
107
  try {
93
- const result = await setServerCertificate(mediaKeys, serverCertificate);
108
+ const result = await setServerCertificate(
109
+ mediaKeys,
110
+ serverCertificate,
111
+ mediaKeySystemAccess,
112
+ );
94
113
  ServerCertificateStore.set(mediaKeys, serverCertificate);
95
114
  return { type: "success", value: result };
96
115
  } catch (error) {
@@ -99,6 +118,11 @@ export default async function trySettingServerCertificate(
99
118
  : new EncryptedMediaError(
100
119
  "LICENSE_SERVER_CERTIFICATE_ERROR",
101
120
  "Unknown error when setting the server certificate.",
121
+ {
122
+ keyStatuses: undefined,
123
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
124
+ keySystem: mediaKeySystemAccess.keySystem,
125
+ },
102
126
  );
103
127
  return { type: "error" as const, value: formattedErr };
104
128
  }
@@ -14,7 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import type { IMediaKeySession } from "../../../compat/browser_compatibility_types";
17
+ import type {
18
+ IMediaKeySession,
19
+ IMediaKeySystemAccess,
20
+ } from "../../../compat/browser_compatibility_types";
18
21
  import getUUIDKidFromKeyStatusKID from "../../../compat/eme/get_uuid_kid_from_keystatus_kid";
19
22
  import { EncryptedMediaError } from "../../../errors";
20
23
  import log from "../../../log";
@@ -79,13 +82,14 @@ type IKeyStatusesForEach = (
79
82
  * @param {MediaKeySession} session - The MediaKeySession from which the keys
80
83
  * will be checked.
81
84
  * @param {Object} options
82
- * @param {String} keySystem - The configuration keySystem used for deciphering
85
+ * @param {MediaKeySystemAccess} mediaKeySystemAccess - The
86
+ * `MediaKeySystemAccess` that produced the linked `MediaKeys` instance.
83
87
  * @returns {Object} - Warnings to send, whitelisted and blacklisted key ids.
84
88
  */
85
89
  export default function checkKeyStatuses(
86
90
  session: IMediaKeySession,
87
91
  options: IKeyStatusesCheckingOptions,
88
- keySystem: string,
92
+ mediaKeySystemAccess: IMediaKeySystemAccess,
89
93
  ): {
90
94
  warning: EncryptedMediaError | undefined;
91
95
  blacklistedKeyIds: Uint8Array[];
@@ -107,7 +111,10 @@ export default function checkKeyStatuses(
107
111
  ];
108
112
  })();
109
113
 
110
- const keyId = getUUIDKidFromKeyStatusKID(keySystem, new Uint8Array(keyStatusKeyId));
114
+ const keyId = getUUIDKidFromKeyStatusKID(
115
+ mediaKeySystemAccess.keySystem,
116
+ new Uint8Array(keyStatusKeyId),
117
+ );
111
118
 
112
119
  const keyStatusObj = { keyId: keyId.buffer, keyStatus };
113
120
 
@@ -120,7 +127,11 @@ export default function checkKeyStatuses(
120
127
  const error = new EncryptedMediaError(
121
128
  "KEY_STATUS_CHANGE_ERROR",
122
129
  `A decryption key expired (${bytesToHex(keyId)})`,
123
- { keyStatuses: [keyStatusObj, ...badKeyStatuses] },
130
+ {
131
+ keyStatuses: [keyStatusObj, ...badKeyStatuses],
132
+ keySystem: mediaKeySystemAccess.keySystem,
133
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
134
+ },
124
135
  );
125
136
 
126
137
  if (onKeyExpiration === "error" || onKeyExpiration === undefined) {
@@ -153,7 +164,11 @@ export default function checkKeyStatuses(
153
164
  const error = new EncryptedMediaError(
154
165
  "KEY_STATUS_CHANGE_ERROR",
155
166
  `A "${keyStatus}" status has been encountered (${bytesToHex(keyId)})`,
156
- { keyStatuses: [keyStatusObj, ...badKeyStatuses] },
167
+ {
168
+ keyStatuses: [keyStatusObj, ...badKeyStatuses],
169
+ keySystem: mediaKeySystemAccess.keySystem,
170
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
171
+ },
157
172
  );
158
173
  switch (onKeyInternalError) {
159
174
  case undefined:
@@ -185,7 +200,11 @@ export default function checkKeyStatuses(
185
200
  const error = new EncryptedMediaError(
186
201
  "KEY_STATUS_CHANGE_ERROR",
187
202
  `A "${keyStatus}" status has been encountered (${bytesToHex(keyId)})`,
188
- { keyStatuses: [keyStatusObj, ...badKeyStatuses] },
203
+ {
204
+ keyStatuses: [keyStatusObj, ...badKeyStatuses],
205
+ keySystem: mediaKeySystemAccess.keySystem,
206
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
207
+ },
189
208
  );
190
209
  switch (onKeyOutputRestricted) {
191
210
  case undefined:
@@ -223,7 +242,11 @@ export default function checkKeyStatuses(
223
242
  warning = new EncryptedMediaError(
224
243
  "KEY_STATUS_CHANGE_ERROR",
225
244
  "One or several problematic key statuses have been encountered",
226
- { keyStatuses: badKeyStatuses },
245
+ {
246
+ keyStatuses: badKeyStatuses,
247
+ keySystem: mediaKeySystemAccess.keySystem,
248
+ keySystemConfiguration: mediaKeySystemAccess.getConfiguration(),
249
+ },
227
250
  );
228
251
  }
229
252
  return { warning, blacklistedKeyIds, whitelistedKeyIds };
@@ -255,6 +255,11 @@ async function attachMediaKeys(
255
255
  throw new EncryptedMediaError(
256
256
  "MEDIA_KEYS_ATTACHMENT_ERROR",
257
257
  "Could not attach the MediaKeys to the media element: " + errMessage,
258
+ {
259
+ keyStatuses: undefined,
260
+ keySystemConfiguration: mediaKeysInfo.mediaKeySystemAccess.getConfiguration(),
261
+ keySystem: mediaKeysInfo.mediaKeySystemAccess.keySystem,
262
+ },
258
263
  );
259
264
  }
260
265
  }
@@ -1247,7 +1247,11 @@ export default class MultiThreadContentInitializer extends ContentInitializer {
1247
1247
  return;
1248
1248
  }
1249
1249
  stopListening();
1250
- const err = new EncryptedMediaError("MEDIA_IS_ENCRYPTED_ERROR", errMsg);
1250
+ const err = new EncryptedMediaError("MEDIA_IS_ENCRYPTED_ERROR", errMsg, {
1251
+ keyStatuses: undefined,
1252
+ keySystemConfiguration: undefined,
1253
+ keySystem: undefined,
1254
+ });
1251
1255
  this._onFatalError(err);
1252
1256
  },
1253
1257
  { clearSignal: cancelSignal },
@@ -2121,13 +2125,14 @@ function formatWorkerError(sentError: ISentError): IPlayerError {
2121
2125
  tracks: sentError.tracks,
2122
2126
  });
2123
2127
  case "EncryptedMediaError":
2124
- if (sentError.code === "KEY_STATUS_CHANGE_ERROR") {
2125
- return new EncryptedMediaError(sentError.code, sentError.reason, {
2126
- keyStatuses: sentError.keyStatuses ?? [],
2127
- });
2128
- } else {
2129
- return new EncryptedMediaError(sentError.code, sentError.reason);
2130
- }
2128
+ // We assume that everything have already been checked Worker-side here
2129
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
2130
+ return new EncryptedMediaError(sentError.code, sentError.reason, {
2131
+ keyStatuses: sentError.keyStatuses,
2132
+ keySystemConfiguration: sentError.keySystemConfiguration,
2133
+ keySystem: sentError.keySystem,
2134
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2135
+ } as any);
2131
2136
  case "OtherError":
2132
2137
  return new OtherError(sentError.code, sentError.reason);
2133
2138
  }
@@ -155,7 +155,11 @@ export default function initializeContentDecryption(
155
155
  value: EncryptedMediaError;
156
156
  };
157
157
  } {
158
- const err = new EncryptedMediaError("MEDIA_IS_ENCRYPTED_ERROR", errMsg);
158
+ const err = new EncryptedMediaError("MEDIA_IS_ENCRYPTED_ERROR", errMsg, {
159
+ keyStatuses: undefined,
160
+ keySystemConfiguration: undefined,
161
+ keySystem: undefined,
162
+ });
159
163
  const ref = new SharedReference({
160
164
  initializationState: { type: "initialized" as const, value: null },
161
165
  drmSystemId: undefined,
@@ -1 +0,0 @@
1
- {}