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/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## v3.27.0
|
|
3
|
+
## v3.27.0 (2022-03-31)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
@@ -16,17 +16,20 @@
|
|
|
16
16
|
- avoid performing a small seek when changing the audio track [#1080]
|
|
17
17
|
- api: allow switching to RELOADING state synchronously after LOADED [#1083]
|
|
18
18
|
- Safari Mobile: Improve decryption support on Safari mobile by relying on the vendored `WebKitMediaKeys` API [#1072]
|
|
19
|
+
- DASH: Fix issue which prevented the integrity check of most MP4 DASH segments when `transportOptions.checkMediaSegmentIntegrity` was set to `true`
|
|
19
20
|
- avoid unnecessary warning logs when loading some initialization segments [#1049]
|
|
20
21
|
- TypeScript: Add forgotten TypeScript types in the exposed segment and manifest loader APIs [#1057]
|
|
21
22
|
- DRM: Avoid decryption issues when a license is persisted in a `singleLicensePer` `"init-data"` mode but loaded in a `"content"` mode [#1031, #1042]
|
|
23
|
+
- DRM: Totally avoid the theoretical possibility of leaking MediaKeySessions when a `generateRequest` or `load` call takes multiple seconds [#1093]
|
|
22
24
|
|
|
23
25
|
### Other improvements
|
|
24
26
|
|
|
25
27
|
- DASH: always consider that the non-last Period is finished when it contains SegmentTimeline elements [#1047]
|
|
26
28
|
- add better buffer cleaning logic on a browser's `QuotaExceededError` to better handle memory limitations [#1065]
|
|
27
29
|
- DASH: Prioritize selectionPriority attribute over a "main" Role when ordering AdaptationSets [#1082]
|
|
28
|
-
- directfile/Safari: use the `getStartDate` method in `getWallClockTime` when available to obtain true offseted times when playing HLS contents on Safari [#1055]
|
|
30
|
+
- directfile/Safari: use the `getStartDate` method in `getWallClockTime`, `seekTo` and the `positionUpdate` event when available to obtain true offseted "wall-clock" times when playing HLS contents on Safari [#1055]
|
|
29
31
|
- DRM: Improve DRM Session caches performance when `singleLicensePer` is set to `"content"`
|
|
32
|
+
- DRM: Stop retrying closing MediaKeySessions multiple times when it fails, instead doing it only once when it should work [#1093]
|
|
30
33
|
- TypeScript: Add IBitrateEstimate, IPositionUpdate and IPlayerState types to the exported types [#1084]
|
|
31
34
|
- Remove dependency on pinkie's promise ponyfill [#1058, #1090]
|
|
32
35
|
- tests: add performance tests, to better catch and avoid performance regressions [#1053, #1062]
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.27.0
|
|
1
|
+
3.27.0
|
|
@@ -56,16 +56,26 @@ var OldWebkitMediaKeySession = /** @class */ (function (_super) {
|
|
|
56
56
|
_this._key = keySystem;
|
|
57
57
|
_this.sessionId = "";
|
|
58
58
|
_this._closeSession = noop; // Just here to make TypeScript happy
|
|
59
|
-
_this.closed = new Promise(function (resolve) {
|
|
60
|
-
_this._closeSession = resolve;
|
|
61
|
-
});
|
|
62
59
|
_this.keyStatuses = new Map();
|
|
63
60
|
_this.expiration = NaN;
|
|
64
|
-
|
|
61
|
+
var onSessionRelatedEvent = function (evt) {
|
|
65
62
|
_this.trigger(evt.type, evt);
|
|
66
63
|
};
|
|
64
|
+
_this.closed = new Promise(function (resolve) {
|
|
65
|
+
_this._closeSession = function () {
|
|
66
|
+
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
67
|
+
.forEach(function (evt) {
|
|
68
|
+
mediaElement.removeEventListener(evt, onSessionRelatedEvent);
|
|
69
|
+
mediaElement.removeEventListener("webkit".concat(evt), onSessionRelatedEvent);
|
|
70
|
+
});
|
|
71
|
+
resolve();
|
|
72
|
+
};
|
|
73
|
+
});
|
|
67
74
|
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
68
|
-
.forEach(function (evt) {
|
|
75
|
+
.forEach(function (evt) {
|
|
76
|
+
mediaElement.addEventListener(evt, onSessionRelatedEvent);
|
|
77
|
+
mediaElement.addEventListener("webkit".concat(evt), onSessionRelatedEvent);
|
|
78
|
+
});
|
|
69
79
|
return _this;
|
|
70
80
|
}
|
|
71
81
|
OldWebkitMediaKeySession.prototype.update = function (license) {
|
|
@@ -105,7 +115,6 @@ var OldWebkitMediaKeySession = /** @class */ (function (_super) {
|
|
|
105
115
|
OldWebkitMediaKeySession.prototype.close = function () {
|
|
106
116
|
var _this = this;
|
|
107
117
|
return new Promise(function (resolve) {
|
|
108
|
-
_this._unbindSession();
|
|
109
118
|
_this._closeSession();
|
|
110
119
|
resolve();
|
|
111
120
|
});
|
|
@@ -122,11 +131,6 @@ var OldWebkitMediaKeySession = /** @class */ (function (_super) {
|
|
|
122
131
|
OldWebkitMediaKeySession.prototype.remove = function () {
|
|
123
132
|
return Promise.resolve();
|
|
124
133
|
};
|
|
125
|
-
OldWebkitMediaKeySession.prototype._unbindSession = function () {
|
|
126
|
-
var _this = this;
|
|
127
|
-
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
128
|
-
.forEach(function (evt) { return _this._vid.removeEventListener(evt, _this._onSessionRelatedEvent); });
|
|
129
|
-
};
|
|
130
134
|
return OldWebkitMediaKeySession;
|
|
131
135
|
}(EventEmitter));
|
|
132
136
|
var OldWebKitCustomMediaKeys = /** @class */ (function () {
|
|
@@ -81,9 +81,6 @@ var WebkitMediaKeySession = /** @class */ (function (_super) {
|
|
|
81
81
|
});
|
|
82
82
|
_this.keyStatuses = new Map();
|
|
83
83
|
_this.expiration = NaN;
|
|
84
|
-
_this._onEvent = function (evt) {
|
|
85
|
-
_this.trigger(evt.type, evt);
|
|
86
|
-
};
|
|
87
84
|
return _this;
|
|
88
85
|
}
|
|
89
86
|
WebkitMediaKeySession.prototype.update = function (license) {
|
|
@@ -96,9 +93,19 @@ var WebkitMediaKeySession = /** @class */ (function (_super) {
|
|
|
96
93
|
return reject("Unavailable WebKit key session.");
|
|
97
94
|
}
|
|
98
95
|
try {
|
|
96
|
+
var uInt8Arraylicense = void 0;
|
|
97
|
+
if (license instanceof ArrayBuffer) {
|
|
98
|
+
uInt8Arraylicense = new Uint8Array(license);
|
|
99
|
+
}
|
|
100
|
+
else if (license instanceof Uint8Array) {
|
|
101
|
+
uInt8Arraylicense = license;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
uInt8Arraylicense = new Uint8Array(license.buffer);
|
|
105
|
+
}
|
|
99
106
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
100
107
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
101
|
-
resolve(_this._nativeSession.update(
|
|
108
|
+
resolve(_this._nativeSession.update(uInt8Arraylicense));
|
|
102
109
|
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
103
110
|
}
|
|
104
111
|
catch (err) {
|
|
@@ -171,14 +178,23 @@ var WebkitMediaKeySession = /** @class */ (function (_super) {
|
|
|
171
178
|
WebkitMediaKeySession.prototype._listenEvent = function (session) {
|
|
172
179
|
var _this = this;
|
|
173
180
|
this._unbindSession(); // If previous session was linked
|
|
181
|
+
var onEvent = function (evt) {
|
|
182
|
+
_this.trigger(evt.type, evt);
|
|
183
|
+
};
|
|
174
184
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
175
185
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
176
186
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
177
187
|
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
178
|
-
.forEach(function (evt) {
|
|
188
|
+
.forEach(function (evt) {
|
|
189
|
+
session.addEventListener(evt, onEvent);
|
|
190
|
+
session.addEventListener("webkit".concat(evt), onEvent);
|
|
191
|
+
});
|
|
179
192
|
this._unbindSession = function () {
|
|
180
193
|
["keymessage", "message", "keyadded", "ready", "keyerror", "error"]
|
|
181
|
-
.forEach(function (evt) {
|
|
194
|
+
.forEach(function (evt) {
|
|
195
|
+
session.removeEventListener(evt, onEvent);
|
|
196
|
+
session.removeEventListener("webkit".concat(evt), onEvent);
|
|
197
|
+
});
|
|
182
198
|
};
|
|
183
199
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
184
200
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
@@ -45,12 +45,10 @@ export declare function patchInitData(initData: Uint8Array): Uint8Array;
|
|
|
45
45
|
* Generate a request from session.
|
|
46
46
|
* @param {MediaKeySession} session - MediaKeySession on which the request will
|
|
47
47
|
* be done.
|
|
48
|
-
* @param {
|
|
49
|
-
* "encrypted" event for the corresponding request.
|
|
50
|
-
* @param {
|
|
51
|
-
* "encrypted" event for the corresponding request.
|
|
52
|
-
* @param {string} sessionType - Type of session you want to generate. Consult
|
|
53
|
-
* EME Specification for more information on session types.
|
|
48
|
+
* @param {string} initializationDataType - Initialization data type given e.g.
|
|
49
|
+
* by the "encrypted" event for the corresponding request.
|
|
50
|
+
* @param {Uint8Array} initializationData - Initialization data given e.g. by
|
|
51
|
+
* the "encrypted" event for the corresponding request.
|
|
54
52
|
* @returns {Promise} - Emit when done. Errors if fails.
|
|
55
53
|
*/
|
|
56
54
|
export default function generateKeyRequest(session: MediaKeySession | ICustomMediaKeySession, initializationDataType: string | undefined, initializationData: Uint8Array): Promise<unknown>;
|
|
@@ -114,12 +114,10 @@ export function patchInitData(initData) {
|
|
|
114
114
|
* Generate a request from session.
|
|
115
115
|
* @param {MediaKeySession} session - MediaKeySession on which the request will
|
|
116
116
|
* be done.
|
|
117
|
-
* @param {
|
|
118
|
-
* "encrypted" event for the corresponding request.
|
|
119
|
-
* @param {
|
|
120
|
-
* "encrypted" event for the corresponding request.
|
|
121
|
-
* @param {string} sessionType - Type of session you want to generate. Consult
|
|
122
|
-
* EME Specification for more information on session types.
|
|
117
|
+
* @param {string} initializationDataType - Initialization data type given e.g.
|
|
118
|
+
* by the "encrypted" event for the corresponding request.
|
|
119
|
+
* @param {Uint8Array} initializationData - Initialization data given e.g. by
|
|
120
|
+
* the "encrypted" event for the corresponding request.
|
|
123
121
|
* @returns {Promise} - Emit when done. Errors if fails.
|
|
124
122
|
*/
|
|
125
123
|
export default function generateKeyRequest(session, initializationDataType, initializationData) {
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
* Calculating a live-offseted media position necessitate to obtain first an
|
|
18
|
+
* offset, and then adding that offset to the wanted position.
|
|
19
|
+
*
|
|
20
|
+
* That offset is in most case present inside the Manifest file, yet in cases
|
|
21
|
+
* without it or without a Manifest, such as the "directfile" mode, the RxPlayer
|
|
22
|
+
* won't know that offset.
|
|
23
|
+
*
|
|
24
|
+
* Thankfully Safari declares a `getStartDate` method allowing to obtain that
|
|
25
|
+
* offset when available. This logic is mainly useful when playing HLS contents
|
|
26
|
+
* in directfile mode on Safari.
|
|
27
|
+
* @param {HTMLMediaElement} mediaElement
|
|
28
|
+
* @returns {number|undefined}
|
|
29
|
+
*/
|
|
30
|
+
export default function getStartDate(mediaElement: HTMLMediaElement): number | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
* Calculating a live-offseted media position necessitate to obtain first an
|
|
18
|
+
* offset, and then adding that offset to the wanted position.
|
|
19
|
+
*
|
|
20
|
+
* That offset is in most case present inside the Manifest file, yet in cases
|
|
21
|
+
* without it or without a Manifest, such as the "directfile" mode, the RxPlayer
|
|
22
|
+
* won't know that offset.
|
|
23
|
+
*
|
|
24
|
+
* Thankfully Safari declares a `getStartDate` method allowing to obtain that
|
|
25
|
+
* offset when available. This logic is mainly useful when playing HLS contents
|
|
26
|
+
* in directfile mode on Safari.
|
|
27
|
+
* @param {HTMLMediaElement} mediaElement
|
|
28
|
+
* @returns {number|undefined}
|
|
29
|
+
*/
|
|
30
|
+
export default function getStartDate(mediaElement) {
|
|
31
|
+
var _mediaElement = mediaElement;
|
|
32
|
+
if (typeof _mediaElement.getStartDate === "function") {
|
|
33
|
+
var startDate = _mediaElement.getStartDate();
|
|
34
|
+
if (typeof startDate === "object" && startDate !== null) {
|
|
35
|
+
var startDateNum = +startDate;
|
|
36
|
+
if (!isNaN(startDateNum)) {
|
|
37
|
+
return startDateNum / 1000;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else if (typeof startDate === "number" && !isNaN(startDate)) {
|
|
41
|
+
return startDate;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -22,6 +22,7 @@ import clearElementSrc from "./clear_element_src";
|
|
|
22
22
|
import { closeSession, CustomMediaKeySystemAccess, generateKeyRequest, getInitData, ICustomMediaKeys, ICustomMediaKeySession, ICustomMediaKeySystemAccess, loadSession, requestMediaKeySystemAccess, setMediaKeys } from "./eme";
|
|
23
23
|
import * as events from "./event_listeners";
|
|
24
24
|
import { exitFullscreen, isFullscreen, requestFullscreen } from "./fullscreen";
|
|
25
|
+
import getStartDate from "./get_start_date";
|
|
25
26
|
import hasEMEAPIs from "./has_eme_apis";
|
|
26
27
|
import isCodecSupported from "./is_codec_supported";
|
|
27
28
|
import isNode from "./is_node";
|
|
@@ -38,4 +39,4 @@ import shouldValidateMetadata from "./should_validate_metadata";
|
|
|
38
39
|
import shouldWaitForDataBeforeLoaded from "./should_wait_for_data_before_loaded";
|
|
39
40
|
import whenLoadedMetadata$ from "./when_loaded_metadata";
|
|
40
41
|
import whenMediaSourceOpen$ from "./when_media_source_open";
|
|
41
|
-
export { addClassName, addTextTrack, canPatchISOBMFFSegment, clearElementSrc, closeSession, CustomMediaKeySystemAccess, events, exitFullscreen, generateKeyRequest, getInitData, hasEMEAPIs, ICompatTextTrack, ICompatVTTCue, ICustomMediaKeySession, ICustomMediaKeySystemAccess, ICustomMediaKeys, ICompatSourceBuffer, isCodecSupported, isFullscreen, isNode, isOffline, isVTTCue, loadSession, makeVTTCue, MediaSource_, onHeightWidthChange, play, requestFullscreen, requestMediaKeySystemAccess, setElementSrc$, setMediaKeys, shouldReloadMediaSourceOnDecipherabilityUpdate, shouldRenewMediaKeys, shouldUnsetMediaKeys, shouldValidateMetadata, shouldWaitForDataBeforeLoaded, tryToChangeSourceBufferType, whenLoadedMetadata$, whenMediaSourceOpen$, };
|
|
42
|
+
export { addClassName, addTextTrack, canPatchISOBMFFSegment, clearElementSrc, closeSession, CustomMediaKeySystemAccess, events, exitFullscreen, generateKeyRequest, getInitData, getStartDate, hasEMEAPIs, ICompatTextTrack, ICompatVTTCue, ICustomMediaKeySession, ICustomMediaKeySystemAccess, ICustomMediaKeys, ICompatSourceBuffer, isCodecSupported, isFullscreen, isNode, isOffline, isVTTCue, loadSession, makeVTTCue, MediaSource_, onHeightWidthChange, play, requestFullscreen, requestMediaKeySystemAccess, setElementSrc$, setMediaKeys, shouldReloadMediaSourceOnDecipherabilityUpdate, shouldRenewMediaKeys, shouldUnsetMediaKeys, shouldValidateMetadata, shouldWaitForDataBeforeLoaded, tryToChangeSourceBufferType, whenLoadedMetadata$, whenMediaSourceOpen$, };
|
|
@@ -22,6 +22,7 @@ import clearElementSrc from "./clear_element_src";
|
|
|
22
22
|
import { closeSession, CustomMediaKeySystemAccess, generateKeyRequest, getInitData, loadSession, requestMediaKeySystemAccess, setMediaKeys, } from "./eme";
|
|
23
23
|
import * as events from "./event_listeners";
|
|
24
24
|
import { exitFullscreen, isFullscreen, requestFullscreen, } from "./fullscreen";
|
|
25
|
+
import getStartDate from "./get_start_date";
|
|
25
26
|
import hasEMEAPIs from "./has_eme_apis";
|
|
26
27
|
import isCodecSupported from "./is_codec_supported";
|
|
27
28
|
import isNode from "./is_node";
|
|
@@ -44,4 +45,4 @@ import whenMediaSourceOpen$ from "./when_media_source_open";
|
|
|
44
45
|
// we would prefer to disallow (both for the understandability of the code and
|
|
45
46
|
// to better exploit tree shaking.
|
|
46
47
|
patchWebkitSourceBuffer();
|
|
47
|
-
export { addClassName, addTextTrack, canPatchISOBMFFSegment, clearElementSrc, closeSession, CustomMediaKeySystemAccess, events, exitFullscreen, generateKeyRequest, getInitData, hasEMEAPIs, isCodecSupported, isFullscreen, isNode, isOffline, isVTTCue, loadSession, makeVTTCue, MediaSource_, onHeightWidthChange, play, requestFullscreen, requestMediaKeySystemAccess, setElementSrc$, setMediaKeys, shouldReloadMediaSourceOnDecipherabilityUpdate, shouldRenewMediaKeys, shouldUnsetMediaKeys, shouldValidateMetadata, shouldWaitForDataBeforeLoaded, tryToChangeSourceBufferType, whenLoadedMetadata$, whenMediaSourceOpen$, };
|
|
48
|
+
export { addClassName, addTextTrack, canPatchISOBMFFSegment, clearElementSrc, closeSession, CustomMediaKeySystemAccess, events, exitFullscreen, generateKeyRequest, getInitData, getStartDate, hasEMEAPIs, isCodecSupported, isFullscreen, isNode, isOffline, isVTTCue, loadSession, makeVTTCue, MediaSource_, onHeightWidthChange, play, requestFullscreen, requestMediaKeySystemAccess, setElementSrc$, setMediaKeys, shouldReloadMediaSourceOnDecipherabilityUpdate, shouldRenewMediaKeys, shouldUnsetMediaKeys, shouldValidateMetadata, shouldWaitForDataBeforeLoaded, tryToChangeSourceBufferType, whenLoadedMetadata$, whenMediaSourceOpen$, };
|
|
@@ -145,9 +145,6 @@ declare class ConfigHandler {
|
|
|
145
145
|
DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0: number;
|
|
146
146
|
EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS: number;
|
|
147
147
|
EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION: number;
|
|
148
|
-
EME_SESSION_CLOSING_MAX_RETRY: number;
|
|
149
|
-
EME_SESSION_CLOSING_INITIAL_DELAY: number;
|
|
150
|
-
EME_SESSION_CLOSING_MAX_DELAY: number;
|
|
151
148
|
EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES: number;
|
|
152
149
|
FORCED_ENDED_THRESHOLD: number;
|
|
153
150
|
ADAPTATION_SWITCH_BUFFER_PADDINGS: {
|
|
@@ -178,8 +175,7 @@ declare class ConfigHandler {
|
|
|
178
175
|
DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR: number;
|
|
179
176
|
BUFFERED_HISTORY_RETENTION_TIME: number;
|
|
180
177
|
BUFFERED_HISTORY_MAXIMUM_ENTRIES: number;
|
|
181
|
-
|
|
182
|
-
MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP: number;
|
|
178
|
+
MIN_BUFFER_AHEAD: number;
|
|
183
179
|
UPTO_CURRENT_POSITION_CLEANUP: number;
|
|
184
180
|
};
|
|
185
181
|
update(config: Partial<IDefaultConfig>): void;
|
|
@@ -44,7 +44,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
44
44
|
* It also starts the different sub-parts of the player on various API calls.
|
|
45
45
|
*/
|
|
46
46
|
import { combineLatest as observableCombineLatest, concat as observableConcat, connectable, distinctUntilChanged, EMPTY, filter, map, merge as observableMerge, mergeMap, of as observableOf, ReplaySubject, share, shareReplay, skipWhile, startWith, Subject, switchMap, take, takeUntil, } from "rxjs";
|
|
47
|
-
import { events, exitFullscreen, isFullscreen, requestFullscreen, } from "../../compat";
|
|
47
|
+
import { events, exitFullscreen, getStartDate, isFullscreen, requestFullscreen, } from "../../compat";
|
|
48
48
|
/* eslint-disable-next-line max-len */
|
|
49
49
|
import canRelyOnVideoVisibilityAndSize from "../../compat/can_rely_on_video_visibility_and_size";
|
|
50
50
|
import config from "../../config";
|
|
@@ -87,7 +87,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
87
87
|
// Workaround to support Firefox autoplay on FF 42.
|
|
88
88
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
89
89
|
videoElement.preload = "auto";
|
|
90
|
-
_this.version = /* PLAYER_VERSION */ "3.27.0
|
|
90
|
+
_this.version = /* PLAYER_VERSION */ "3.27.0";
|
|
91
91
|
_this.log = log;
|
|
92
92
|
_this.state = "STOPPED";
|
|
93
93
|
_this.videoElement = videoElement;
|
|
@@ -805,22 +805,8 @@ var Player = /** @class */ (function (_super) {
|
|
|
805
805
|
}
|
|
806
806
|
var _a = this._priv_contentInfos, isDirectFile = _a.isDirectFile, manifest = _a.manifest;
|
|
807
807
|
if (isDirectFile) {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
// That offset is in most case present inside the Manifest file, yet in
|
|
811
|
-
// directfile mode, the RxPlayer won't parse that file, the browser does it.
|
|
812
|
-
//
|
|
813
|
-
// Thankfully Safari declares a `getStartDate` method allowing to obtain
|
|
814
|
-
// that offset when available. This logic is thus mainly useful when
|
|
815
|
-
// playing HLS contents in directfile mode on Safari.
|
|
816
|
-
var mediaElement = this.videoElement;
|
|
817
|
-
if (typeof mediaElement.getStartDate === "function") {
|
|
818
|
-
var startDate = mediaElement.getStartDate();
|
|
819
|
-
if (typeof startDate === "number" && !isNaN(startDate)) {
|
|
820
|
-
return startDate + mediaElement.currentTime;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
return mediaElement.currentTime;
|
|
808
|
+
var startDate = getStartDate(this.videoElement);
|
|
809
|
+
return (startDate !== null && startDate !== void 0 ? startDate : 0) + this.videoElement.currentTime;
|
|
824
810
|
}
|
|
825
811
|
if (manifest !== null) {
|
|
826
812
|
var currentTime = this.videoElement.currentTime;
|
|
@@ -1069,13 +1055,14 @@ var Player = /** @class */ (function (_super) {
|
|
|
1069
1055
|
* @returns {Number} - The time the player has seek to
|
|
1070
1056
|
*/
|
|
1071
1057
|
Player.prototype.seekTo = function (time) {
|
|
1058
|
+
var _a;
|
|
1072
1059
|
if (this.videoElement === null) {
|
|
1073
1060
|
throw new Error("Disposed player");
|
|
1074
1061
|
}
|
|
1075
1062
|
if (this._priv_contentInfos === null) {
|
|
1076
1063
|
throw new Error("player: no content loaded");
|
|
1077
1064
|
}
|
|
1078
|
-
var
|
|
1065
|
+
var _b = this._priv_contentInfos, isDirectFile = _b.isDirectFile, manifest = _b.manifest;
|
|
1079
1066
|
if (!isDirectFile && manifest === null) {
|
|
1080
1067
|
throw new Error("player: the content did not load yet");
|
|
1081
1068
|
}
|
|
@@ -1093,11 +1080,18 @@ var Player = /** @class */ (function (_super) {
|
|
|
1093
1080
|
positionWanted = timeObj.position;
|
|
1094
1081
|
}
|
|
1095
1082
|
else if (!isNullOrUndefined(timeObj.wallClockTime)) {
|
|
1096
|
-
|
|
1097
|
-
timeObj.wallClockTime :
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1083
|
+
if (manifest !== null) {
|
|
1084
|
+
positionWanted = timeObj.wallClockTime - ((_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0);
|
|
1085
|
+
}
|
|
1086
|
+
else if (isDirectFile && this.videoElement !== null) {
|
|
1087
|
+
var startDate = getStartDate(this.videoElement);
|
|
1088
|
+
if (startDate !== undefined) {
|
|
1089
|
+
positionWanted = timeObj.wallClockTime - startDate;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
if (positionWanted === undefined) {
|
|
1093
|
+
positionWanted = timeObj.wallClockTime;
|
|
1094
|
+
}
|
|
1101
1095
|
}
|
|
1102
1096
|
else {
|
|
1103
1097
|
throw new Error("invalid time object. You must set one of the " +
|
|
@@ -2261,6 +2255,12 @@ var Player = /** @class */ (function (_super) {
|
|
|
2261
2255
|
positionData.wallClockTime = observation.position + ast;
|
|
2262
2256
|
positionData.liveGap = maximumPosition - observation.position;
|
|
2263
2257
|
}
|
|
2258
|
+
else if (isDirectFile && this.videoElement !== null) {
|
|
2259
|
+
var startDate = getStartDate(this.videoElement);
|
|
2260
|
+
if (startDate !== undefined) {
|
|
2261
|
+
positionData.wallClockTime = startDate + observation.position;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
2264
|
this.trigger("positionUpdate", positionData);
|
|
2265
2265
|
};
|
|
2266
2266
|
/**
|
|
@@ -2302,5 +2302,5 @@ var Player = /** @class */ (function (_super) {
|
|
|
2302
2302
|
};
|
|
2303
2303
|
return Player;
|
|
2304
2304
|
}(EventEmitter));
|
|
2305
|
-
Player.version = /* PLAYER_VERSION */ "3.27.0
|
|
2305
|
+
Player.version = /* PLAYER_VERSION */ "3.27.0";
|
|
2306
2306
|
export default Player;
|
|
@@ -84,7 +84,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
84
84
|
}
|
|
85
85
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
86
86
|
};
|
|
87
|
-
import { events,
|
|
87
|
+
import { events, getInitData, } from "../../compat/";
|
|
88
88
|
import config from "../../config";
|
|
89
89
|
import { EncryptedMediaError, OtherError, } from "../../errors";
|
|
90
90
|
import log from "../../log";
|
|
@@ -318,7 +318,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
|
|
|
318
318
|
*/
|
|
319
319
|
ContentDecryptor.prototype._processInitializationData = function (initializationData, mediaKeysData) {
|
|
320
320
|
return __awaiter(this, void 0, void 0, function () {
|
|
321
|
-
var mediaKeySystemAccess, stores, options, firstCreatedSession, keyIds, hexKids, period, createdSessions, periodKeys, _i, createdSessions_1, createdSess, periodKeysArr, _a, periodKeysArr_1, kid, _b, periodKeysArr_2, innerKid, wantedSessionType, _c, EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION, maxSessionCacheSize, sessionRes, sessionInfo, _d, mediaKeySession, sessionType, isSessionPersisted, sub, requestData, error_1;
|
|
321
|
+
var mediaKeySystemAccess, stores, options, firstCreatedSession, keyIds, hexKids, period, createdSessions, periodKeys, _i, createdSessions_1, createdSess, periodKeysArr, _a, periodKeysArr_1, kid, _b, periodKeysArr_2, innerKid, wantedSessionType, _c, EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION, maxSessionCacheSize, sessionRes, sessionInfo, _d, mediaKeySession, sessionType, isSessionPersisted, sub, requestData, error_1, entry, indexInCurrent;
|
|
322
322
|
var _this = this;
|
|
323
323
|
return __generator(this, function (_e) {
|
|
324
324
|
switch (_e.label) {
|
|
@@ -486,12 +486,20 @@ var ContentDecryptor = /** @class */ (function (_super) {
|
|
|
486
486
|
_e.label = 2;
|
|
487
487
|
case 2:
|
|
488
488
|
_e.trys.push([2, 4, , 5]);
|
|
489
|
-
return [4 /*yield*/,
|
|
489
|
+
return [4 /*yield*/, stores.loadedSessionsStore.generateLicenseRequest(mediaKeySession, initializationData.type, requestData)];
|
|
490
490
|
case 3:
|
|
491
491
|
_e.sent();
|
|
492
492
|
return [3 /*break*/, 5];
|
|
493
493
|
case 4:
|
|
494
494
|
error_1 = _e.sent();
|
|
495
|
+
entry = stores.loadedSessionsStore.getEntryForSession(mediaKeySession);
|
|
496
|
+
if (entry === null || entry.closingStatus.type !== "none") {
|
|
497
|
+
indexInCurrent = this._currentSessions.indexOf(sessionInfo);
|
|
498
|
+
if (indexInCurrent >= 0) {
|
|
499
|
+
this._currentSessions.splice(indexInCurrent, 1);
|
|
500
|
+
}
|
|
501
|
+
return [2 /*return*/, Promise.resolve()];
|
|
502
|
+
}
|
|
495
503
|
throw new EncryptedMediaError("KEY_GENERATE_REQUEST_ERROR", error_1 instanceof Error ? error_1.toString() :
|
|
496
504
|
"Unknown error");
|
|
497
505
|
case 5: return [2 /*return*/, Promise.resolve()];
|
|
@@ -111,7 +111,7 @@ export default function createOrLoadSession(initializationData, stores, wantedSe
|
|
|
111
111
|
if (cancelSignal.cancellationError !== null) {
|
|
112
112
|
throw cancelSignal.cancellationError; // stop here if cancelled since
|
|
113
113
|
}
|
|
114
|
-
return [4 /*yield*/, createSession(stores, initializationData, wantedSessionType)];
|
|
114
|
+
return [4 /*yield*/, createSession(stores, initializationData, wantedSessionType, cancelSignal)];
|
|
115
115
|
case 4:
|
|
116
116
|
evt = _a.sent();
|
|
117
117
|
return [2 /*return*/, { type: evt.type,
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { ICustomMediaKeySession } from "../../compat";
|
|
17
|
+
import { CancellationSignal } from "../../utils/task_canceller";
|
|
17
18
|
import { IProcessedProtectionData, IMediaKeySessionStores, MediaKeySessionLoadingType } from "./types";
|
|
18
19
|
import KeySessionRecord from "./utils/key_session_record";
|
|
19
20
|
/**
|
|
@@ -29,9 +30,10 @@ import KeySessionRecord from "./utils/key_session_record";
|
|
|
29
30
|
* @param {Object} stores
|
|
30
31
|
* @param {Object} initData
|
|
31
32
|
* @param {string} wantedSessionType
|
|
33
|
+
* @param {Object} cancelSignal
|
|
32
34
|
* @returns {Promise}
|
|
33
35
|
*/
|
|
34
|
-
export default function createSession(stores: IMediaKeySessionStores, initData: IProcessedProtectionData, wantedSessionType: MediaKeySessionType): Promise<ICreateSessionEvent>;
|
|
36
|
+
export default function createSession(stores: IMediaKeySessionStores, initData: IProcessedProtectionData, wantedSessionType: MediaKeySessionType, cancelSignal: CancellationSignal): Promise<ICreateSessionEvent>;
|
|
35
37
|
export interface INewSessionCreatedEvent {
|
|
36
38
|
type: MediaKeySessionLoadingType.Created;
|
|
37
39
|
value: {
|
|
@@ -49,7 +49,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
49
49
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
-
import { loadSession, } from "../../compat";
|
|
53
52
|
import log from "../../log";
|
|
54
53
|
import isSessionUsable from "./utils/is_session_usable";
|
|
55
54
|
/**
|
|
@@ -65,9 +64,10 @@ import isSessionUsable from "./utils/is_session_usable";
|
|
|
65
64
|
* @param {Object} stores
|
|
66
65
|
* @param {Object} initData
|
|
67
66
|
* @param {string} wantedSessionType
|
|
67
|
+
* @param {Object} cancelSignal
|
|
68
68
|
* @returns {Promise}
|
|
69
69
|
*/
|
|
70
|
-
export default function createSession(stores, initData, wantedSessionType) {
|
|
70
|
+
export default function createSession(stores, initData, wantedSessionType, cancelSignal) {
|
|
71
71
|
var loadedSessionsStore = stores.loadedSessionsStore, persistentSessionsStore = stores.persistentSessionsStore;
|
|
72
72
|
if (wantedSessionType === "temporary") {
|
|
73
73
|
return createTemporarySession(loadedSessionsStore, initData);
|
|
@@ -77,7 +77,7 @@ export default function createSession(stores, initData, wantedSessionType) {
|
|
|
77
77
|
"PersistentSessionsStore not created.");
|
|
78
78
|
return createTemporarySession(loadedSessionsStore, initData);
|
|
79
79
|
}
|
|
80
|
-
return createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData);
|
|
80
|
+
return createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData, cancelSignal);
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Create a new temporary MediaKeySession linked to the given initData and
|
|
@@ -98,9 +98,10 @@ function createTemporarySession(loadedSessionsStore, initData) {
|
|
|
98
98
|
* @param {Object} loadedSessionsStore
|
|
99
99
|
* @param {Object} persistentSessionsStore
|
|
100
100
|
* @param {Object} initData
|
|
101
|
+
* @param {Object} cancelSignal
|
|
101
102
|
* @returns {Promise}
|
|
102
103
|
*/
|
|
103
|
-
function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData) {
|
|
104
|
+
function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData, cancelSignal) {
|
|
104
105
|
return __awaiter(this, void 0, void 0, function () {
|
|
105
106
|
/**
|
|
106
107
|
* Helper function to close and restart the current persistent session
|
|
@@ -113,6 +114,9 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
|
|
|
113
114
|
return __generator(this, function (_a) {
|
|
114
115
|
switch (_a.label) {
|
|
115
116
|
case 0:
|
|
117
|
+
if (cancelSignal.cancellationError !== null) {
|
|
118
|
+
throw cancelSignal.cancellationError;
|
|
119
|
+
}
|
|
116
120
|
log.info("DRM: Removing previous persistent session.");
|
|
117
121
|
persistentEntry = persistentSessionsStore.get(initData);
|
|
118
122
|
if (persistentEntry !== null) {
|
|
@@ -121,6 +125,9 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
|
|
|
121
125
|
return [4 /*yield*/, loadedSessionsStore.closeSession(entry.mediaKeySession)];
|
|
122
126
|
case 1:
|
|
123
127
|
_a.sent();
|
|
128
|
+
if (cancelSignal.cancellationError !== null) {
|
|
129
|
+
throw cancelSignal.cancellationError;
|
|
130
|
+
}
|
|
124
131
|
newEntry = loadedSessionsStore.createSession(initData, "persistent-license");
|
|
125
132
|
return [2 /*return*/, { type: "created-session" /* Created */,
|
|
126
133
|
value: newEntry }];
|
|
@@ -132,6 +139,9 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
|
|
|
132
139
|
return __generator(this, function (_a) {
|
|
133
140
|
switch (_a.label) {
|
|
134
141
|
case 0:
|
|
142
|
+
if (cancelSignal.cancellationError !== null) {
|
|
143
|
+
throw cancelSignal.cancellationError;
|
|
144
|
+
}
|
|
135
145
|
log.info("DRM: Creating persistent MediaKeySession");
|
|
136
146
|
entry = loadedSessionsStore.createSession(initData, "persistent-license");
|
|
137
147
|
storedEntry = persistentSessionsStore.getAndReuse(initData);
|
|
@@ -142,7 +152,7 @@ function createAndTryToRetrievePersistentSession(loadedSessionsStore, persistent
|
|
|
142
152
|
_a.label = 1;
|
|
143
153
|
case 1:
|
|
144
154
|
_a.trys.push([1, 3, , 4]);
|
|
145
|
-
return [4 /*yield*/,
|
|
155
|
+
return [4 /*yield*/, loadedSessionsStore.loadPersistentSession(entry.mediaKeySession, storedEntry.sessionId)];
|
|
146
156
|
case 2:
|
|
147
157
|
hasLoadedSession = _a.sent();
|
|
148
158
|
if (!hasLoadedSession) {
|