rx-player 4.2.0-dev.2024080600 → 4.2.0-dev.2024081300
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.
- package/VERSION +1 -1
- package/dist/commonjs/main_thread/api/public_api.js +2 -2
- package/dist/commonjs/main_thread/decrypt/attach_media_keys.d.ts +6 -1
- package/dist/commonjs/main_thread/decrypt/attach_media_keys.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/attach_media_keys.js +2 -1
- package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/content_decryptor.js +2 -1
- package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts +17 -5
- package/dist/commonjs/main_thread/decrypt/find_key_system.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/find_key_system.js +56 -26
- package/dist/commonjs/main_thread/decrypt/get_media_keys.d.ts +5 -0
- package/dist/commonjs/main_thread/decrypt/get_media_keys.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/get_media_keys.js +4 -2
- package/dist/commonjs/main_thread/decrypt/utils/media_keys_infos_store.d.ts +5 -0
- package/dist/commonjs/main_thread/decrypt/utils/media_keys_infos_store.d.ts.map +1 -1
- package/dist/es2017/main_thread/api/public_api.js +2 -2
- package/dist/es2017/main_thread/decrypt/attach_media_keys.d.ts +6 -1
- package/dist/es2017/main_thread/decrypt/attach_media_keys.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/attach_media_keys.js +2 -1
- package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/content_decryptor.js +2 -1
- package/dist/es2017/main_thread/decrypt/find_key_system.d.ts +17 -5
- package/dist/es2017/main_thread/decrypt/find_key_system.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/find_key_system.js +61 -35
- package/dist/es2017/main_thread/decrypt/get_media_keys.d.ts +5 -0
- package/dist/es2017/main_thread/decrypt/get_media_keys.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/get_media_keys.js +3 -1
- package/dist/es2017/main_thread/decrypt/utils/media_keys_infos_store.d.ts +5 -0
- package/dist/es2017/main_thread/decrypt/utils/media_keys_infos_store.d.ts.map +1 -1
- package/dist/rx-player.js +15 -15
- package/package.json +1 -1
- package/src/main_thread/api/public_api.ts +2 -2
- package/src/main_thread/decrypt/__tests__/__global__/media_key_system_access.test.ts +376 -102
- package/src/main_thread/decrypt/__tests__/__global__/utils.ts +4 -23
- package/src/main_thread/decrypt/attach_media_keys.ts +7 -0
- package/src/main_thread/decrypt/content_decryptor.ts +3 -1
- package/src/main_thread/decrypt/find_key_system.ts +78 -43
- package/src/main_thread/decrypt/get_media_keys.ts +8 -1
- 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 } =
|
|
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;
|
|
@@ -265,6 +275,31 @@ function buildKeySystemConfigurations(
|
|
|
265
275
|
sessionTypes,
|
|
266
276
|
};
|
|
267
277
|
|
|
278
|
+
if (audioCapabilitiesConfig !== undefined) {
|
|
279
|
+
if (videoCapabilitiesConfig !== undefined) {
|
|
280
|
+
return [wantedMediaKeySystemConfiguration];
|
|
281
|
+
}
|
|
282
|
+
return [
|
|
283
|
+
wantedMediaKeySystemConfiguration,
|
|
284
|
+
{
|
|
285
|
+
...wantedMediaKeySystemConfiguration,
|
|
286
|
+
// Re-try without `videoCapabilities` in case the EME implementation is
|
|
287
|
+
// buggy
|
|
288
|
+
videoCapabilities: undefined,
|
|
289
|
+
} as unknown as MediaKeySystemConfiguration,
|
|
290
|
+
];
|
|
291
|
+
} else if (videoCapabilitiesConfig !== undefined) {
|
|
292
|
+
return [
|
|
293
|
+
wantedMediaKeySystemConfiguration,
|
|
294
|
+
{
|
|
295
|
+
...wantedMediaKeySystemConfiguration,
|
|
296
|
+
// Re-try without `audioCapabilities` in case the EME implementation is
|
|
297
|
+
// buggy
|
|
298
|
+
audioCapabilities: undefined,
|
|
299
|
+
} as unknown as MediaKeySystemConfiguration,
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
|
|
268
303
|
return [
|
|
269
304
|
wantedMediaKeySystemConfiguration,
|
|
270
305
|
|
|
@@ -280,29 +315,23 @@ function buildKeySystemConfigurations(
|
|
|
280
315
|
}
|
|
281
316
|
/**
|
|
282
317
|
* Extract from the current mediaKeys the supported Codecs.
|
|
283
|
-
* @param {Object
|
|
284
|
-
*
|
|
285
|
-
* @param {Object | undefined} mksConfiguration - The result of
|
|
318
|
+
* @param {Object} initialConfiguration - The MediaKeySystemConfiguration given
|
|
319
|
+
* to the `navigator.requestMediaKeySystemAccess` API.
|
|
320
|
+
* @param {Object | undefined} mksConfiguration - The result of
|
|
321
|
+
* getConfiguration() of the media keys.
|
|
286
322
|
* @return {Array} The list of supported codec by the CDM.
|
|
287
323
|
*/
|
|
288
324
|
export function extractCodecSupportListFromConfiguration(
|
|
289
|
-
|
|
290
|
-
videoCapabilitiesConfig: IVideoCapabilitiesConfiguration | undefined,
|
|
325
|
+
initialConfiguration: MediaKeySystemConfiguration,
|
|
291
326
|
mksConfiguration: MediaKeySystemConfiguration,
|
|
292
327
|
): ICodecSupportList {
|
|
293
|
-
const { EME_DEFAULT_AUDIO_CODECS, EME_DEFAULT_VIDEO_CODECS } = config.getCurrent();
|
|
294
|
-
|
|
295
328
|
const testedAudioCodecs =
|
|
296
|
-
|
|
297
|
-
? audioCapabilitiesConfig?.value
|
|
298
|
-
: EME_DEFAULT_AUDIO_CODECS;
|
|
299
|
-
|
|
329
|
+
initialConfiguration.audioCapabilities?.map((v) => v.contentType) ?? [];
|
|
300
330
|
const testedVideoCodecs =
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const testedCodecs = testedAudioCodecs.concat(testedVideoCodecs);
|
|
331
|
+
initialConfiguration.videoCapabilities?.map((v) => v.contentType) ?? [];
|
|
332
|
+
const testedCodecs: string[] = testedAudioCodecs
|
|
333
|
+
.concat(testedVideoCodecs)
|
|
334
|
+
.filter((c): c is string => c !== undefined);
|
|
306
335
|
const supportedVideoCodecs = mksConfiguration.videoCapabilities?.map(
|
|
307
336
|
(entry) => entry.contentType,
|
|
308
337
|
);
|
|
@@ -368,6 +397,7 @@ export default function getMediaKeySystemAccess(
|
|
|
368
397
|
// one as exactly the same compatibility options.
|
|
369
398
|
const cachedKeySystemAccess = checkCachedMediaKeySystemAccess(
|
|
370
399
|
keySystemsConfigs,
|
|
400
|
+
currentState.askedConfiguration,
|
|
371
401
|
currentState.mediaKeySystemAccess,
|
|
372
402
|
currentState.keySystemOptions,
|
|
373
403
|
);
|
|
@@ -377,10 +407,10 @@ export default function getMediaKeySystemAccess(
|
|
|
377
407
|
type: "reuse-media-key-system-access" as const,
|
|
378
408
|
value: {
|
|
379
409
|
mediaKeySystemAccess: cachedKeySystemAccess.keySystemAccess,
|
|
410
|
+
askedConfiguration: cachedKeySystemAccess.askedConfiguration,
|
|
380
411
|
options: cachedKeySystemAccess.keySystemOptions,
|
|
381
412
|
codecSupport: extractCodecSupportListFromConfiguration(
|
|
382
|
-
cachedKeySystemAccess.
|
|
383
|
-
cachedKeySystemAccess.keySystemOptions.videoCapabilitiesConfig,
|
|
413
|
+
cachedKeySystemAccess.askedConfiguration,
|
|
384
414
|
cachedKeySystemAccess.keySystemAccess.getConfiguration(),
|
|
385
415
|
),
|
|
386
416
|
},
|
|
@@ -458,30 +488,35 @@ export default function getMediaKeySystemAccess(
|
|
|
458
488
|
`${index + 1} of ${keySystemsType.length}`,
|
|
459
489
|
);
|
|
460
490
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
keySystemOptions
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
491
|
+
let keySystemAccess;
|
|
492
|
+
for (let configIdx = 0; configIdx < keySystemConfigurations.length; configIdx++) {
|
|
493
|
+
const keySystemConfiguration = keySystemConfigurations[configIdx];
|
|
494
|
+
try {
|
|
495
|
+
keySystemAccess = await testKeySystem(keyType, [keySystemConfiguration]);
|
|
496
|
+
log.info("DRM: Found compatible keysystem", keyType, index + 1);
|
|
497
|
+
return {
|
|
498
|
+
type: "create-media-key-system-access" as const,
|
|
499
|
+
value: {
|
|
500
|
+
options: keySystemOptions,
|
|
501
|
+
mediaKeySystemAccess: keySystemAccess,
|
|
502
|
+
askedConfiguration: keySystemConfiguration,
|
|
503
|
+
codecSupport: extractCodecSupportListFromConfiguration(
|
|
504
|
+
keySystemConfiguration,
|
|
505
|
+
keySystemAccess.getConfiguration(),
|
|
506
|
+
),
|
|
507
|
+
},
|
|
508
|
+
};
|
|
509
|
+
} catch (_) {
|
|
510
|
+
log.debug("DRM: Rejected access to keysystem", keyType, index + 1, configIdx);
|
|
511
|
+
if (cancelSignal.cancellationError !== null) {
|
|
512
|
+
throw cancelSignal.cancellationError;
|
|
513
|
+
}
|
|
480
514
|
}
|
|
481
|
-
return recursivelyTestKeySystems(index + 1);
|
|
482
515
|
}
|
|
516
|
+
return recursivelyTestKeySystems(index + 1);
|
|
483
517
|
}
|
|
484
518
|
}
|
|
519
|
+
|
|
485
520
|
/**
|
|
486
521
|
* Test a key system configuration, resolves with the MediaKeySystemAccess
|
|
487
522
|
* 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.
|