rx-player 4.2.0-dev.2024080600 → 4.2.0-dev.2024080900

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 (39) hide show
  1. package/VERSION +1 -1
  2. package/dist/commonjs/main_thread/api/public_api.js +2 -2
  3. package/dist/commonjs/main_thread/decrypt/attach_media_keys.d.ts +6 -1
  4. package/dist/commonjs/main_thread/decrypt/attach_media_keys.d.ts.map +1 -1
  5. package/dist/commonjs/main_thread/decrypt/attach_media_keys.js +2 -1
  6. package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  7. package/dist/commonjs/main_thread/decrypt/content_decryptor.js +2 -1
  8. package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts +17 -5
  9. package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts.map +1 -1
  10. package/dist/commonjs/main_thread/decrypt/find_key_system.js +35 -26
  11. package/dist/commonjs/main_thread/decrypt/get_media_keys.d.ts +5 -0
  12. package/dist/commonjs/main_thread/decrypt/get_media_keys.d.ts.map +1 -1
  13. package/dist/commonjs/main_thread/decrypt/get_media_keys.js +4 -2
  14. package/dist/commonjs/main_thread/decrypt/utils/media_keys_infos_store.d.ts +5 -0
  15. package/dist/commonjs/main_thread/decrypt/utils/media_keys_infos_store.d.ts.map +1 -1
  16. package/dist/es2017/main_thread/api/public_api.js +2 -2
  17. package/dist/es2017/main_thread/decrypt/attach_media_keys.d.ts +6 -1
  18. package/dist/es2017/main_thread/decrypt/attach_media_keys.d.ts.map +1 -1
  19. package/dist/es2017/main_thread/decrypt/attach_media_keys.js +2 -1
  20. package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
  21. package/dist/es2017/main_thread/decrypt/content_decryptor.js +2 -1
  22. package/dist/es2017/main_thread/decrypt/find_key_system.d.ts +17 -5
  23. package/dist/es2017/main_thread/decrypt/find_key_system.d.ts.map +1 -1
  24. package/dist/es2017/main_thread/decrypt/find_key_system.js +40 -35
  25. package/dist/es2017/main_thread/decrypt/get_media_keys.d.ts +5 -0
  26. package/dist/es2017/main_thread/decrypt/get_media_keys.d.ts.map +1 -1
  27. package/dist/es2017/main_thread/decrypt/get_media_keys.js +3 -1
  28. package/dist/es2017/main_thread/decrypt/utils/media_keys_infos_store.d.ts +5 -0
  29. package/dist/es2017/main_thread/decrypt/utils/media_keys_infos_store.d.ts.map +1 -1
  30. package/dist/rx-player.js +15 -15
  31. package/package.json +1 -1
  32. package/src/main_thread/api/public_api.ts +2 -2
  33. package/src/main_thread/decrypt/__tests__/__global__/media_key_system_access.test.ts +376 -102
  34. package/src/main_thread/decrypt/__tests__/__global__/utils.ts +4 -23
  35. package/src/main_thread/decrypt/attach_media_keys.ts +7 -0
  36. package/src/main_thread/decrypt/content_decryptor.ts +3 -1
  37. package/src/main_thread/decrypt/find_key_system.ts +53 -43
  38. package/src/main_thread/decrypt/get_media_keys.ts +8 -1
  39. package/src/main_thread/decrypt/utils/media_keys_infos_store.ts +6 -0
@@ -21,7 +21,7 @@ import { strToUtf8, utf8ToStr } from "../../../../utils/string_parsing";
21
21
  import type { CancellationSignal } from "../../../../utils/task_canceller";
22
22
 
23
23
  /** Default MediaKeySystemAccess configuration used by the RxPlayer. */
