rx-player 4.2.0-dev.2024081300 → 4.2.0-dev.2024081301
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/compat/eme/custom_media_keys/types.d.ts +0 -3
- package/dist/commonjs/compat/eme/custom_media_keys/types.d.ts.map +1 -1
- package/dist/commonjs/compat/eme/eme-api-implementation.d.ts +2 -2
- package/dist/commonjs/compat/eme/eme-api-implementation.d.ts.map +1 -1
- package/dist/commonjs/compat/eme/eme-api-implementation.js +2 -17
- package/dist/commonjs/compat/eme/get_init_data.d.ts +1 -3
- package/dist/commonjs/compat/eme/get_init_data.d.ts.map +1 -1
- package/dist/commonjs/compat/eme/get_init_data.js +2 -2
- package/dist/commonjs/compat/event_listeners.d.ts +19 -21
- package/dist/commonjs/compat/event_listeners.d.ts.map +1 -1
- package/dist/commonjs/compat/event_listeners.js +11 -0
- package/dist/commonjs/main_thread/api/public_api.js +2 -2
- package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts +0 -8
- package/dist/commonjs/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
- package/dist/commonjs/main_thread/decrypt/content_decryptor.js +0 -49
- package/dist/commonjs/main_thread/decrypt/types.d.ts +0 -1
- package/dist/commonjs/main_thread/decrypt/types.d.ts.map +1 -1
- package/dist/es2017/compat/eme/custom_media_keys/types.d.ts +0 -3
- package/dist/es2017/compat/eme/custom_media_keys/types.d.ts.map +1 -1
- package/dist/es2017/compat/eme/eme-api-implementation.d.ts +2 -2
- package/dist/es2017/compat/eme/eme-api-implementation.d.ts.map +1 -1
- package/dist/es2017/compat/eme/eme-api-implementation.js +2 -17
- package/dist/es2017/compat/eme/get_init_data.d.ts +1 -3
- package/dist/es2017/compat/eme/get_init_data.d.ts.map +1 -1
- package/dist/es2017/compat/eme/get_init_data.js +2 -2
- package/dist/es2017/compat/event_listeners.d.ts +19 -21
- package/dist/es2017/compat/event_listeners.d.ts.map +1 -1
- package/dist/es2017/compat/event_listeners.js +11 -0
- package/dist/es2017/main_thread/api/public_api.js +2 -2
- package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts +0 -8
- package/dist/es2017/main_thread/decrypt/content_decryptor.d.ts.map +1 -1
- package/dist/es2017/main_thread/decrypt/content_decryptor.js +0 -45
- package/dist/es2017/main_thread/decrypt/types.d.ts +0 -1
- package/dist/es2017/main_thread/decrypt/types.d.ts.map +1 -1
- package/dist/rx-player.js +18 -18
- package/package.json +1 -1
- package/src/compat/eme/custom_media_keys/types.ts +0 -4
- package/src/compat/eme/eme-api-implementation.ts +4 -36
- package/src/compat/eme/get_init_data.ts +3 -5
- package/src/compat/event_listeners.ts +5 -30
- package/src/main_thread/api/public_api.ts +2 -2
- package/src/main_thread/decrypt/content_decryptor.ts +1 -58
- package/src/main_thread/decrypt/types.ts +0 -2
package/package.json
CHANGED
|
@@ -3,7 +3,6 @@ import assert from "../../utils/assert";
|
|
|
3
3
|
import globalScope from "../../utils/global_scope";
|
|
4
4
|
import isNode from "../../utils/is_node";
|
|
5
5
|
import isNullOrUndefined from "../../utils/is_null_or_undefined";
|
|
6
|
-
import objectAssign from "../../utils/object_assign";
|
|
7
6
|
import type { CancellationSignal } from "../../utils/task_canceller";
|
|
8
7
|
import type { IMediaElement } from "../browser_compatibility_types";
|
|
9
8
|
import { isIE11 } from "../browser_detection";
|
|
@@ -20,10 +19,7 @@ import getMozMediaKeysCallbacks, {
|
|
|
20
19
|
import getOldKitWebKitMediaKeyCallbacks, {
|
|
21
20
|
isOldWebkitMediaElement,
|
|
22
21
|
} from "./custom_media_keys/old_webkit_media_keys";
|
|
23
|
-
import type {
|
|
24
|
-
ICustomMediaEncryptedEvent,
|
|
25
|
-
ICustomMediaKeys,
|
|
26
|
-
} from "./custom_media_keys/types";
|
|
22
|
+
import type { ICustomMediaKeys } from "./custom_media_keys/types";
|
|
27
23
|
import getWebKitMediaKeysCallbacks from "./custom_media_keys/webkit_media_keys";
|
|
28
24
|
import { WebKitMediaKeysConstructor } from "./custom_media_keys/webkit_media_keys_constructor";
|
|
29
25
|
|
|
@@ -67,7 +63,7 @@ export interface IEmeApiImplementation {
|
|
|
67
63
|
*/
|
|
68
64
|
onEncrypted: (
|
|
69
65
|
target: IEventTargetLike,
|
|
70
|
-
listener: (evt:
|
|
66
|
+
listener: (evt: unknown) => void,
|
|
71
67
|
cancelSignal: CancellationSignal,
|
|
72
68
|
) => void;
|
|
73
69
|
|
|
@@ -147,8 +143,8 @@ function getEmeApiImplementation(
|
|
|
147
143
|
let createCustomMediaKeys: (keyType: string) => ICustomMediaKeys;
|
|
148
144
|
|
|
149
145
|
if (preferredApiType === "webkit" && WebKitMediaKeysConstructor !== undefined) {
|
|
146
|
+
onEncrypted = createCompatibleEventListener(["needkey"]);
|
|
150
147
|
const callbacks = getWebKitMediaKeysCallbacks();
|
|
151
|
-
onEncrypted = createOnEncryptedForWebkit();
|
|
152
148
|
isTypeSupported = callbacks.isTypeSupported;
|
|
153
149
|
createCustomMediaKeys = callbacks.createCustomMediaKeys;
|
|
154
150
|
setMediaKeys = callbacks.setMediaKeys;
|
|
@@ -164,7 +160,7 @@ function getEmeApiImplementation(
|
|
|
164
160
|
implementation = "older-webkit";
|
|
165
161
|
// This is for WebKit with prefixed EME api
|
|
166
162
|
} else if (WebKitMediaKeysConstructor !== undefined) {
|
|
167
|
-
onEncrypted =
|
|
163
|
+
onEncrypted = createCompatibleEventListener(["needkey"]);
|
|
168
164
|
const callbacks = getWebKitMediaKeysCallbacks();
|
|
169
165
|
isTypeSupported = callbacks.isTypeSupported;
|
|
170
166
|
createCustomMediaKeys = callbacks.createCustomMediaKeys;
|
|
@@ -278,34 +274,6 @@ function getEmeApiImplementation(
|
|
|
278
274
|
implementation,
|
|
279
275
|
};
|
|
280
276
|
}
|
|
281
|
-
/**
|
|
282
|
-
* Create an event listener for the "webkitneedkey" event
|
|
283
|
-
* @returns
|
|
284
|
-
*/
|
|
285
|
-
function createOnEncryptedForWebkit(): IEmeApiImplementation["onEncrypted"] {
|
|
286
|
-
const compatibleEventListener = createCompatibleEventListener(
|
|
287
|
-
["needkey"],
|
|
288
|
-
undefined /* prefixes */,
|
|
289
|
-
);
|
|
290
|
-
const onEncrypted = (
|
|
291
|
-
target: IEventTargetLike,
|
|
292
|
-
listener: (event: ICustomMediaEncryptedEvent) => void,
|
|
293
|
-
cancelSignal: CancellationSignal,
|
|
294
|
-
) => {
|
|
295
|
-
compatibleEventListener(
|
|
296
|
-
target,
|
|
297
|
-
(event?: Event) => {
|
|
298
|
-
const patchedEvent = objectAssign(
|
|
299
|
-
{ forceSessionRecreation: true },
|
|
300
|
-
event as MediaEncryptedEvent,
|
|
301
|
-
);
|
|
302
|
-
listener(patchedEvent);
|
|
303
|
-
},
|
|
304
|
-
cancelSignal,
|
|
305
|
-
);
|
|
306
|
-
};
|
|
307
|
-
return onEncrypted;
|
|
308
|
-
}
|
|
309
277
|
|
|
310
278
|
/**
|
|
311
279
|
* Set the given MediaKeys on the given HTMLMediaElement.
|
|
@@ -20,7 +20,6 @@ import areArraysOfNumbersEqual from "../../utils/are_arrays_of_numbers_equal";
|
|
|
20
20
|
import { be4toi } from "../../utils/byte_parsing";
|
|
21
21
|
import isNullOrUndefined from "../../utils/is_null_or_undefined";
|
|
22
22
|
import { PSSH_TO_INTEGER } from "./constants";
|
|
23
|
-
import type { ICustomMediaEncryptedEvent } from "./custom_media_keys/types";
|
|
24
23
|
|
|
25
24
|
/** Data recuperated from parsing the payload of an `encrypted` event. */
|
|
26
25
|
export interface IEncryptedEventData {
|
|
@@ -51,7 +50,6 @@ export interface IEncryptedEventData {
|
|
|
51
50
|
*/
|
|
52
51
|
data: Uint8Array;
|
|
53
52
|
}>;
|
|
54
|
-
forceSessionRecreation?: boolean | undefined;
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
/**
|
|
@@ -147,9 +145,9 @@ function isPSSHAlreadyEncountered(
|
|
|
147
145
|
* encountered in the given event.
|
|
148
146
|
*/
|
|
149
147
|
export default function getInitData(
|
|
150
|
-
encryptedEvent:
|
|
148
|
+
encryptedEvent: MediaEncryptedEvent,
|
|
151
149
|
): IEncryptedEventData | null {
|
|
152
|
-
const { initData, initDataType
|
|
150
|
+
const { initData, initDataType } = encryptedEvent;
|
|
153
151
|
if (isNullOrUndefined(initData)) {
|
|
154
152
|
log.warn("Compat: No init data found on media encrypted event.");
|
|
155
153
|
return null;
|
|
@@ -157,5 +155,5 @@ export default function getInitData(
|
|
|
157
155
|
|
|
158
156
|
const initDataBytes = new Uint8Array(initData);
|
|
159
157
|
const values = getInitializationDataValues(initDataBytes);
|
|
160
|
-
return { type: initDataType, values
|
|
158
|
+
return { type: initDataType, values };
|
|
161
159
|
}
|
|
@@ -30,7 +30,6 @@ import type {
|
|
|
30
30
|
IEventTarget,
|
|
31
31
|
IMediaElement,
|
|
32
32
|
} from "./browser_compatibility_types";
|
|
33
|
-
import type { ICustomMediaEncryptedEvent } from "./eme/custom_media_keys/types";
|
|
34
33
|
|
|
35
34
|
const BROWSER_PREFIXES = ["", "webkit", "moz", "ms"];
|
|
36
35
|
|
|
@@ -83,14 +82,8 @@ function eventPrefixed(eventNames: string[], prefixes?: string[]): string[] {
|
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
export interface IEventEmitterLike {
|
|
86
|
-
addEventListener: (
|
|
87
|
-
|
|
88
|
-
handler: EventListenerOrEventListenerObject,
|
|
89
|
-
) => void;
|
|
90
|
-
removeEventListener: (
|
|
91
|
-
eventName: string,
|
|
92
|
-
handler: EventListenerOrEventListenerObject,
|
|
93
|
-
) => void;
|
|
85
|
+
addEventListener: (eventName: string, handler: () => void) => void;
|
|
86
|
+
removeEventListener: (eventName: string, handler: () => void) => void;
|
|
94
87
|
}
|
|
95
88
|
|
|
96
89
|
export type IEventTargetLike = HTMLElement | IEventEmitterLike | IEventEmitter<unknown>;
|
|
@@ -106,31 +99,12 @@ export type IEventTargetLike = HTMLElement | IEventEmitterLike | IEventEmitter<u
|
|
|
106
99
|
* @returns {Function} - Returns function allowing to easily add a callback to
|
|
107
100
|
* be triggered when that event is emitted on a given event target.
|
|
108
101
|
*/
|
|
109
|
-
|
|
110
|
-
function createCompatibleEventListener(
|
|
111
|
-
eventNames: Array<"needkey" | "encrypted">,
|
|
112
|
-
prefixes?: string[],
|
|
113
|
-
): (
|
|
114
|
-
element: IEventTargetLike,
|
|
115
|
-
listener: (event: ICustomMediaEncryptedEvent) => void,
|
|
116
|
-
cancelSignal: CancellationSignal,
|
|
117
|
-
) => void;
|
|
118
|
-
|
|
119
102
|
function createCompatibleEventListener(
|
|
120
103
|
eventNames: string[],
|
|
121
104
|
prefixes?: string[],
|
|
122
105
|
): (
|
|
123
106
|
element: IEventTargetLike,
|
|
124
|
-
listener: (event?:
|
|
125
|
-
cancelSignal: CancellationSignal,
|
|
126
|
-
) => void;
|
|
127
|
-
|
|
128
|
-
function createCompatibleEventListener(
|
|
129
|
-
eventNames: string[] | Array<"needkey" | "encrypted">,
|
|
130
|
-
prefixes?: string[],
|
|
131
|
-
): (
|
|
132
|
-
element: IEventTargetLike,
|
|
133
|
-
listener: (event?: Event | MediaEncryptedEvent) => void,
|
|
107
|
+
listener: (event?: unknown) => void,
|
|
134
108
|
cancelSignal: CancellationSignal,
|
|
135
109
|
) => void {
|
|
136
110
|
let mem: string | undefined;
|
|
@@ -138,12 +112,13 @@ function createCompatibleEventListener(
|
|
|
138
112
|
|
|
139
113
|
return (
|
|
140
114
|
element: IEventTargetLike,
|
|
141
|
-
listener: (event?:
|
|
115
|
+
listener: (event?: unknown) => void,
|
|
142
116
|
cancelSignal: CancellationSignal,
|
|
143
117
|
) => {
|
|
144
118
|
if (cancelSignal.isCancelled()) {
|
|
145
119
|
return;
|
|
146
120
|
}
|
|
121
|
+
|
|
147
122
|
// if the element is a HTMLElement we can detect
|
|
148
123
|
// the supported event, and memoize it in `mem`
|
|
149
124
|
if (typeof HTMLElement !== "undefined" && element instanceof HTMLElement) {
|
|
@@ -409,7 +409,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
409
409
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
410
410
|
videoElement.preload = "auto";
|
|
411
411
|
|
|
412
|
-
this.version = /* PLAYER_VERSION */ "4.2.0-dev.
|
|
412
|
+
this.version = /* PLAYER_VERSION */ "4.2.0-dev.2024081301";
|
|
413
413
|
this.log = log;
|
|
414
414
|
this.state = "STOPPED";
|
|
415
415
|
this.videoElement = videoElement;
|
|
@@ -3235,7 +3235,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
3235
3235
|
}
|
|
3236
3236
|
}
|
|
3237
3237
|
}
|
|
3238
|
-
Player.version = /* PLAYER_VERSION */ "4.2.0-dev.
|
|
3238
|
+
Player.version = /* PLAYER_VERSION */ "4.2.0-dev.2024081301";
|
|
3239
3239
|
|
|
3240
3240
|
/** Every events sent by the RxPlayer's public API. */
|
|
3241
3241
|
interface IPublicAPIEvent {
|
|
@@ -177,7 +177,7 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
|
|
|
177
177
|
mediaElement,
|
|
178
178
|
(evt) => {
|
|
179
179
|
log.debug("DRM: Encrypted event received from media element.");
|
|
180
|
-
const initData = getInitData(evt);
|
|
180
|
+
const initData = getInitData(evt as MediaEncryptedEvent);
|
|
181
181
|
if (initData !== null) {
|
|
182
182
|
this.onInitializationData(initData);
|
|
183
183
|
}
|
|
@@ -730,21 +730,6 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
|
|
|
730
730
|
return false;
|
|
731
731
|
}
|
|
732
732
|
|
|
733
|
-
/**
|
|
734
|
-
* On Safari using Directfile, the old EME implementation triggers
|
|
735
|
-
* the "webkitneedkey" event instead of "encrypted". There's an issue in Safari
|
|
736
|
-
* where "webkitneedkey" fires too early before all tracks are added from an HLS playlist.
|
|
737
|
-
* Safari incorrectly assumes some keys are missing for these tracks,
|
|
738
|
-
* leading to repeated "webkitneedkey" events. Because RxPlayer recognizes
|
|
739
|
-
* it already has a session for these keys and ignores the events,
|
|
740
|
-
* the content remains frozen. To resolve this, the session is re-created.
|
|
741
|
-
*/
|
|
742
|
-
const forceSessionRecreation = initializationData.forceSessionRecreation;
|
|
743
|
-
if (forceSessionRecreation === true) {
|
|
744
|
-
this.removeSessionForInitData(initializationData, mediaKeysData);
|
|
745
|
-
return false;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
733
|
// Check if the compatible session is blacklisted
|
|
749
734
|
const blacklistedSessionError = compatibleSessionInfo.blacklistedSessionError;
|
|
750
735
|
if (!isNullOrUndefined(blacklistedSessionError)) {
|
|
@@ -849,48 +834,6 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
|
|
|
849
834
|
return false;
|
|
850
835
|
}
|
|
851
836
|
|
|
852
|
-
/**
|
|
853
|
-
* Remove the session corresponding to the initData provided, and close it.
|
|
854
|
-
* It does nothing if no session was found for this initData.
|
|
855
|
-
* @param {Object} initData : The initialization data corresponding to the session
|
|
856
|
-
* that need to be removed
|
|
857
|
-
* @param {Object} mediaKeysData : The media keys data
|
|
858
|
-
*/
|
|
859
|
-
private removeSessionForInitData(
|
|
860
|
-
initData: IProcessedProtectionData,
|
|
861
|
-
mediaKeysData: IAttachedMediaKeysData,
|
|
862
|
-
) {
|
|
863
|
-
const { stores } = mediaKeysData;
|
|
864
|
-
/** Remove the session and close it from the loadedSessionStore */
|
|
865
|
-
const entry = stores.loadedSessionsStore.reuse(initData);
|
|
866
|
-
if (entry !== null) {
|
|
867
|
-
stores.loadedSessionsStore
|
|
868
|
-
.closeSession(entry.mediaKeySession)
|
|
869
|
-
.catch(() =>
|
|
870
|
-
log.error("DRM: Cannot close the session from the loaded session store"),
|
|
871
|
-
);
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* If set, a currently-used key session is already compatible to this
|
|
876
|
-
* initialization data.
|
|
877
|
-
*/
|
|
878
|
-
const compatibleSessionInfo = arrayFind(this._currentSessions, (x) =>
|
|
879
|
-
x.record.isCompatibleWith(initData),
|
|
880
|
-
);
|
|
881
|
-
if (compatibleSessionInfo === undefined) {
|
|
882
|
-
return;
|
|
883
|
-
}
|
|
884
|
-
/** Remove the session from the currentSessions */
|
|
885
|
-
const indexOf = this._currentSessions.indexOf(compatibleSessionInfo);
|
|
886
|
-
if (indexOf !== -1) {
|
|
887
|
-
log.debug(
|
|
888
|
-
"DRM: A session from a processed init is removed due to forceSessionRecreation policy.",
|
|
889
|
-
);
|
|
890
|
-
this._currentSessions.splice(indexOf, 1);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
|
|
894
837
|
/**
|
|
895
838
|
* Callback that should be called if an error that made the current
|
|
896
839
|
* `ContentDecryptor` instance unusable arised.
|
|
@@ -122,8 +122,6 @@ export interface IProtectionData {
|
|
|
122
122
|
content?: IContent;
|
|
123
123
|
/** Every initialization data for that type. */
|
|
124
124
|
values: IInitDataValue[];
|
|
125
|
-
|
|
126
|
-
forceSessionRecreation?: boolean | undefined;
|
|
127
125
|
}
|
|
128
126
|
|
|
129
127
|
/** Protection initialization data actually processed by the `ContentDecryptor`. */
|