rx-player 3.30.0-dev.2023020100 → 3.30.0-dev.2023030200

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 (183) hide show
  1. package/.eslintrc.js +8 -0
  2. package/CHANGELOG.md +5 -1
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/browser_detection.d.ts +23 -12
  5. package/dist/_esm5.processed/compat/browser_detection.js +80 -38
  6. package/dist/_esm5.processed/compat/can_reuse_media_keys.js +2 -2
  7. package/dist/_esm5.processed/compat/eme/close_session.js +2 -2
  8. package/dist/_esm5.processed/compat/event_listeners.js +1 -1
  9. package/dist/_esm5.processed/config.d.ts +2 -0
  10. package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +4 -2
  11. package/dist/_esm5.processed/core/api/debug/buffer_graph.d.ts +28 -0
  12. package/dist/_esm5.processed/core/api/debug/buffer_graph.js +175 -0
  13. package/dist/_esm5.processed/core/api/debug/buffer_size_graph.d.ts +10 -0
  14. package/dist/_esm5.processed/core/api/debug/buffer_size_graph.js +104 -0
  15. package/dist/_esm5.processed/core/api/debug/constants.d.ts +2 -0
  16. package/dist/_esm5.processed/core/api/debug/constants.js +2 -0
  17. package/dist/_esm5.processed/core/api/debug/index.d.ts +2 -0
  18. package/dist/_esm5.processed/core/api/debug/index.js +2 -0
  19. package/dist/_esm5.processed/core/api/debug/modules/general_info.d.ts +3 -0
  20. package/dist/_esm5.processed/core/api/debug/modules/general_info.js +199 -0
  21. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.d.ts +4 -0
  22. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.js +121 -0
  23. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.d.ts +3 -0
  24. package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.js +35 -0
  25. package/dist/_esm5.processed/core/api/debug/render.d.ts +3 -0
  26. package/dist/_esm5.processed/core/api/debug/render.js +32 -0
  27. package/dist/_esm5.processed/core/api/debug/utils.d.ts +39 -0
  28. package/dist/_esm5.processed/core/api/debug/utils.js +57 -0
  29. package/dist/_esm5.processed/core/api/playback_observer.js +3 -2
  30. package/dist/_esm5.processed/core/api/public_api.d.ts +3 -0
  31. package/dist/_esm5.processed/core/api/public_api.js +25 -14
  32. package/dist/_esm5.processed/core/api/utils.js +3 -3
  33. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +32 -13
  34. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +28 -7
  35. package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +1 -1
  36. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +1 -1
  37. package/dist/_esm5.processed/core/decrypt/find_key_system.js +33 -24
  38. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +54 -50
  39. package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +4 -0
  40. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +17 -8
  41. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +10 -6
  42. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +5 -4
  43. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +22 -5
  44. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +37 -21
  45. package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +21 -23
  46. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +17 -7
  47. package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
  48. package/dist/_esm5.processed/core/init/media_source_content_initializer.js +27 -31
  49. package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +2 -2
  50. package/dist/_esm5.processed/core/init/utils/create_media_source.js +3 -12
  51. package/dist/_esm5.processed/core/init/utils/end_of_stream.js +6 -3
  52. package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +2 -1
  53. package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +9 -5
  54. package/dist/_esm5.processed/core/init/utils/initialize_content_decryption.js +2 -1
  55. package/dist/_esm5.processed/core/init/utils/media_duration_updater.js +23 -19
  56. package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +1 -1
  57. package/dist/_esm5.processed/core/init/utils/stream_events_emitter/stream_events_emitter.js +6 -4
  58. package/dist/_esm5.processed/core/init/utils/throw_on_media_error.js +1 -1
  59. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +7 -10
  60. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +4 -2
  61. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +13 -9
  62. package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +25 -16
  63. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +26 -12
  64. package/dist/_esm5.processed/core/stream/period/period_stream.js +11 -10
  65. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -15
  66. package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +1 -1
  67. package/dist/_esm5.processed/core/stream/representation/utils/downloading_queue.js +16 -6
  68. package/dist/_esm5.processed/default_config.d.ts +16 -0
  69. package/dist/_esm5.processed/default_config.js +19 -0
  70. package/dist/_esm5.processed/experimental/features/debug_element.d.ts +8 -0
  71. package/dist/_esm5.processed/experimental/features/debug_element.js +10 -0
  72. package/dist/_esm5.processed/experimental/features/index.d.ts +1 -0
  73. package/dist/_esm5.processed/experimental/features/index.js +1 -0
  74. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +7 -4
  75. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +8 -4
  76. package/dist/_esm5.processed/features/features_object.js +1 -0
  77. package/dist/_esm5.processed/features/initialize_features.js +13 -10
  78. package/dist/_esm5.processed/features/types.d.ts +3 -0
  79. package/dist/_esm5.processed/manifest/adaptation.js +4 -0
  80. package/dist/_esm5.processed/manifest/manifest.js +2 -0
  81. package/dist/_esm5.processed/manifest/representation.js +11 -4
  82. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +105 -137
  83. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +25 -5
  84. package/dist/_esm5.processed/public_types.d.ts +1 -0
  85. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +15 -11
  86. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +2 -2
  87. package/dist/_esm5.processed/transports/dash/manifest_parser.js +1 -1
  88. package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -4
  89. package/dist/_esm5.processed/transports/local/segment_loader.js +13 -26
  90. package/dist/_esm5.processed/transports/smooth/segment_loader.js +4 -4
  91. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
  92. package/dist/_esm5.processed/utils/cancellable_sleep.js +4 -10
  93. package/dist/_esm5.processed/utils/create_cancellable_promise.d.ts +26 -0
  94. package/dist/_esm5.processed/utils/create_cancellable_promise.js +52 -0
  95. package/dist/_esm5.processed/utils/reference.js +6 -0
  96. package/dist/_esm5.processed/utils/request/xhr.js +1 -1
  97. package/dist/_esm5.processed/utils/task_canceller.d.ts +34 -15
  98. package/dist/_esm5.processed/utils/task_canceller.js +55 -22
  99. package/dist/rx-player.js +880 -677
  100. package/dist/rx-player.min.js +1 -1
  101. package/jest.config.js +1 -0
  102. package/package.json +19 -18
  103. package/scripts/build/constants.d.ts +1 -0
  104. package/scripts/report_build_sizes +4 -0
  105. package/sonar-project.properties +1 -1
  106. package/src/compat/browser_detection.ts +99 -52
  107. package/src/compat/can_reuse_media_keys.ts +5 -2
  108. package/src/compat/eme/close_session.ts +2 -2
  109. package/src/compat/event_listeners.ts +1 -1
  110. package/src/core/adaptive/adaptive_representation_selector.ts +4 -2
  111. package/src/core/api/debug/buffer_graph.ts +247 -0
  112. package/src/core/api/debug/buffer_size_graph.ts +130 -0
  113. package/src/core/api/debug/constants.ts +2 -0
  114. package/src/core/api/debug/index.ts +3 -0
  115. package/src/core/api/debug/modules/general_info.ts +204 -0
  116. package/src/core/api/debug/modules/segment_buffer_content.ts +155 -0
  117. package/src/core/api/debug/modules/segment_buffer_size.ts +48 -0
  118. package/src/core/api/debug/render.ts +40 -0
  119. package/src/core/api/debug/utils.ts +103 -0
  120. package/src/core/api/playback_observer.ts +4 -2
  121. package/src/core/api/public_api.ts +28 -14
  122. package/src/core/api/utils.ts +3 -3
  123. package/src/core/decrypt/__tests__/__global__/utils.ts +61 -40
  124. package/src/core/decrypt/attach_media_keys.ts +1 -1
  125. package/src/core/decrypt/content_decryptor.ts +1 -1
  126. package/src/core/decrypt/find_key_system.ts +36 -35
  127. package/src/core/decrypt/session_events_listener.ts +57 -56
  128. package/src/core/decrypt/utils/check_key_statuses.ts +6 -0
  129. package/src/core/fetchers/cdn_prioritizer.ts +18 -9
  130. package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -4
  131. package/src/core/fetchers/segment/segment_fetcher.ts +36 -14
  132. package/src/core/fetchers/segment/task_prioritizer.ts +25 -30
  133. package/src/core/fetchers/utils/schedule_request.ts +18 -7
  134. package/src/core/init/directfile_content_initializer.ts +1 -1
  135. package/src/core/init/media_source_content_initializer.ts +37 -41
  136. package/src/core/init/utils/content_time_boundaries_observer.ts +2 -2
  137. package/src/core/init/utils/create_media_source.ts +4 -16
  138. package/src/core/init/utils/end_of_stream.ts +6 -3
  139. package/src/core/init/utils/get_loaded_reference.ts +2 -1
  140. package/src/core/init/utils/initial_seek_and_play.ts +9 -5
  141. package/src/core/init/utils/initialize_content_decryption.ts +2 -1
  142. package/src/core/init/utils/media_duration_updater.ts +25 -20
  143. package/src/core/init/utils/rebuffering_controller.ts +1 -1
  144. package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +6 -4
  145. package/src/core/init/utils/throw_on_media_error.ts +1 -1
  146. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +7 -11
  147. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +4 -2
  148. package/src/core/segment_buffers/segment_buffers_store.ts +16 -13
  149. package/src/core/stream/adaptation/adaptation_stream.ts +28 -19
  150. package/src/core/stream/orchestrator/stream_orchestrator.ts +26 -12
  151. package/src/core/stream/period/period_stream.ts +11 -10
  152. package/src/core/stream/representation/representation_stream.ts +15 -15
  153. package/src/core/stream/representation/utils/append_segment_to_buffer.ts +1 -1
  154. package/src/core/stream/representation/utils/downloading_queue.ts +16 -4
  155. package/src/default_config.ts +30 -9
  156. package/src/experimental/features/__tests__/debug_element.test.ts +26 -0
  157. package/src/experimental/features/debug_element.ts +13 -0
  158. package/src/experimental/features/index.ts +1 -0
  159. package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +7 -4
  160. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +8 -4
  161. package/src/features/__tests__/initialize_features.test.ts +11 -0
  162. package/src/features/features_object.ts +1 -0
  163. package/src/features/initialize_features.ts +15 -10
  164. package/src/features/types.ts +9 -0
  165. package/src/manifest/adaptation.ts +7 -0
  166. package/src/manifest/manifest.ts +4 -0
  167. package/src/manifest/representation.ts +10 -4
  168. package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +116 -151
  169. package/src/parsers/manifest/dash/common/parse_representations.ts +21 -4
  170. package/src/public_types.ts +1 -0
  171. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +31 -22
  172. package/src/transports/dash/low_latency_segment_loader.ts +2 -2
  173. package/src/transports/dash/manifest_parser.ts +1 -1
  174. package/src/transports/dash/segment_loader.ts +4 -4
  175. package/src/transports/local/segment_loader.ts +14 -30
  176. package/src/transports/smooth/segment_loader.ts +4 -4
  177. package/src/transports/utils/call_custom_manifest_loader.ts +3 -3
  178. package/src/typings/globals.d.ts +2 -0
  179. package/src/utils/cancellable_sleep.ts +5 -14
  180. package/src/utils/create_cancellable_promise.ts +69 -0
  181. package/src/utils/reference.ts +6 -0
  182. package/src/utils/request/xhr.ts +1 -1
  183. package/src/utils/task_canceller.ts +63 -34