24
- export const defaultKSConfig = [
24
+ export const defaultKSConfig: MediaKeySystemConfiguration[] = [
25
25
  {
26
26
  audioCapabilities: [
27
27
  { contentType: 'audio/mp4;codecs="mp4a.40.2"' },
@@ -38,21 +38,13 @@ export const defaultKSConfig = [
38
38
  { contentType: 'video/webm;codecs="vp8"' },
39
39
  ],
40
40
  },
41
- {
42
- audioCapabilities: undefined,
43
- distinctiveIdentifier: "optional" as const,
44
- initDataTypes: ["cenc"] as const,
45
- persistentState: "optional" as const,
46
- sessionTypes: ["temporary"] as const,
47
- videoCapabilities: undefined,
48
- },
49
41
  ];
50
42
 
51
43
  /**
52
44
  * Default "com.microsoft.playready.recommendation" MediaKeySystemAccess
53
45
  * configuration used by the RxPlayer.
54
46
  */
55
- export const defaultPRRecommendationKSConfig = [
47
+ export const defaultPRRecommendationKSConfig: MediaKeySystemConfiguration[] = [
56
48
  {
57
49
  audioCapabilities: [
58
50
  { robustness: "3000", contentType: 'audio/mp4;codecs="mp4a.40.2"' },
@@ -75,18 +67,10 @@ export const defaultPRRecommendationKSConfig = [
75
67
  { robustness: "2000", contentType: 'video/webm;codecs="vp8"' },
76
68
  ],
77
69
  },
78
- {
79
- audioCapabilities: undefined,
80
- distinctiveIdentifier: "optional" as const,
81
- initDataTypes: ["cenc"] as const,
82
- persistentState: "optional" as const,
83
- sessionTypes: ["temporary"] as const,
84
- videoCapabilities: undefined,
85
- },
86
70
  ];
87
71
 
88
72
  /** Default Widevine MediaKeySystemAccess configuration used by the RxPlayer. */
89
- export const defaultWidevineConfig = (() => {
73
+ export const defaultWidevineConfig: MediaKeySystemConfiguration[] = (() => {
90
74
  const ROBUSTNESSES = [
91
75
  "HW_SECURE_ALL",
92
76
  "HW_SECURE_DECODE",
@@ -108,10 +92,7 @@ export const defaultWidevineConfig = (() => {
108
92
  { contentType: "audio/webm;codecs=opus", robustness },
109
93
  ];
110
94
  });
111
- return [
112
- { ...defaultKSConfig[0], audioCapabilities, videoCapabilities },
113
- defaultKSConfig[1],
114
- ];
95
+ return [{ ...defaultKSConfig[0], audioCapabilities, videoCapabilities }];
115
96
  })();
116
97
 
117
98
  /**
@@ -55,6 +55,7 @@ export default async function attachMediaKeys(
55
55
  {
56
56
  emeImplementation,
57
57
  keySystemOptions,
58
+ askedConfiguration,
58
59
  loadedSessionsStore,
59
60
  mediaKeySystemAccess,
60
61
  mediaKeys,
@@ -81,6 +82,7 @@ export default async function attachMediaKeys(
81
82
  mediaKeySystemAccess,
82
83
  mediaKeys,
83
84
  loadedSessionsStore,
85
+ askedConfiguration,
84
86
  });
85
87
  if (mediaElement.mediaKeys === mediaKeys) {
86
88
  return;
@@ -109,6 +111,11 @@ export interface IMediaKeysState {
109
111
  mediaKeySystemAccess: MediaKeySystemAccess | ICustomMediaKeySystemAccess;
110
112
  /** The MediaKeys instance to attach to the media element. */
111
113
  mediaKeys: MediaKeys | ICustomMediaKeys;
114
+ /**
115
+ * The MediaKeySystemConfiguration that has been provided to the
116
+ * `requestMediaKeySystemAccess` API.
117
+ */
118
+ askedConfiguration: MediaKeySystemConfiguration;
112
119
  /**
113
120
  * The chosen EME implementation abstraction linked to `mediaKeys`.
114
121
  * Different EME implementation might for example be used while debugging or
@@ -255,7 +255,8 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
255
255
  }
256
256
 
257
257
  const { mediaElement, mediaKeysInfo } = this._stateData.data;
258
- const { options, mediaKeys, mediaKeySystemAccess, stores } = mediaKeysInfo;
258
+ const { options, mediaKeys, mediaKeySystemAccess, stores, askedConfiguration } =
259
+ mediaKeysInfo;
259
260
  const shouldDisableLock = options.disableMediaKeysAttachmentLock === true;
260
261
 
261
262
  if (shouldDisableLock) {
@@ -279,6 +280,7 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
279
280
  loadedSessionsStore: stores.loadedSessionsStore,
280
281
  mediaKeySystemAccess,
281
282
  mediaKeys,
283
+ askedConfiguration,
282
284
  keySystemOptions: options,
283
285
  };
284
286
 
@@ -26,11 +26,7 @@ import shouldRenewMediaKeySystemAccess from "../../compat/should_renew_media_key
26
26
  import config from "../../config";
27
27
  import { EncryptedMediaError } from "../../errors";
28
28
  import log from "../../log";
29
- import type {
30
- IAudioCapabilitiesConfiguration,
31
- IKeySystemOption,
32
- IVideoCapabilitiesConfiguration,
33
- } from "../../public_types";
29
+ import type { IKeySystemOption } from "../../public_types";
34
30
  import { parseCodec } from "../../utils/are_codecs_compatible";
35
31
  import arrayIncludes from "../../utils/array_includes";
36
32
  import flatMap from "../../utils/flat_map";
@@ -47,8 +43,19 @@ export type ICodecSupportList = Array<{
47
43
  }>;
48
44
 
49
45
  export interface IMediaKeySystemAccessInfos {
46
+ /** `MediaKeySystemAccess` to use to create `MediaKeys` instances. */
50
47
  mediaKeySystemAccess: MediaKeySystemAccess | ICustomMediaKeySystemAccess;
48
+ /**
49
+ * The MediaKeySystemConfiguration that has been provided to the
50
+ * `requestMediaKeySystemAccess` API.
51
+ */
52
+ askedConfiguration: MediaKeySystemConfiguration;
53
+ /**
54
+ * Corresponding `keySystems` element that has led to the creation of the
55
+ * `MediaKeySystemAccess`.
56
+ */
51
57
  options: IKeySystemOption;
58
+ /** Information on supported or unsupported codec on that `MediaKeySystemAccess`. */
52
59
  codecSupport: ICodecSupportList;
53
60
  }
54
61
 
@@ -88,10 +95,12 @@ interface IKeySystemType {
88
95
  */
89
96
  function checkCachedMediaKeySystemAccess(
90
97
  keySystems: IKeySystemOption[],
98
+ askedConfiguration: MediaKeySystemConfiguration,
91
99
  currentKeySystemAccess: MediaKeySystemAccess | ICustomMediaKeySystemAccess,
92
100
  currentKeySystemOptions: IKeySystemOption,
93
101
  ): null | {
94
102
  keySystemOptions: IKeySystemOption;
103
+ askedConfiguration: MediaKeySystemConfiguration;
95
104
  keySystemAccess: MediaKeySystemAccess | ICustomMediaKeySystemAccess;
96
105
  } {
97
106
  const mksConfiguration = currentKeySystemAccess.getConfiguration();
@@ -127,6 +136,7 @@ function checkCachedMediaKeySystemAccess(
127
136
  return {
128
137
  keySystemOptions: firstCompatibleOption,
129
138
  keySystemAccess: currentKeySystemAccess,
139
+ askedConfiguration,
130
140
  };
131
141
  }
132
142
  return null;
@@ -280,29 +290,23 @@ function buildKeySystemConfigurations(
280
290
  }
281
291
  /**
282
292
  * Extract from the current mediaKeys the supported Codecs.
283
- * @param {Object | undefined} audioCapabilitiesConfig - The audio capabilities provided to the KeySystem.
284
- * @param {Object | undefined} videoCapabilitiesConfig - The video capabilities provided to the KeySystem.
285
- * @param {Object | undefined} mksConfiguration - The result of getConfiguration() of the media keys.
293
+ * @param {Object} initialConfiguration - The MediaKeySystemConfiguration given
294
+ * to the `navigator.requestMediaKeySystemAccess` API.
295
+ * @param {Object | undefined} mksConfiguration - The result of
296
+ * getConfiguration() of the media keys.
286
297
  * @return {Array} The list of supported codec by the CDM.
287
298
  */
288
299
  export function extractCodecSupportListFromConfiguration(
289
- audioCapabilitiesConfig: IAudioCapabilitiesConfiguration | undefined,
290
- videoCapabilitiesConfig: IVideoCapabilitiesConfiguration | undefined,
300
+ initialConfiguration: MediaKeySystemConfiguration,
291
301
  mksConfiguration: MediaKeySystemConfiguration,
292
302
  ): ICodecSupportList {
293
- const { EME_DEFAULT_AUDIO_CODECS, EME_DEFAULT_VIDEO_CODECS } = config.getCurrent();
294
-
295
303
  const testedAudioCodecs =
296
- audioCapabilitiesConfig?.type === "contentType"
297
- ? audioCapabilitiesConfig?.value
298
- : EME_DEFAULT_AUDIO_CODECS;
299
-
304
+ initialConfiguration.audioCapabilities?.map((v) => v.contentType) ?? [];
300
305
  const testedVideoCodecs =
301
- videoCapabilitiesConfig?.type === "contentType"
302
- ? videoCapabilitiesConfig.value
303
- : EME_DEFAULT_VIDEO_CODECS;
304
-
305
- const testedCodecs = testedAudioCodecs.concat(testedVideoCodecs);
306
+ initialConfiguration.videoCapabilities?.map((v) => v.contentType) ?? [];
307
+ const testedCodecs: string[] = testedAudioCodecs
308
+ .concat(testedVideoCodecs)
309
+ .filter((c): c is string => c !== undefined);
306
310
  const supportedVideoCodecs = mksConfiguration.videoCapabilities?.map(
307
311
  (entry) => entry.contentType,
308
312
  );
@@ -368,6 +372,7 @@ export default function getMediaKeySystemAccess(
368
372
  // one as exactly the same compatibility options.
369
373
  const cachedKeySystemAccess = checkCachedMediaKeySystemAccess(
370
374
  keySystemsConfigs,
375
+ currentState.askedConfiguration,
371
376
  currentState.mediaKeySystemAccess,
372
377
  currentState.keySystemOptions,
373
378
  );
@@ -377,10 +382,10 @@ export default function getMediaKeySystemAccess(
377
382
  type: "reuse-media-key-system-access" as const,
378
383
  value: {
379
384
  mediaKeySystemAccess: cachedKeySystemAccess.keySystemAccess,
385
+ askedConfiguration: cachedKeySystemAccess.askedConfiguration,
380
386
  options: cachedKeySystemAccess.keySystemOptions,
381
387
  codecSupport: extractCodecSupportListFromConfiguration(
382
- cachedKeySystemAccess.keySystemOptions.audioCapabilitiesConfig,
383
- cachedKeySystemAccess.keySystemOptions.videoCapabilitiesConfig,
388
+ cachedKeySystemAccess.askedConfiguration,
384
389
  cachedKeySystemAccess.keySystemAccess.getConfiguration(),
385
390
  ),
386
391
  },
@@ -458,30 +463,35 @@ export default function getMediaKeySystemAccess(
458
463
  `${index + 1} of ${keySystemsType.length}`,
459
464
  );
460
465
 
461
- try {
462
- const keySystemAccess = await testKeySystem(keyType, keySystemConfigurations);
463
- log.info("DRM: Found compatible keysystem", keyType, index + 1);
464
- return {
465
- type: "create-media-key-system-access" as const,
466
- value: {
467
- options: keySystemOptions,
468
- mediaKeySystemAccess: keySystemAccess,
469
- codecSupport: extractCodecSupportListFromConfiguration(
470
- keySystemOptions.audioCapabilitiesConfig,
471
- keySystemOptions.videoCapabilitiesConfig,
472
- keySystemAccess.getConfiguration(),
473
- ),
474
- },
475
- };
476
- } catch (_) {
477
- log.debug("DRM: Rejected access to keysystem", keyType, index + 1);
478
- if (cancelSignal.cancellationError !== null) {
479
- throw cancelSignal.cancellationError;
466
+ let keySystemAccess;
467
+ for (let configIdx = 0; configIdx < keySystemConfigurations.length; configIdx++) {
468
+ const keySystemConfiguration = keySystemConfigurations[configIdx];
469
+ try {
470
+ keySystemAccess = await testKeySystem(keyType, [keySystemConfiguration]);
471
+ log.info("DRM: Found compatible keysystem", keyType, index + 1);
472
+ return {
473
+ type: "create-media-key-system-access" as const,
474
+ value: {
475
+ options: keySystemOptions,
476
+ mediaKeySystemAccess: keySystemAccess,
477
+ askedConfiguration: keySystemConfiguration,
478
+ codecSupport: extractCodecSupportListFromConfiguration(
479
+ keySystemConfiguration,
480
+ keySystemAccess.getConfiguration(),
481
+ ),
482
+ },
483
+ };
484
+ } catch (_) {
485
+ log.debug("DRM: Rejected access to keysystem", keyType, index + 1, configIdx);
486
+ if (cancelSignal.cancellationError !== null) {
487
+ throw cancelSignal.cancellationError;
488
+ }
480
489
  }
481
- return recursivelyTestKeySystems(index + 1);
482
490
  }
491
+ return recursivelyTestKeySystems(index + 1);
483
492
  }
484
493
  }
494
+
485
495
  /**
486
496
  * Test a key system configuration, resolves with the MediaKeySystemAccess
487
497
  * or reject if the key system is unsupported.
@@ -51,6 +51,11 @@ function createPersistentSessionsStorage(
51
51
  export interface IMediaKeysInfos {
52
52
  /** The MediaKeySystemAccess which allowed to create the MediaKeys instance. */
53
53
  mediaKeySystemAccess: MediaKeySystemAccess | ICustomMediaKeySystemAccess;
54
+ /**
55
+ * The MediaKeySystemConfiguration that has been provided to the
56
+ * `requestMediaKeySystemAccess` API.
57
+ */
58
+ askedConfiguration: MediaKeySystemConfiguration;
54
59
  /** The MediaKeys instance. */
55
60
  mediaKeys: MediaKeys | ICustomMediaKeys;
56
61
  /** Stores allowing to create and retrieve MediaKeySessions. */
@@ -88,7 +93,7 @@ export default async function getMediaKeysInfos(
88
93
  throw cancelSignal.cancellationError;
89
94
  }
90
95
 
91
- const { options, mediaKeySystemAccess, codecSupport } = evt.value;
96
+ const { options, mediaKeySystemAccess, askedConfiguration, codecSupport } = evt.value;
92
97
  const currentState = MediaKeysInfosStore.getState(mediaElement);
93
98
  const persistentSessionsStore = createPersistentSessionsStorage(options);
94
99
 
@@ -110,6 +115,7 @@ export default async function getMediaKeysInfos(
110
115
  return {
111
116
  mediaKeys,
112
117
  mediaKeySystemAccess,
118
+ askedConfiguration,
113
119
  stores: { loadedSessionsStore, persistentSessionsStore },
114
120
  options,
115
121
  codecSupport,
@@ -123,6 +129,7 @@ export default async function getMediaKeysInfos(
123
129
  return {
124
130
  mediaKeys,
125
131
  mediaKeySystemAccess,
132
+ askedConfiguration,
126
133
  stores: { loadedSessionsStore, persistentSessionsStore },
127
134
  options,
128
135
  codecSupport,
@@ -30,6 +30,12 @@ export interface IMediaElementMediaKeysInfos {
30
30
  /** Last keySystemOptions used with that HTMLMediaElement. */
31
31
  keySystemOptions: IKeySystemOption;
32
32
 
33
+ /**
34
+ * The actual MediaKeySystemConfiguration asked to the
35
+ * `requestMediaKeySystemAccess` API.
36
+ */
37
+ askedConfiguration: MediaKeySystemConfiguration;
38
+
33
39
  /**
34
40
  * Last MediaKeySystemAccess used to create a MediaKeys bound to that
35
41
  * HTMLMediaElement.