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.
Files changed (60) hide show
  1. package/CHANGELOG.md +5 -2
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +15 -11
  4. package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +22 -6
  5. package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +4 -6
  6. package/dist/_esm5.processed/compat/eme/generate_key_request.js +4 -6
  7. package/dist/_esm5.processed/compat/get_start_date.d.ts +30 -0
  8. package/dist/_esm5.processed/compat/get_start_date.js +44 -0
  9. package/dist/_esm5.processed/compat/index.d.ts +2 -1
  10. package/dist/_esm5.processed/compat/index.js +2 -1
  11. package/dist/_esm5.processed/config.d.ts +1 -5
  12. package/dist/_esm5.processed/core/api/public_api.js +25 -25
  13. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +11 -3
  14. package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +1 -1
  15. package/dist/_esm5.processed/core/decrypt/create_session.d.ts +3 -1
  16. package/dist/_esm5.processed/core/decrypt/create_session.js +15 -5
  17. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +94 -1
  18. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +237 -96
  19. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +4 -1
  20. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +2 -1
  21. package/dist/_esm5.processed/core/stream/period/period_stream.js +9 -3
  22. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +4 -3
  23. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +3 -2
  24. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +2 -2
  25. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +9 -3
  26. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.d.ts +11 -1
  27. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +27 -45
  28. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +6 -4
  29. package/dist/_esm5.processed/default_config.d.ts +2 -35
  30. package/dist/_esm5.processed/default_config.js +2 -35
  31. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +39 -38
  32. package/dist/_esm5.processed/utils/reference.js +0 -2
  33. package/dist/_esm5.processed/utils/task_canceller.d.ts +8 -1
  34. package/dist/_esm5.processed/utils/task_canceller.js +9 -1
  35. package/dist/rx-player.js +927 -587
  36. package/dist/rx-player.min.js +1 -1
  37. package/package.json +1 -1
  38. package/sonar-project.properties +1 -1
  39. package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +16 -12
  40. package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +21 -8
  41. package/src/compat/eme/generate_key_request.ts +4 -6
  42. package/src/compat/get_start_date.ts +48 -0
  43. package/src/compat/index.ts +2 -0
  44. package/src/core/api/public_api.ts +23 -27
  45. package/src/core/decrypt/content_decryptor.ts +15 -4
  46. package/src/core/decrypt/create_or_load_session.ts +4 -1
  47. package/src/core/decrypt/create_session.ts +23 -9
  48. package/src/core/decrypt/utils/loaded_sessions_store.ts +254 -102
  49. package/src/core/segment_buffers/garbage_collector.ts +4 -0
  50. package/src/core/stream/orchestrator/stream_orchestrator.ts +2 -1
  51. package/src/core/stream/period/period_stream.ts +9 -4
  52. package/src/core/stream/representation/append_segment_to_buffer.ts +17 -13
  53. package/src/core/stream/representation/force_garbage_collection.ts +4 -1
  54. package/src/core/stream/representation/get_buffer_status.ts +21 -13
  55. package/src/core/stream/representation/get_needed_segments.ts +40 -55
  56. package/src/core/stream/representation/representation_stream.ts +6 -4
  57. package/src/default_config.ts +20 -57
  58. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +41 -44
  59. package/src/utils/reference.ts +0 -2
  60. 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-dev.2022032100 (2022-03-21)
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-dev.2022032100
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
- _this._onSessionRelatedEvent = function (evt) {
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) { return mediaElement.addEventListener(evt, _this._onSessionRelatedEvent); });
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(license));
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) { return session.addEventListener(evt, _this._onEvent); });
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) { return session.removeEventListener(evt, _this._onEvent); });
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 {Uint8Array} initData - Initialization data given e.g. by the
49
- * "encrypted" event for the corresponding request.
50
- * @param {string} initDataType - Initialization data type given e.g. by the
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 {Uint8Array} initData - Initialization data given e.g. by the
118
- * "encrypted" event for the corresponding request.
119
- * @param {string} initDataType - Initialization data type given e.g. by the
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
- MIN_BUFFER_LENGTH: number;
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-dev.2022032100";
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
- // Calculating the "wall-clock time" necessitate to obtain first an offset,
809
- // and then adding that offset to the HTMLMediaElement's current position.
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 _a = this._priv_contentInfos, isDirectFile = _a.isDirectFile, manifest = _a.manifest;
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
- positionWanted = (isDirectFile || manifest === null) ?
1097
- timeObj.wallClockTime :
1098
- timeObj.wallClockTime - (manifest.availabilityStartTime !== undefined ?
1099
- manifest.availabilityStartTime :
1100
- 0);
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-dev.2022032100";
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, generateKeyRequest, getInitData, } from "../../compat/";
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*/, generateKeyRequest(mediaKeySession, initializationData.type, requestData)];
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*/, loadSession(entry.mediaKeySession, storedEntry.sessionId)];
155
+ return [4 /*yield*/, loadedSessionsStore.loadPersistentSession(entry.mediaKeySession, storedEntry.sessionId)];
146
156
  case 2:
147
157
  hasLoadedSession = _a.sent();
148
158
  if (!hasLoadedSession) {