@@ -69,10 +69,22 @@ var generateRequestID = idGenerator();
69
69
  * An `ISegmentFetcher` also implements a retry mechanism, based on the given
70
70
  * `options` argument, which may retry a segment request when it fails.
71
71
  *
72
- * @param {string} bufferType
73
- * @param {Object} pipeline
74
- * @param {Object} lifecycleCallbacks
75
- * @param {Object} options
72
+ * @param {string} bufferType - Type of buffer concerned (e.g. `"audio"`,
73
+ * `"video"`, `"text" etc.)
74
+ * @param {Object} pipeline - The transport-specific logic allowing to load
75
+ * segments of the given buffer type and transport protocol (e.g. DASH).
76
+ * @param {Object|null} cdnPrioritizer - Abstraction allowing to synchronize,
77
+ * update and keep track of the priorization of the CDN to use to load any given
78
+ * segment, in cases where multiple ones are available.
79
+ *
80
+ * Can be set to `null` in which case a minimal priorization logic will be used
81
+ * instead.
82
+ * @param {Object} lifecycleCallbacks - Callbacks that can be registered to be
83
+ * informed when new requests are made, ended, new metrics are available etc.
84
+ * This should be mainly useful to implement an adaptive logic relying on those
85
+ * metrics and events.
86
+ * @param {Object} options - Various tweaking options allowing to configure the
87
+ * behavior of the returned `ISegmentFetcher`.
76
88
  * @returns {Function}
77
89
  */
78
90
  export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritizer, lifecycleCallbacks, options) {
@@ -97,8 +109,17 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
97
109
  * @returns {Promise}
98
110
  */
99
111
  return function fetchSegment(content, fetcherCallbacks, cancellationSignal) {
100
- var _a, _b;
112
+ var _a, _b, _c;
101
113
  return __awaiter(this, void 0, void 0, function () {
114
+ function onCancellation() {
115
+ var _a;
116
+ if (requestInfo !== undefined) {
117
+ return; // Request already terminated
118
+ }
119
+ log.debug("SF: Segment request cancelled", segmentIdString);
120
+ requestInfo = null;
121
+ (_a = lifecycleCallbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, { id: requestId });
122
+ }
102
123
  /**
103
124
  * Call a segment loader for the given URL with the right arguments.
104
125
  * @param {Object|null} cdnMetadata
@@ -169,8 +190,8 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
169
190
  }
170
191
  }
171
192
  var segmentIdString, requestId, requestInfo, parsedChunks, segmentDurationAcc, metricsSent, loaderCallbacks, cached, res, loadedData, err_1;
172
- return __generator(this, function (_c) {
173
- switch (_c.label) {
193
+ return __generator(this, function (_d) {
194
+ switch (_d.label) {
174
195
  case 0:
175
196
  segmentIdString = getLoggableSegmentId(content);
176
197
  requestId = generateRequestID();
@@ -216,21 +237,13 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
216
237
  log.debug("SF: Beginning request", segmentIdString);
217
238
  (_a = lifecycleCallbacks.onRequestBegin) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, { requestTimestamp: performance.now(),
218
239
  id: requestId, content: content });
219
- cancellationSignal.register(function () {
220
- var _a;
221
- if (requestInfo !== undefined) {
222
- return; // Request already terminated
223
- }
224
- log.debug("SF: Segment request cancelled", segmentIdString);
225
- requestInfo = null;
226
- (_a = lifecycleCallbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, { id: requestId });
227
- });
228
- _c.label = 1;
240
+ cancellationSignal.register(onCancellation);
241
+ _d.label = 1;
229
242
  case 1:
230
- _c.trys.push([1, 3, , 4]);
243
+ _d.trys.push([1, 3, , 4]);
231
244
  return [4 /*yield*/, scheduleRequestWithCdns(content.representation.cdnMetadata, cdnPrioritizer, callLoaderWithUrl, objectAssign({ onRetry: onRetry }, options), cancellationSignal)];
232
245
  case 2:
233
- res = _c.sent();
246
+ res = _d.sent();
234
247
  if (res.resultType === "segment-loaded") {
235
248
  loadedData = res.resultData.responseData;
236
249
  if (cache !== undefined) {
@@ -250,21 +263,24 @@ export default function createSegmentFetcher(bufferType, pipeline, cdnPrioritize
250
263
  else {
251
264
  requestInfo = null;
252
265
  }
253
- if (!cancellationSignal.isCancelled) {
266
+ if (!cancellationSignal.isCancelled()) {
254
267
  // The current task could have been canceled as a result of one
255
268
  // of the previous callbacks call. In that case, we don't want to send
256
269
  // a "requestEnd" again as it has already been sent on cancellation.
257
270
  (_b = lifecycleCallbacks.onRequestEnd) === null || _b === void 0 ? void 0 : _b.call(lifecycleCallbacks, { id: requestId });
258
271
  }
272
+ cancellationSignal.deregister(onCancellation);
259
273
  return [3 /*break*/, 4];
260
274
  case 3:
261
- err_1 = _c.sent();
275
+ err_1 = _d.sent();
276
+ cancellationSignal.deregister(onCancellation);
262
277
  requestInfo = null;
263
278
  if (err_1 instanceof CancellationError) {
264
279
  log.debug("SF: Segment request aborted", segmentIdString);
265
280
  throw err_1;
266
281
  }
267
282
  log.debug("SF: Segment request failed", segmentIdString);
283
+ (_c = lifecycleCallbacks.onRequestEnd) === null || _c === void 0 ? void 0 : _c.call(lifecycleCallbacks, { id: requestId });
268
284
  throw errorSelector(err_1);
269
285
  case 4: return [2 /*return*/];
270
286
  }
@@ -1,5 +1,6 @@
1
1
  import log from "../../../log";
2
2
  import arrayFindIndex from "../../../utils/array_find_index";
3
+ import createCancellablePromise from "../../../utils/create_cancellable_promise";
3
4
  import TaskCanceller, { CancellationError, } from "../../../utils/task_canceller";
4
5
  var TaskPrioritizer = /** @class */ (function () {
5
6
  /**
@@ -41,18 +42,31 @@ var TaskPrioritizer = /** @class */ (function () {
41
42
  TaskPrioritizer.prototype.create = function (taskFn, priority, callbacks, cancelSignal) {
42
43
  var _this = this;
43
44
  var newTask;
44
- return new Promise(function (resolve, reject) {
45
+ return createCancellablePromise(cancelSignal, function (resolve, reject) {
45
46
  /** Function allowing to start the underlying Promise. */
46
47
  var trigger = function () {
47
48
  if (newTask.hasEnded) {
48
- unregisterCancelSignal();
49
49
  return;
50
50
  }
51
- var interrupter = new TaskCanceller({ cancelOn: cancelSignal });
51
+ var finishTask = function () {
52
+ unlinkInterrupter();
53
+ _this._endTask(newTask);
54
+ };
55
+ var onResolve = function (value) {
56
+ callbacks.beforeEnded();
57
+ finishTask();
58
+ resolve(value);
59
+ };
60
+ var onReject = function (err) {
61
+ finishTask();
62
+ reject(err);
63
+ };
64
+ var interrupter = new TaskCanceller();
65
+ var unlinkInterrupter = interrupter.linkToSignal(cancelSignal);
52
66
  newTask.interrupter = interrupter;
53
67
  interrupter.signal.register(function () {
54
68
  newTask.interrupter = null;
55
- if (!cancelSignal.isCancelled) {
69
+ if (!cancelSignal.isCancelled()) {
56
70
  callbacks.beforeInterrupted();
57
71
  }
58
72
  });
@@ -63,31 +77,14 @@ var TaskPrioritizer = /** @class */ (function () {
63
77
  newTask.taskFn(interrupter.signal)
64
78
  .then(onResolve)
65
79
  .catch(function (err) {
66
- if (!cancelSignal.isCancelled &&
67
- interrupter.isUsed &&
80
+ if (!cancelSignal.isCancelled() &&
81
+ interrupter.isUsed() &&
68
82
  err instanceof CancellationError) {
69
83
  return;
70
84
  }
71
85
  onReject(err);
72
86
  });
73
87
  };
74
- var unregisterCancelSignal = cancelSignal.register(function (cancellationError) {
75
- _this._endTask(newTask);
76
- reject(cancellationError);
77
- });
78
- var finishTask = function () {
79
- unregisterCancelSignal();
80
- _this._endTask(newTask);
81
- };
82
- var onResolve = function (value) {
83
- callbacks.beforeEnded();
84
- finishTask();
85
- resolve(value);
86
- };
87
- var onReject = function (err) {
88
- finishTask();
89
- reject(err);
90
- };
91
88
  newTask = {
92
89
  hasEnded: false,
93
90
  priority: priority,
@@ -112,6 +109,7 @@ var TaskPrioritizer = /** @class */ (function () {
112
109
  _this._interruptCancellableTasks();
113
110
  }
114
111
  }
112
+ return function () { return _this._endTask(newTask); };
115
113
  });
116
114
  };
117
115
  TaskPrioritizer.prototype._endTask = function (task) {
@@ -288,14 +288,14 @@ export function scheduleRequestWithCdns(cdns, cdnPrioritizer, performRequest, op
288
288
  var nextCdn;
289
289
  return __generator(this, function (_a) {
290
290
  nextCdn = getCdnToRequest();
291
- if (cancellationSignal.isCancelled) {
291
+ if (cancellationSignal.isCancelled()) {
292
292
  throw cancellationSignal.cancellationError;
293
293
  }
294
294
  if (nextCdn === undefined) {
295
295
  throw prevRequestError;
296
296
  }
297
297
  onRetry(prevRequestError);
298
- if (cancellationSignal.isCancelled) {
298
+ if (cancellationSignal.isCancelled()) {
299
299
  throw cancellationSignal.cancellationError;
300
300
  }
301
301
  return [2 /*return*/, waitPotentialBackoffAndRequest(nextCdn, prevRequestError)];
@@ -323,25 +323,35 @@ export function scheduleRequestWithCdns(cdns, cdnPrioritizer, performRequest, op
323
323
  if (blockedFor <= 0) {
324
324
  return requestCdn(nextWantedCdn);
325
325
  }
326
- var canceller = new TaskCanceller({ cancelOn: cancellationSignal });
326
+ var canceller = new TaskCanceller();
327
+ var unlinkCanceller = canceller.linkToSignal(cancellationSignal);
327
328
  return new Promise(function (res, rej) {
328
329
  /* eslint-disable-next-line @typescript-eslint/no-misused-promises */
329
330
  cdnPrioritizer === null || cdnPrioritizer === void 0 ? void 0 : cdnPrioritizer.addEventListener("priorityChange", function () {
330
331
  var updatedPrioritaryCdn = getCdnToRequest();
331
- if (cancellationSignal.isCancelled) {
332
+ if (cancellationSignal.isCancelled()) {
332
333
  throw cancellationSignal.cancellationError;
333
334
  }
334
335
  if (updatedPrioritaryCdn === undefined) {
335
- return rej(prevRequestError);
336
+ return cleanAndReject(prevRequestError);
336
337
  }
337
338
  if (updatedPrioritaryCdn !== nextWantedCdn) {
338
339
  canceller.cancel();
339
340
  waitPotentialBackoffAndRequest(updatedPrioritaryCdn, prevRequestError)
340
- .then(res, rej);
341
+ .then(cleanAndResolve, cleanAndReject);
341
342
  }
342
343
  }, canceller.signal);
343
344
  cancellableSleep(blockedFor, canceller.signal)
344
- .then(function () { return requestCdn(nextWantedCdn).then(res, rej); }, noop);
345
+ .then(function () { return requestCdn(nextWantedCdn)
346
+ .then(cleanAndResolve, cleanAndReject); }, noop);
347
+ function cleanAndResolve(response) {
348
+ unlinkCanceller();
349
+ res(response);
350
+ }
351
+ function cleanAndReject(err) {
352
+ unlinkCanceller();
353
+ rej(err);
354
+ }
345
355
  });
346
356
  }
347
357
  /**
@@ -145,7 +145,7 @@ var DirectFileContentInitializer = /** @class */ (function (_super) {
145
145
  }, { emitCurrentValue: true, clearSignal: cancelSignal });
146
146
  })
147
147
  .catch(function (err) {
148
- if (!cancelSignal.isCancelled) {
148
+ if (!cancelSignal.isCancelled()) {
149
149
  _this._onFatalError(err);
150
150
  }
151
151
  });
@@ -69,6 +69,7 @@ import config from "../../config";
69
69
  import { MediaError } from "../../errors";
70
70
  import log from "../../log";
71
71
  import assert from "../../utils/assert";
72
+ import createCancellablePromise from "../../utils/create_cancellable_promise";
72
73
  import objectAssign from "../../utils/object_assign";
73
74
  import createSharedReference from "../../utils/reference";
74
75
  import TaskCanceller from "../../utils/task_canceller";
@@ -127,11 +128,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
127
128
  if (this._initialManifestProm !== null) {
128
129
  return;
129
130
  }
130
- this._initialManifestProm = new Promise(function (res, rej) {
131
- _this._initCanceller.signal.register(function (err) {
132
- _this._manifestFetcher.dispose();
133
- rej(err);
134
- });
131
+ this._initialManifestProm = createCancellablePromise(this._initCanceller.signal, function (res, rej) {
135
132
  _this._manifestFetcher.addEventListener("warning", function (err) {
136
133
  return _this.trigger("warning", err);
137
134
  });
@@ -142,7 +139,10 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
142
139
  _this._manifestFetcher.addEventListener("manifestReady", function (manifest) {
143
140
  res(manifest);
144
141
  });
145
- _this._manifestFetcher.start();
142
+ });
143
+ this._manifestFetcher.start();
144
+ this._initCanceller.signal.register(function () {
145
+ _this._manifestFetcher.dispose();
146
146
  });
147
147
  };
148
148
  /**
@@ -176,7 +176,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
176
176
  this._initCanceller.cancel();
177
177
  };
178
178
  MediaSourceContentInitializer.prototype._onFatalError = function (err) {
179
- if (this._initCanceller.isUsed) {
179
+ if (this._initCanceller.isUsed()) {
180
180
  return;
181
181
  }
182
182
  this._initCanceller.cancel();
@@ -184,12 +184,9 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
184
184
  };
185
185
  MediaSourceContentInitializer.prototype._initializeMediaSourceAndDecryption = function (mediaElement, protectionRef) {
186
186
  var _this = this;
187
- return new Promise(function (resolve, reject) {
187
+ var initCanceller = this._initCanceller;
188
+ return createCancellablePromise(initCanceller.signal, function (resolve) {
188
189
  var keySystems = _this._settings.keySystems;
189
- var initCanceller = _this._initCanceller;
190
- var unregisterReject = initCanceller.signal.register(function (err) {
191
- reject(err);
192
- });
193
190
  /** Initialize decryption capabilities. */
194
191
  var drmInitRef = initializeContentDecryption(mediaElement, keySystems, protectionRef, {
195
192
  onWarning: function (err) { return _this.trigger("warning", err); },
@@ -200,9 +197,8 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
200
197
  return;
201
198
  }
202
199
  stopListeningToDrmUpdates();
203
- var mediaSourceCanceller = new TaskCanceller({
204
- cancelOn: initCanceller.signal,
205
- });
200
+ var mediaSourceCanceller = new TaskCanceller();
201
+ mediaSourceCanceller.linkToSignal(initCanceller.signal);
206
202
  openMediaSource(mediaElement, mediaSourceCanceller.signal)
207
203
  .then(function (mediaSource) {
208
204
  var lastDrmStatus = drmInitRef.getValue();
@@ -211,7 +207,6 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
211
207
  drmInitRef.onUpdate(function (newDrmStatus, stopListeningToDrmUpdatesAgain) {
212
208
  if (newDrmStatus.initializationState.type === "initialized") {
213
209
  stopListeningToDrmUpdatesAgain();
214
- unregisterReject();
215
210
  resolve({ mediaSource: mediaSource, drmSystemId: newDrmStatus.drmSystemId,
216
211
  unlinkMediaSource: mediaSourceCanceller });
217
212
  return;
@@ -219,14 +214,13 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
219
214
  }, { emitCurrentValue: true, clearSignal: initCanceller.signal });
220
215
  }
221
216
  else if (drmStatus.initializationState.type === "initialized") {
222
- unregisterReject();
223
217
  resolve({ mediaSource: mediaSource, drmSystemId: drmStatus.drmSystemId,
224
218
  unlinkMediaSource: mediaSourceCanceller });
225
219
  return;
226
220
  }
227
221
  })
228
222
  .catch(function (err) {
229
- if (mediaSourceCanceller.isUsed) {
223
+ if (mediaSourceCanceller.isUsed()) {
230
224
  return;
231
225
  }
232
226
  _this._onFatalError(err);
@@ -252,20 +246,21 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
252
246
  bufferOnMediaSource(opts, onReloadMediaSource, currentCanceller.signal);
253
247
  function onReloadMediaSource(reloadOrder) {
254
248
  currentCanceller.cancel();
255
- if (initCanceller.isUsed) {
249
+ if (initCanceller.isUsed()) {
256
250
  return;
257
251
  }
258
252
  triggerEvent("reloadingMediaSource", null);
259
- if (initCanceller.isUsed) {
253
+ if (initCanceller.isUsed()) {
260
254
  return;
261
255
  }
262
- var newCanceller = new TaskCanceller({ cancelOn: initCanceller.signal });
256
+ var newCanceller = new TaskCanceller();
257
+ newCanceller.linkToSignal(initCanceller.signal);
263
258
  openMediaSource(mediaElement, newCanceller.signal)
264
259
  .then(function (newMediaSource) {
265
260
  recursivelyLoadOnMediaSource(newMediaSource, reloadOrder.position, reloadOrder.autoPlay, newCanceller);
266
261
  })
267
262
  .catch(function (err) {
268
- if (newCanceller.isUsed) {
263
+ if (newCanceller.isUsed()) {
269
264
  return;
270
265
  }
271
266
  onFatalError(err);
@@ -305,7 +300,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
305
300
  subBufferOptions = objectAssign({ textTrackOptions: textTrackOptions, drmSystemId: drmSystemId }, bufferOptions);
306
301
  segmentFetcherCreator = new SegmentFetcherCreator(transport, segmentRequestOptions, initCanceller.signal);
307
302
  this.trigger("manifestReady", manifest);
308
- if (initCanceller.isUsed) {
303
+ if (initCanceller.isUsed()) {
309
304
  return [2 /*return*/];
310
305
  }
311
306
  bufferOnMediaSource = this._startBufferingOnMediaSource.bind(this);
@@ -339,7 +334,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
339
334
  segmentBuffersStore.disposeAll();
340
335
  });
341
336
  var _b = performInitialSeekAndPlay(mediaElement, playbackObserver, initialTime, autoPlay, function (err) { return _this.trigger("warning", err); }, cancelSignal), autoPlayResult = _b.autoPlayResult, initialPlayPerformed = _b.initialPlayPerformed, initialSeekPerformed = _b.initialSeekPerformed;
342
- if (cancelSignal.isCancelled) {
337
+ if (cancelSignal.isCancelled()) {
343
338
  return;
344
339
  }
345
340
  initialPlayPerformed.onUpdate(function (isPerformed, stopListening) {
@@ -368,7 +363,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
368
363
  }, { emitCurrentValue: true, clearSignal: cancelSignal });
369
364
  })
370
365
  .catch(function (err) {
371
- if (cancelSignal.isCancelled) {
366
+ if (cancelSignal.isCancelled()) {
372
367
  return; // Current loading cancelled, no need to trigger the error
373
368
  }
374
369
  _this._onFatalError(err);
@@ -395,7 +390,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
395
390
  discontinuity: imminentDiscontinuity,
396
391
  position: position,
397
392
  });
398
- if (cancelSignal.isCancelled) {
393
+ if (cancelSignal.isCancelled()) {
399
394
  return; // Previous call has stopped streams due to a side-effect
400
395
  }
401
396
  // If the status for the last Period indicates that segments are all loaded
@@ -432,14 +427,14 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
432
427
  },
433
428
  adaptationChange: function (value) {
434
429
  self.trigger("adaptationChange", value);
435
- if (cancelSignal.isCancelled) {
430
+ if (cancelSignal.isCancelled()) {
436
431
  return; // Previous call has stopped streams due to a side-effect
437
432
  }
438
433
  contentTimeBoundariesObserver.onAdaptationChange(value.type, value.period, value.adaptation);
439
434
  },
440
435
  representationChange: function (value) {
441
436
  self.trigger("representationChange", value);
442
- if (cancelSignal.isCancelled) {
437
+ if (cancelSignal.isCancelled()) {
443
438
  return; // Previous call has stopped streams due to a side-effect
444
439
  }
445
440
  contentTimeBoundariesObserver.onRepresentationChange(value.type, value.period);
@@ -449,7 +444,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
449
444
  periodStreamReady: function (value) { return self.trigger("periodStreamReady", value); },
450
445
  periodStreamCleared: function (value) {
451
446
  contentTimeBoundariesObserver.onPeriodCleared(value.type, value.period);
452
- if (cancelSignal.isCancelled) {
447
+ if (cancelSignal.isCancelled()) {
453
448
  return; // Previous call has stopped streams due to a side-effect
454
449
  }
455
450
  self.trigger("periodStreamCleared", value);
@@ -479,7 +474,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
479
474
  for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
480
475
  var protectionData = value_1[_i];
481
476
  protectionRef.setValue(protectionData);
482
- if (cancelSignal.isCancelled) {
477
+ if (cancelSignal.isCancelled()) {
483
478
  return; // Previous call has stopped streams due to a side-effect
484
479
  }
485
480
  }
@@ -528,7 +523,8 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
528
523
  });
529
524
  contentTimeBoundariesObserver.addEventListener("endOfStream", function () {
530
525
  if (endOfStreamCanceller === null) {
531
- endOfStreamCanceller = new TaskCanceller({ cancelOn: cancelSignal });
526
+ endOfStreamCanceller = new TaskCanceller();
527
+ endOfStreamCanceller.linkToSignal(cancelSignal);
532
528
  log.debug("Init: end-of-stream order received.");
533
529
  maintainEndOfStream(mediaSource, endOfStreamCanceller.signal);
534
530
  }
@@ -83,7 +83,7 @@ var ContentTimeBoundariesObserver = /** @class */ (function (_super) {
83
83
  }, { includeLastObservation: true, clearSignal: cancelSignal });
84
84
  manifest.addEventListener("manifestUpdate", function () {
85
85
  _this.trigger("durationUpdate", getManifestDuration());
86
- if (cancelSignal.isCancelled) {
86
+ if (cancelSignal.isCancelled()) {
87
87
  return;
88
88
  }
89
89
  _this._checkEndOfStream();
@@ -128,7 +128,7 @@ var ContentTimeBoundariesObserver = /** @class */ (function (_super) {
128
128
  }
129
129
  }
130
130
  }
131
- if (this._canceller.isUsed) {
131
+ if (this._canceller.isUsed()) {
132
132
  return;
133
133
  }
134
134
  if (adaptation === null) {
@@ -16,8 +16,8 @@
16
16
  import { clearElementSrc, events, MediaSource_, } from "../../../compat";
17
17
  import { MediaError } from "../../../errors";
18
18
  import log from "../../../log";
19
+ import createCancellablePromise from "../../../utils/create_cancellable_promise";
19
20
  import isNonEmptyString from "../../../utils/is_non_empty_string";
20
- import TaskCanceller from "../../../utils/task_canceller";
21
21
  /**
22
22
  * Dispose of ressources taken by the MediaSource:
23
23
  * - Clear the MediaSource' SourceBuffers
@@ -100,19 +100,10 @@ function createMediaSource(mediaElement, unlinkSignal) {
100
100
  * @returns {Promise}
101
101
  */
102
102
  export default function openMediaSource(mediaElement, unlinkSignal) {
103
- return new Promise(function (resolve, reject) {
104
- var hasResolved = false;
103
+ return createCancellablePromise(unlinkSignal, function (resolve) {
105
104
  var mediaSource = createMediaSource(mediaElement, unlinkSignal);
106
- var eventListenerCanceller = new TaskCanceller({ cancelOn: unlinkSignal });
107
105
  events.onSourceOpen(mediaSource, function () {
108
- eventListenerCanceller.cancel();
109
- hasResolved = true;
110
106
  resolve(mediaSource);
111
- }, eventListenerCanceller.signal);
112
- unlinkSignal.register(function (error) {
113
- if (!hasResolved) {
114
- reject(error);
115
- }
116
- });
107
+ }, unlinkSignal);
117
108
  });
118
109
  }
@@ -55,7 +55,8 @@ export default function triggerEndOfStream(mediaSource, cancelSignal) {
55
55
  return;
56
56
  }
57
57
  log.debug("Init: Waiting SourceBuffers to be updated before calling endOfStream.");
58
- var innerCanceller = new TaskCanceller({ cancelOn: cancelSignal });
58
+ var innerCanceller = new TaskCanceller();
59
+ innerCanceller.linkToSignal(cancelSignal);
59
60
  for (var _i = 0, updatingSourceBuffers_1 = updatingSourceBuffers; _i < updatingSourceBuffers_1.length; _i++) {
60
61
  var sourceBuffer = updatingSourceBuffers_1[_i];
61
62
  onSourceBufferUpdate(sourceBuffer, function () {
@@ -75,10 +76,12 @@ export default function triggerEndOfStream(mediaSource, cancelSignal) {
75
76
  * @param {Object} cancelSignal
76
77
  */
77
78
  export function maintainEndOfStream(mediaSource, cancelSignal) {
78
- var endOfStreamCanceller = new TaskCanceller({ cancelOn: cancelSignal });
79
+ var endOfStreamCanceller = new TaskCanceller();
80
+ endOfStreamCanceller.linkToSignal(cancelSignal);
79
81
  onSourceOpen(mediaSource, function () {
80
82
  endOfStreamCanceller.cancel();
81
- endOfStreamCanceller = new TaskCanceller({ cancelOn: cancelSignal });
83
+ endOfStreamCanceller = new TaskCanceller();
84
+ endOfStreamCanceller.linkToSignal(cancelSignal);
82
85
  triggerEndOfStream(mediaSource, endOfStreamCanceller.signal);
83
86
  }, cancelSignal);
84
87
  triggerEndOfStream(mediaSource, endOfStreamCanceller.signal);
@@ -26,7 +26,8 @@ import TaskCanceller from "../../../utils/task_canceller";
26
26
  * @returns {Object}
27
27
  */
28
28
  export default function getLoadedReference(playbackObserver, mediaElement, isDirectfile, cancelSignal) {
29
- var listenCanceller = new TaskCanceller({ cancelOn: cancelSignal });
29
+ var listenCanceller = new TaskCanceller();
30
+ listenCanceller.linkToSignal(cancelSignal);
30
31
  var isLoaded = createSharedReference(false, listenCanceller.signal);
31
32
  playbackObserver.listen(function (observation) {
32
33
  if (observation.rebuffering !== null ||
@@ -42,7 +42,7 @@ export default function performInitialSeekAndPlay(mediaElement, playbackObserver
42
42
  if (mediaElement.readyState >= READY_STATES.HAVE_METADATA) {
43
43
  onLoadedMetadata();
44
44
  }
45
- cancelSignal.register(function (err) {
45
+ var deregisterCancellation = cancelSignal.register(function (err) {
46
46
  mediaElement.removeEventListener("loadedmetadata", onLoadedMetadata);
47
47
  rejectAutoPlay(err);
48
48
  });
@@ -60,7 +60,7 @@ export default function performInitialSeekAndPlay(mediaElement, playbackObserver
60
60
  "falsely announced having loaded the content.");
61
61
  onWarning(error);
62
62
  }
63
- if (cancelSignal.isCancelled) {
63
+ if (cancelSignal.isCancelled()) {
64
64
  return;
65
65
  }
66
66
  playbackObserver.listen(function (observation, stopListening) {
@@ -82,6 +82,7 @@ export default function performInitialSeekAndPlay(mediaElement, playbackObserver
82
82
  }
83
83
  initialPlayPerformed.setValue(true);
84
84
  initialPlayPerformed.finish();
85
+ deregisterCancellation();
85
86
  return resolveAutoPlay({ type: "skipped" });
86
87
  }
87
88
  var playResult;
@@ -89,19 +90,22 @@ export default function performInitialSeekAndPlay(mediaElement, playbackObserver
89
90
  playResult = (_a = mediaElement.play()) !== null && _a !== void 0 ? _a : Promise.resolve();
90
91
  }
91
92
  catch (playError) {
93
+ deregisterCancellation();
92
94
  return rejectAutoPlay(playError);
93
95
  }
94
96
  playResult
95
97
  .then(function () {
96
- if (cancelSignal.isCancelled) {
98
+ if (cancelSignal.isCancelled()) {
97
99
  return;
98
100
  }
99
101
  initialPlayPerformed.setValue(true);
100
102
  initialPlayPerformed.finish();
103
+ deregisterCancellation();
101
104
  return resolveAutoPlay({ type: "autoplay" });
102
105
  })
103
106
  .catch(function (playError) {
104
- if (cancelSignal.isCancelled) {
107
+ deregisterCancellation();
108
+ if (cancelSignal.isCancelled()) {
105
109
  return;
106
110
  }
107
111
  if (playError instanceof Error && playError.name === "NotAllowedError") {
@@ -111,7 +115,7 @@ export default function performInitialSeekAndPlay(mediaElement, playbackObserver
111
115
  var error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY", "Cannot trigger auto-play automatically: " +
112
116
  "your browser does not allow it.");
113
117
  onWarning(error);
114
- if (cancelSignal.isCancelled) {
118
+ if (cancelSignal.isCancelled()) {
115
119
  return;
116
120
  }
117
121
  return resolveAutoPlay({ type: "autoplay-blocked" });
@@ -62,7 +62,8 @@ export default function initializeContentDecryption(mediaElement, keySystems, pr
62
62
  ref.finish(); // We know that no new value will be triggered
63
63
  return ref;
64
64
  }
65
- var decryptorCanceller = new TaskCanceller({ cancelOn: cancelSignal });
65
+ var decryptorCanceller = new TaskCanceller();
66
+ decryptorCanceller.linkToSignal(cancelSignal);
66
67
  var drmStatusRef = createSharedReference({
67
68
  initializationState: { type: "uninitialized", value: null },
68
69
  drmSystemId: undefined,