rx-player 3.27.0-dev.2022032100 → 3.27.0
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/CHANGELOG.md +5 -2
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +15 -11
- package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +22 -6
- package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +4 -6
- package/dist/_esm5.processed/compat/eme/generate_key_request.js +4 -6
- package/dist/_esm5.processed/compat/get_start_date.d.ts +30 -0
- package/dist/_esm5.processed/compat/get_start_date.js +44 -0
- package/dist/_esm5.processed/compat/index.d.ts +2 -1
- package/dist/_esm5.processed/compat/index.js +2 -1
- package/dist/_esm5.processed/config.d.ts +1 -5
- package/dist/_esm5.processed/core/api/public_api.js +25 -25
- package/dist/_esm5.processed/core/decrypt/content_decryptor.js +11 -3
- package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +1 -1
- package/dist/_esm5.processed/core/decrypt/create_session.d.ts +3 -1
- package/dist/_esm5.processed/core/decrypt/create_session.js +15 -5
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +94 -1
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +237 -96
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +4 -1
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +2 -1
- package/dist/_esm5.processed/core/stream/period/period_stream.js +9 -3
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +4 -3
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +3 -2
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +9 -3
- package/dist/_esm5.processed/core/stream/representation/get_needed_segments.d.ts +11 -1
- package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +27 -45
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +6 -4
- package/dist/_esm5.processed/default_config.d.ts +2 -35
- package/dist/_esm5.processed/default_config.js +2 -35
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +39 -38
- package/dist/_esm5.processed/utils/reference.js +0 -2
- package/dist/_esm5.processed/utils/task_canceller.d.ts +8 -1
- package/dist/_esm5.processed/utils/task_canceller.js +9 -1
- package/dist/rx-player.js +927 -587
- package/dist/rx-player.min.js +1 -1
- package/package.json +1 -1
- package/sonar-project.properties +1 -1
- package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +16 -12
- package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +21 -8
- package/src/compat/eme/generate_key_request.ts +4 -6
- package/src/compat/get_start_date.ts +48 -0
- package/src/compat/index.ts +2 -0
- package/src/core/api/public_api.ts +23 -27
- package/src/core/decrypt/content_decryptor.ts +15 -4
- package/src/core/decrypt/create_or_load_session.ts +4 -1
- package/src/core/decrypt/create_session.ts +23 -9
- package/src/core/decrypt/utils/loaded_sessions_store.ts +254 -102
- package/src/core/segment_buffers/garbage_collector.ts +4 -0
- package/src/core/stream/orchestrator/stream_orchestrator.ts +2 -1
- package/src/core/stream/period/period_stream.ts +9 -4
- package/src/core/stream/representation/append_segment_to_buffer.ts +17 -13
- package/src/core/stream/representation/force_garbage_collection.ts +4 -1
- package/src/core/stream/representation/get_buffer_status.ts +21 -13
- package/src/core/stream/representation/get_needed_segments.ts +40 -55
- package/src/core/stream/representation/representation_stream.ts +6 -4
- package/src/default_config.ts +20 -57
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +41 -44
- package/src/utils/reference.ts +0 -2
- package/src/utils/task_canceller.ts +16 -1
package/package.json
CHANGED
package/sonar-project.properties
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
sonar.projectKey=rx-player
|
|
2
2
|
sonar.organization=rx-player
|
|
3
3
|
sonar.projectName=rx-player
|
|
4
|
-
sonar.projectVersion=3.27.0
|
|
4
|
+
sonar.projectVersion=3.27.0
|
|
5
5
|
sonar.sources=./src,./demo,./tests
|
|
6
6
|
sonar.exclusions=demo/full/bundle.js,demo/standalone/lib.js,demo/bundle.js
|
|
7
7
|
sonar.host.url=https://sonarcloud.io
|
|
@@ -66,7 +66,6 @@ class OldWebkitMediaKeySession
|
|
|
66
66
|
private readonly _vid: IOldWebkitHTMLMediaElement;
|
|
67
67
|
private readonly _key: string;
|
|
68
68
|
|
|
69
|
-
private readonly _onSessionRelatedEvent : (evt : Event) => void;
|
|
70
69
|
private _closeSession : () => void;
|
|
71
70
|
|
|
72
71
|
constructor(mediaElement: IOldWebkitHTMLMediaElement, keySystem: string) {
|
|
@@ -76,18 +75,29 @@ class OldWebkitMediaKeySession
|
|
|
76
75
|
|
|
77
76
|
this.sessionId = "";
|
|
78
77
|
this._closeSession = noop; // Just here to make TypeScript happy
|
|
79
|
-
this.closed = new Promise((resolve) => {
|
|
80
|
-
this._closeSession = resolve;
|
|
81
|
-
});
|
|
82
78
|
this.keyStatuses = new Map();
|
|
83
79
|
this.expiration = NaN;
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
const onSessionRelatedEvent = (evt : Event) => {
|
|
86
82
|
this.trigger(evt.type, evt);
|
|
87
83
|
};
|
|
84
|
+
this.closed = new Promise((resolve) => {
|
|
85
|
+
this._closeSession = () => {
|
|
86
|
+
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
87
|
+
.forEach(evt => {
|
|
88
|
+
mediaElement.removeEventListener(evt, onSessionRelatedEvent);
|
|
89
|
+
mediaElement.removeEventListener(`webkit${evt}`, onSessionRelatedEvent);
|
|
90
|
+
});
|
|
91
|
+
resolve();
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
|
|
88
95
|
|
|
89
96
|
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
90
|
-
.forEach(evt =>
|
|
97
|
+
.forEach(evt => {
|
|
98
|
+
mediaElement.addEventListener(evt, onSessionRelatedEvent);
|
|
99
|
+
mediaElement.addEventListener(`webkit${evt}`, onSessionRelatedEvent);
|
|
100
|
+
});
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
public update(license: Uint8Array) : Promise<void> {
|
|
@@ -128,7 +138,6 @@ class OldWebkitMediaKeySession
|
|
|
128
138
|
|
|
129
139
|
public close(): Promise<void> {
|
|
130
140
|
return new Promise((resolve) => {
|
|
131
|
-
this._unbindSession();
|
|
132
141
|
this._closeSession();
|
|
133
142
|
resolve();
|
|
134
143
|
});
|
|
@@ -147,11 +156,6 @@ class OldWebkitMediaKeySession
|
|
|
147
156
|
public remove(): Promise<void> {
|
|
148
157
|
return Promise.resolve();
|
|
149
158
|
}
|
|
150
|
-
|
|
151
|
-
private _unbindSession() {
|
|
152
|
-
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
153
|
-
.forEach(evt => this._vid.removeEventListener(evt, this._onSessionRelatedEvent));
|
|
154
|
-
}
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
class OldWebKitCustomMediaKeys implements ICustomMediaKeys {
|
|
@@ -83,7 +83,6 @@ class WebkitMediaKeySession
|
|
|
83
83
|
private _nativeSession: undefined | MediaKeySession;
|
|
84
84
|
private _serverCertificate: Uint8Array | undefined;
|
|
85
85
|
|
|
86
|
-
private readonly _onEvent : (evt : Event) => void;
|
|
87
86
|
private _closeSession : () => void;
|
|
88
87
|
private _unbindSession : () => void;
|
|
89
88
|
|
|
@@ -109,10 +108,6 @@ class WebkitMediaKeySession
|
|
|
109
108
|
});
|
|
110
109
|
this.keyStatuses = new Map();
|
|
111
110
|
this.expiration = NaN;
|
|
112
|
-
|
|
113
|
-
this._onEvent = (evt : Event) => {
|
|
114
|
-
this.trigger(evt.type, evt);
|
|
115
|
-
};
|
|
116
111
|
}
|
|
117
112
|
|
|
118
113
|
public update(license: BufferSource) : Promise<void> {
|
|
@@ -124,9 +119,17 @@ class WebkitMediaKeySession
|
|
|
124
119
|
return reject("Unavailable WebKit key session.");
|
|
125
120
|
}
|
|
126
121
|
try {
|
|
122
|
+
let uInt8Arraylicense: Uint8Array;
|
|
123
|
+
if (license instanceof ArrayBuffer) {
|
|
124
|
+
uInt8Arraylicense = new Uint8Array(license);
|
|
125
|
+
} else if (license instanceof Uint8Array) {
|
|
126
|
+
uInt8Arraylicense = license;
|
|
127
|
+
} else {
|
|
128
|
+
uInt8Arraylicense = new Uint8Array(license.buffer);
|
|
129
|
+
}
|
|
127
130
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
128
131
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
129
|
-
resolve(this._nativeSession.update(
|
|
132
|
+
resolve(this._nativeSession.update(uInt8Arraylicense));
|
|
130
133
|
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
131
134
|
} catch (err) {
|
|
132
135
|
reject(err);
|
|
@@ -202,15 +205,25 @@ class WebkitMediaKeySession
|
|
|
202
205
|
private _listenEvent(session: MediaKeySession) : void {
|
|
203
206
|
this._unbindSession(); // If previous session was linked
|
|
204
207
|
|
|
208
|
+
const onEvent = (evt : Event) => {
|
|
209
|
+
this.trigger(evt.type, evt);
|
|
210
|
+
};
|
|
211
|
+
|
|
205
212
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
206
213
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
207
214
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
208
215
|
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
209
|
-
.forEach(evt =>
|
|
216
|
+
.forEach(evt => {
|
|
217
|
+
session.addEventListener(evt, onEvent);
|
|
218
|
+
session.addEventListener(`webkit${evt}`, onEvent);
|
|
219
|
+
});
|
|
210
220
|
|
|
211
221
|
this._unbindSession = () => {
|
|
212
222
|
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
213
|
-
.forEach(evt =>
|
|
223
|
+
.forEach(evt => {
|
|
224
|
+
session.removeEventListener(evt, onEvent);
|
|
225
|
+
session.removeEventListener(`webkit${evt}`, onEvent);
|
|
226
|
+
});
|
|
214
227
|
};
|
|
215
228
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
216
229
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
@@ -124,12 +124,10 @@ export function patchInitData(initData : Uint8Array) : Uint8Array {
|
|
|
124
124
|
* Generate a request from session.
|
|
125
125
|
* @param {MediaKeySession} session - MediaKeySession on which the request will
|
|
126
126
|
* be done.
|
|
127
|
-
* @param {
|
|
128
|
-
* "encrypted" event for the corresponding request.
|
|
129
|
-
* @param {
|
|
130
|
-
* "encrypted" event for the corresponding request.
|
|
131
|
-
* @param {string} sessionType - Type of session you want to generate. Consult
|
|
132
|
-
* EME Specification for more information on session types.
|
|
127
|
+
* @param {string} initializationDataType - Initialization data type given e.g.
|
|
128
|
+
* by the "encrypted" event for the corresponding request.
|
|
129
|
+
* @param {Uint8Array} initializationData - Initialization data given e.g. by
|
|
130
|
+
* the "encrypted" event for the corresponding request.
|
|
133
131
|
* @returns {Promise} - Emit when done. Errors if fails.
|
|
134
132
|
*/
|
|
135
133
|
export default function generateKeyRequest(
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2015 CANAL+ Group
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Calculating a live-offseted media position necessitate to obtain first an
|
|
19
|
+
* offset, and then adding that offset to the wanted position.
|
|
20
|
+
*
|
|
21
|
+
* That offset is in most case present inside the Manifest file, yet in cases
|
|
22
|
+
* without it or without a Manifest, such as the "directfile" mode, the RxPlayer
|
|
23
|
+
* won't know that offset.
|
|
24
|
+
*
|
|
25
|
+
* Thankfully Safari declares a `getStartDate` method allowing to obtain that
|
|
26
|
+
* offset when available. This logic is mainly useful when playing HLS contents
|
|
27
|
+
* in directfile mode on Safari.
|
|
28
|
+
* @param {HTMLMediaElement} mediaElement
|
|
29
|
+
* @returns {number|undefined}
|
|
30
|
+
*/
|
|
31
|
+
export default function getStartDate(
|
|
32
|
+
mediaElement : HTMLMediaElement
|
|
33
|
+
) : number | undefined {
|
|
34
|
+
const _mediaElement : HTMLMediaElement & {
|
|
35
|
+
getStartDate? : () => number | Date | null | undefined;
|
|
36
|
+
} = mediaElement;
|
|
37
|
+
if (typeof _mediaElement.getStartDate === "function") {
|
|
38
|
+
const startDate = _mediaElement.getStartDate();
|
|
39
|
+
if (typeof startDate === "object" && startDate !== null) {
|
|
40
|
+
const startDateNum = +startDate;
|
|
41
|
+
if (!isNaN(startDateNum)) {
|
|
42
|
+
return startDateNum / 1000;
|
|
43
|
+
}
|
|
44
|
+
} else if (typeof startDate === "number" && !isNaN(startDate)) {
|
|
45
|
+
return startDate;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/compat/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
isFullscreen,
|
|
45
45
|
requestFullscreen,
|
|
46
46
|
} from "./fullscreen";
|
|
47
|
+
import getStartDate from "./get_start_date";
|
|
47
48
|
import hasEMEAPIs from "./has_eme_apis";
|
|
48
49
|
import isCodecSupported from "./is_codec_supported";
|
|
49
50
|
import isNode from "./is_node";
|
|
@@ -79,6 +80,7 @@ export {
|
|
|
79
80
|
exitFullscreen,
|
|
80
81
|
generateKeyRequest,
|
|
81
82
|
getInitData,
|
|
83
|
+
getStartDate,
|
|
82
84
|
hasEMEAPIs,
|
|
83
85
|
ICompatTextTrack,
|
|
84
86
|
ICompatVTTCue,
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
import {
|
|
47
47
|
events,
|
|
48
48
|
exitFullscreen,
|
|
49
|
+
getStartDate,
|
|
49
50
|
isFullscreen,
|
|
50
51
|
requestFullscreen,
|
|
51
52
|
} from "../../compat";
|
|
@@ -427,7 +428,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
427
428
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
428
429
|
videoElement.preload = "auto";
|
|
429
430
|
|
|
430
|
-
this.version = /* PLAYER_VERSION */"3.27.0
|
|
431
|
+
this.version = /* PLAYER_VERSION */"3.27.0";
|
|
431
432
|
this.log = log;
|
|
432
433
|
this.state = "STOPPED";
|
|
433
434
|
this.videoElement = videoElement;
|
|
@@ -1276,24 +1277,8 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
1276
1277
|
|
|
1277
1278
|
const { isDirectFile, manifest } = this._priv_contentInfos;
|
|
1278
1279
|
if (isDirectFile) {
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
// That offset is in most case present inside the Manifest file, yet in
|
|
1282
|
-
// directfile mode, the RxPlayer won't parse that file, the browser does it.
|
|
1283
|
-
//
|
|
1284
|
-
// Thankfully Safari declares a `getStartDate` method allowing to obtain
|
|
1285
|
-
// that offset when available. This logic is thus mainly useful when
|
|
1286
|
-
// playing HLS contents in directfile mode on Safari.
|
|
1287
|
-
const mediaElement : HTMLMediaElement & {
|
|
1288
|
-
getStartDate? : () => number | null | undefined;
|
|
1289
|
-
} = this.videoElement;
|
|
1290
|
-
if (typeof mediaElement.getStartDate === "function") {
|
|
1291
|
-
const startDate = mediaElement.getStartDate();
|
|
1292
|
-
if (typeof startDate === "number" && !isNaN(startDate)) {
|
|
1293
|
-
return startDate + mediaElement.currentTime;
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
return mediaElement.currentTime;
|
|
1280
|
+
const startDate = getStartDate(this.videoElement);
|
|
1281
|
+
return (startDate ?? 0) + this.videoElement.currentTime;
|
|
1297
1282
|
}
|
|
1298
1283
|
if (manifest !== null) {
|
|
1299
1284
|
const currentTime = this.videoElement.currentTime;
|
|
@@ -1596,12 +1581,19 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
1596
1581
|
} else if (!isNullOrUndefined(timeObj.position)) {
|
|
1597
1582
|
positionWanted = timeObj.position;
|
|
1598
1583
|
} else if (!isNullOrUndefined(timeObj.wallClockTime)) {
|
|
1599
|
-
|
|
1600
|
-
timeObj.wallClockTime
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1584
|
+
if (manifest !== null) {
|
|
1585
|
+
positionWanted = timeObj.wallClockTime - (
|
|
1586
|
+
manifest.availabilityStartTime ?? 0
|
|
1587
|
+
);
|
|
1588
|
+
} else if (isDirectFile && this.videoElement !== null) {
|
|
1589
|
+
const startDate = getStartDate(this.videoElement);
|
|
1590
|
+
if (startDate !== undefined) {
|
|
1591
|
+
positionWanted = timeObj.wallClockTime - startDate;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
if (positionWanted === undefined) {
|
|
1595
|
+
positionWanted = timeObj.wallClockTime;
|
|
1596
|
+
}
|
|
1605
1597
|
} else {
|
|
1606
1598
|
throw new Error("invalid time object. You must set one of the " +
|
|
1607
1599
|
"following properties: \"relative\", \"position\" or " +
|
|
@@ -2893,8 +2885,12 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
2893
2885
|
const ast = manifest.availabilityStartTime ?? 0;
|
|
2894
2886
|
positionData.wallClockTime = observation.position + ast;
|
|
2895
2887
|
positionData.liveGap = maximumPosition - observation.position;
|
|
2888
|
+
} else if (isDirectFile && this.videoElement !== null) {
|
|
2889
|
+
const startDate = getStartDate(this.videoElement);
|
|
2890
|
+
if (startDate !== undefined) {
|
|
2891
|
+
positionData.wallClockTime = startDate + observation.position;
|
|
2892
|
+
}
|
|
2896
2893
|
}
|
|
2897
|
-
|
|
2898
2894
|
this.trigger("positionUpdate", positionData);
|
|
2899
2895
|
}
|
|
2900
2896
|
|
|
@@ -2946,7 +2942,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
2946
2942
|
return activeRepresentations[currentPeriod.id];
|
|
2947
2943
|
}
|
|
2948
2944
|
}
|
|
2949
|
-
Player.version = /* PLAYER_VERSION */"3.27.0
|
|
2945
|
+
Player.version = /* PLAYER_VERSION */"3.27.0";
|
|
2950
2946
|
|
|
2951
2947
|
/** Payload emitted with a `positionUpdate` event. */
|
|
2952
2948
|
export interface IPositionUpdateItem {
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
18
|
events,
|
|
19
|
-
generateKeyRequest,
|
|
20
19
|
getInitData,
|
|
21
20
|
ICustomMediaKeys,
|
|
22
21
|
ICustomMediaKeySystemAccess,
|
|
@@ -567,10 +566,22 @@ export default class ContentDecryptor extends EventEmitter<IContentDecryptorEven
|
|
|
567
566
|
if (sessionRes.type === MediaKeySessionLoadingType.Created) {
|
|
568
567
|
const requestData = initializationData.values.constructRequestData();
|
|
569
568
|
try {
|
|
570
|
-
await
|
|
571
|
-
|
|
572
|
-
|
|
569
|
+
await stores.loadedSessionsStore.generateLicenseRequest(
|
|
570
|
+
mediaKeySession,
|
|
571
|
+
initializationData.type,
|
|
572
|
+
requestData);
|
|
573
573
|
} catch (error) {
|
|
574
|
+
// First check that the error was not due to the MediaKeySession closing
|
|
575
|
+
// or being closed
|
|
576
|
+
const entry = stores.loadedSessionsStore.getEntryForSession(mediaKeySession);
|
|
577
|
+
if (entry === null || entry.closingStatus.type !== "none") {
|
|
578
|
+
// MediaKeySession closing/closed: Just remove from handled list and abort.
|
|
579
|
+
const indexInCurrent = this._currentSessions.indexOf(sessionInfo);
|
|
580
|
+
if (indexInCurrent >= 0) {
|
|
581
|
+
this._currentSessions.splice(indexInCurrent, 1);
|
|
582
|
+
}
|
|
583
|
+
return Promise.resolve();
|
|
584
|
+
}
|
|
574
585
|
throw new EncryptedMediaError("KEY_GENERATE_REQUEST_ERROR",
|
|
575
586
|
error instanceof Error ? error.toString() :
|
|
576
587
|
"Unknown error");
|
|
@@ -88,7 +88,10 @@ export default async function createOrLoadSession(
|
|
|
88
88
|
throw cancelSignal.cancellationError; // stop here if cancelled since
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
const evt = await createSession(stores,
|
|
91
|
+
const evt = await createSession(stores,
|
|
92
|
+
initializationData,
|
|
93
|
+
wantedSessionType,
|
|
94
|
+
cancelSignal);
|
|
92
95
|
return { type: evt.type,
|
|
93
96
|
value: { mediaKeySession: evt.value.mediaKeySession,
|
|
94
97
|
sessionType: evt.value.sessionType,
|
|
@@ -14,11 +14,9 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
ICustomMediaKeySession,
|
|
19
|
-
loadSession,
|
|
20
|
-
} from "../../compat";
|
|
17
|
+
import { ICustomMediaKeySession } from "../../compat";
|
|
21
18
|
import log from "../../log";
|
|
19
|
+
import { CancellationSignal } from "../../utils/task_canceller";
|
|
22
20
|
import {
|
|
23
21
|
IProcessedProtectionData,
|
|
24
22
|
IMediaKeySessionStores,
|
|
@@ -42,12 +40,14 @@ import PersistentSessionsStore from "./utils/persistent_sessions_store";
|
|
|
42
40
|
* @param {Object} stores
|
|
43
41
|
* @param {Object} initData
|
|
44
42
|
* @param {string} wantedSessionType
|
|
43
|
+
* @param {Object} cancelSignal
|
|
45
44
|
* @returns {Promise}
|
|
46
45
|
*/
|
|
47
46
|
export default function createSession(
|
|
48
47
|
stores : IMediaKeySessionStores,
|
|
49
48
|
initData : IProcessedProtectionData,
|
|
50
|
-
wantedSessionType : MediaKeySessionType
|
|
49
|
+
wantedSessionType : MediaKeySessionType,
|
|
50
|
+
cancelSignal : CancellationSignal
|
|
51
51
|
) : Promise<ICreateSessionEvent> {
|
|
52
52
|
const { loadedSessionsStore,
|
|
53
53
|
persistentSessionsStore } = stores;
|
|
@@ -61,7 +61,8 @@ export default function createSession(
|
|
|
61
61
|
}
|
|
62
62
|
return createAndTryToRetrievePersistentSession(loadedSessionsStore,
|
|
63
63
|
persistentSessionsStore,
|
|
64
|
-
initData
|
|
64
|
+
initData,
|
|
65
|
+
cancelSignal);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/**
|
|
@@ -87,13 +88,18 @@ function createTemporarySession(
|
|
|
87
88
|
* @param {Object} loadedSessionsStore
|
|
88
89
|
* @param {Object} persistentSessionsStore
|
|
89
90
|
* @param {Object} initData
|
|
91
|
+
* @param {Object} cancelSignal
|
|
90
92
|
* @returns {Promise}
|
|
91
93
|
*/
|
|
92
94
|
async function createAndTryToRetrievePersistentSession(
|
|
93
95
|
loadedSessionsStore : LoadedSessionsStore,
|
|
94
96
|
persistentSessionsStore : PersistentSessionsStore,
|
|
95
|
-
initData : IProcessedProtectionData
|
|
97
|
+
initData : IProcessedProtectionData,
|
|
98
|
+
cancelSignal : CancellationSignal
|
|
96
99
|
) : Promise<INewSessionCreatedEvent | IPersistentSessionRecoveryEvent> {
|
|
100
|
+
if (cancelSignal.cancellationError !== null) {
|
|
101
|
+
throw cancelSignal.cancellationError;
|
|
102
|
+
}
|
|
97
103
|
log.info("DRM: Creating persistent MediaKeySession");
|
|
98
104
|
|
|
99
105
|
const entry = loadedSessionsStore.createSession(initData, "persistent-license");
|
|
@@ -104,8 +110,10 @@ async function createAndTryToRetrievePersistentSession(
|
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
try {
|
|
107
|
-
const hasLoadedSession = await
|
|
108
|
-
|
|
113
|
+
const hasLoadedSession = await loadedSessionsStore.loadPersistentSession(
|
|
114
|
+
entry.mediaKeySession,
|
|
115
|
+
storedEntry.sessionId
|
|
116
|
+
);
|
|
109
117
|
if (!hasLoadedSession) {
|
|
110
118
|
log.warn("DRM: No data stored for the loaded session");
|
|
111
119
|
persistentSessionsStore.delete(storedEntry.sessionId);
|
|
@@ -136,6 +144,9 @@ async function createAndTryToRetrievePersistentSession(
|
|
|
136
144
|
* @returns {Observable}
|
|
137
145
|
*/
|
|
138
146
|
async function recreatePersistentSession() : Promise<INewSessionCreatedEvent> {
|
|
147
|
+
if (cancelSignal.cancellationError !== null) {
|
|
148
|
+
throw cancelSignal.cancellationError;
|
|
149
|
+
}
|
|
139
150
|
log.info("DRM: Removing previous persistent session.");
|
|
140
151
|
const persistentEntry = persistentSessionsStore.get(initData);
|
|
141
152
|
if (persistentEntry !== null) {
|
|
@@ -143,6 +154,9 @@ async function createAndTryToRetrievePersistentSession(
|
|
|
143
154
|
}
|
|
144
155
|
|
|
145
156
|
await loadedSessionsStore.closeSession(entry.mediaKeySession);
|
|
157
|
+
if (cancelSignal.cancellationError !== null) {
|
|
158
|
+
throw cancelSignal.cancellationError;
|
|
159
|
+
}
|
|
146
160
|
const newEntry = loadedSessionsStore.createSession(initData,
|
|
147
161
|
"persistent-license");
|
|
148
162
|
return { type: MediaKeySessionLoadingType.Created,
|