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
@@ -97,16 +97,16 @@ export default function RepresentationStream<TSegmentDataType>(
97
97
  const bufferType = adaptation.type;
98
98
 
99
99
  /** `TaskCanceller` stopping ALL operations performed by the `RepresentationStream` */
100
- const globalCanceller = new TaskCanceller({ cancelOn: parentCancelSignal });
100
+ const globalCanceller = new TaskCanceller();
101
+ globalCanceller.linkToSignal(parentCancelSignal);
101
102
 
102
103
  /**
103
104
  * `TaskCanceller` allowing to only stop segment loading and checking operations.
104
105
  * This allows to stop only tasks linked to network resource usage, which is
105
106
  * often a limited resource, while still letting buffer operations to finish.
106
107
  */
107
- const segmentsLoadingCanceller = new TaskCanceller({
108
- cancelOn: globalCanceller.signal,
109
- });
108
+ const segmentsLoadingCanceller = new TaskCanceller();
109
+ segmentsLoadingCanceller.linkToSignal(globalCanceller.signal);
110
110
 
111
111
  /** Saved initialization segment state for this representation. */
112
112
  const initSegmentState : IInitSegmentState<TSegmentDataType> = {
@@ -149,7 +149,7 @@ export default function RepresentationStream<TSegmentDataType>(
149
149
  callbacks.encryptionDataEncountered(
150
150
  encryptionData.map(d => objectAssign({ content }, d))
151
151
  );
152
- if (globalCanceller.isUsed) {
152
+ if (globalCanceller.isUsed()) {
153
153
  return ; // previous callback has stopped everything by side-effect
154
154
  }
155
155
  }
@@ -161,7 +161,7 @@ export default function RepresentationStream<TSegmentDataType>(
161
161
  segmentFetcher,
162
162
  hasInitSegment);
163
163
  downloadingQueue.addEventListener("error", (err) => {
164
- if (segmentsLoadingCanceller.signal.isCancelled) {
164
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
165
165
  return; // ignore post requests-cancellation loading-related errors,
166
166
  }
167
167
  globalCanceller.cancel(); // Stop every operations
@@ -172,7 +172,7 @@ export default function RepresentationStream<TSegmentDataType>(
172
172
  downloadingQueue.addEventListener("emptyQueue", checkStatus);
173
173
  downloadingQueue.addEventListener("requestRetry", (payload) => {
174
174
  callbacks.warning(payload.error);
175
- if (segmentsLoadingCanceller.signal.isCancelled) {
175
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
176
176
  return; // If the previous callback led to loading operations being stopped, skip
177
177
  }
178
178
  const retriedSegment = payload.segment;
@@ -218,7 +218,7 @@ export default function RepresentationStream<TSegmentDataType>(
218
218
  * issues at the current time, calling the right callbacks if necessary.
219
219
  */
220
220
  function checkStatus() : void {
221
- if (segmentsLoadingCanceller.isUsed) {
221
+ if (segmentsLoadingCanceller.isUsed()) {
222
222
  return ; // Stop all buffer status checking if load operations are stopped
223
223
  }
224
224
  const observation = playbackObserver.getReference().getValue();
@@ -305,7 +305,7 @@ export default function RepresentationStream<TSegmentDataType>(
305
305
  isEmptyStream: false,
306
306
  hasFinishedLoading: status.hasFinishedLoading,
307
307
  neededSegments: status.neededSegments });
308
- if (segmentsLoadingCanceller.signal.isCancelled) {
308
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
309
309
  return ; // previous callback has stopped loading operations by side-effect
310
310
  }
311
311
  const { UPTO_CURRENT_POSITION_CLEANUP } = config.getCurrent();
@@ -314,7 +314,7 @@ export default function RepresentationStream<TSegmentDataType>(
314
314
  0,
315
315
  initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
316
316
  if (gcedPosition > 0) {
317
- segmentBuffer.removeBuffer(0, gcedPosition, segmentsLoadingCanceller.signal)
317
+ segmentBuffer.removeBuffer(0, gcedPosition, globalCanceller.signal)
318
318
  .catch(onFatalBufferError);
319
319
  }
320
320
  }
@@ -332,7 +332,7 @@ export default function RepresentationStream<TSegmentDataType>(
332
332
  evt : IParsedInitSegmentPayload<TSegmentDataType> |
333
333
  IParsedSegmentPayload<TSegmentDataType>
334
334
  ) : void {
335
- if (globalCanceller.isUsed) {
335
+ if (globalCanceller.isUsed()) {
336
336
  // We should not do anything with segments if the `RepresentationStream`
337
337
  // is not running anymore.
338
338
  return ;
@@ -382,7 +382,7 @@ export default function RepresentationStream<TSegmentDataType>(
382
382
  callbacks.encryptionDataEncountered(
383
383
  allEncryptionData.map(p => objectAssign({ content }, p))
384
384
  );
385
- if (globalCanceller.isUsed) {
385
+ if (globalCanceller.isUsed()) {
386
386
  return ; // previous callback has stopped everything by side-effect
387
387
  }
388
388
  }
@@ -390,13 +390,13 @@ export default function RepresentationStream<TSegmentDataType>(
390
390
 
391
391
  if (needsManifestRefresh === true) {
392
392
  callbacks.needsManifestRefresh();
393
- if (globalCanceller.isUsed) {
393
+ if (globalCanceller.isUsed()) {
394
394
  return ; // previous callback has stopped everything by side-effect
395
395
  }
396
396
  }
397
397
  if (inbandEvents !== undefined && inbandEvents.length > 0) {
398
398
  callbacks.inbandEvent(inbandEvents);
399
- if (globalCanceller.isUsed) {
399
+ if (globalCanceller.isUsed()) {
400
400
  return ; // previous callback has stopped everything by side-effect
401
401
  }
402
402
  }
@@ -425,7 +425,7 @@ export default function RepresentationStream<TSegmentDataType>(
425
425
  * @param {*} err
426
426
  */
427
427
  function onFatalBufferError(err : unknown) : void {
428
- if (globalCanceller.isUsed && err instanceof CancellationError) {
428
+ if (globalCanceller.isUsed() && err instanceof CancellationError) {
429
429
  // The error is linked to cancellation AND we explicitely cancelled buffer
430
430
  // operations.
431
431
  // We can thus ignore it, it is very unlikely to lead to true buffer issues.
@@ -47,7 +47,7 @@ export default async function appendSegmentToBuffer<T>(
47
47
  try {
48
48
  await segmentBuffer.pushChunk(dataInfos, cancellationSignal);
49
49
  } catch (appendError : unknown) {
50
- if (cancellationSignal.isCancelled && appendError instanceof CancellationError) {
50
+ if (cancellationSignal.isCancelled() && appendError instanceof CancellationError) {
51
51
  throw appendError;
52
52
  } else if (!(appendError instanceof Error) ||
53
53
  appendError.name !== "QuotaExceededError")
@@ -28,6 +28,7 @@ import {
28
28
  } from "../../../../transports";
29
29
  import assert from "../../../../utils/assert";
30
30
  import EventEmitter from "../../../../utils/event_emitter";
31
+ import noop from "../../../../utils/noop";
31
32
  import objectAssign from "../../../../utils/object_assign";
32
33
  import createSharedReference, {
33
34
  IReadOnlySharedReference,
@@ -231,6 +232,7 @@ export default class DownloadingQueue<T>
231
232
 
232
233
  public stop() {
233
234
  this._currentCanceller?.cancel();
235
+ this._currentCanceller = null;
234
236
  }
235
237
 
236
238
  /**
@@ -245,7 +247,7 @@ export default class DownloadingQueue<T>
245
247
  const recursivelyRequestSegments = (
246
248
  startingSegment : IQueuedSegment | undefined
247
249
  ) : void => {
248
- if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
250
+ if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
249
251
  this._mediaSegmentRequest = null;
250
252
  return;
251
253
  }
@@ -254,7 +256,10 @@ export default class DownloadingQueue<T>
254
256
  this.trigger("emptyQueue", null);
255
257
  return;
256
258
  }
257
- const canceller = new TaskCanceller({ cancelOn: this._currentCanceller?.signal });
259
+ const canceller = new TaskCanceller();
260
+ const unlinkCanceller = this._currentCanceller === null ?
261
+ noop :
262
+ canceller.linkToSignal(this._currentCanceller.signal);
258
263
 
259
264
  const { segment, priority } = startingSegment;
260
265
  const context = objectAssign({ segment }, this._content);
@@ -368,6 +373,7 @@ export default class DownloadingQueue<T>
368
373
  * requests are scheduled. It is used to schedule the next segment.
369
374
  */
370
375
  beforeEnded: () : void => {
376
+ unlinkCanceller();
371
377
  this._mediaSegmentRequest = null;
372
378
 
373
379
  if (isWaitingOnInitSegment) {
@@ -381,6 +387,7 @@ export default class DownloadingQueue<T>
381
387
  }, canceller.signal);
382
388
 
383
389
  request.catch((error : unknown) => {
390
+ unlinkCanceller();
384
391
  if (!isComplete) {
385
392
  isComplete = true;
386
393
  this.stop();
@@ -400,7 +407,7 @@ export default class DownloadingQueue<T>
400
407
  private _restartInitSegmentDownloadingQueue(
401
408
  queuedInitSegment : IQueuedSegment | null
402
409
  ) : void {
403
- if (this._currentCanceller !== null && this._currentCanceller.isUsed) {
410
+ if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
404
411
  return;
405
412
  }
406
413
  if (this._initSegmentRequest !== null) {
@@ -410,7 +417,10 @@ export default class DownloadingQueue<T>
410
417
  return ;
411
418
  }
412
419
 
413
- const canceller = new TaskCanceller({ cancelOn: this._currentCanceller?.signal });
420
+ const canceller = new TaskCanceller();
421
+ const unlinkCanceller = this._currentCanceller === null ?
422
+ noop :
423
+ canceller.linkToSignal(this._currentCanceller.signal);
414
424
  const { segment, priority } = queuedInitSegment;
415
425
  const context = objectAssign({ segment }, this._content);
416
426
 
@@ -428,6 +438,7 @@ export default class DownloadingQueue<T>
428
438
  log.info("Stream: init segment request interrupted temporarly.", segment.id);
429
439
  },
430
440
  beforeEnded: () => {
441
+ unlinkCanceller();
431
442
  this._initSegmentRequest = null;
432
443
  isComplete = true;
433
444
  },
@@ -446,6 +457,7 @@ export default class DownloadingQueue<T>
446
457
  }, canceller.signal);
447
458
 
448
459
  request.catch((error : unknown) => {
460
+ unlinkCanceller();
449
461
  if (!isComplete) {
450
462
  isComplete = true;
451
463
  this.stop();
@@ -923,15 +923,36 @@ const DEFAULT_CONFIG = {
923
923
  */
924
924
  MIN_CANCELABLE_PRIORITY: 3, // priority number 3 onward can be cancelled
925
925
 
926
- /**
927
- * Robustnesses used in the {audio,video}Capabilities of the
928
- * MediaKeySystemConfiguration (DRM).
929
- *
930
- * Only used for widevine keysystems.
931
- *
932
- * Defined in order of importance (first will be tested first etc.)
933
- * @type {Array.<string>}
934
- */
926
+ /**
927
+ * Codecs used in the videoCapabilities of the MediaKeySystemConfiguration
928
+ * (DRM).
929
+ *
930
+ * Defined in order of importance (first will be tested first etc.)
931
+ * @type {Array.<string>}
932
+ */
933
+ EME_DEFAULT_VIDEO_CODECS: [ "video/mp4;codecs=\"avc1.4d401e\"",
934
+ "video/mp4;codecs=\"avc1.42e01e\"",
935
+ "video/webm;codecs=\"vp8\"" ],
936
+
937
+ /**
938
+ * Codecs used in the audioCapabilities of the MediaKeySystemConfiguration
939
+ * (DRM).
940
+ *
941
+ * Defined in order of importance (first will be tested first etc.)
942
+ * @type {Array.<string>}
943
+ */
944
+ EME_DEFAULT_AUDIO_CODECS: [ "audio/mp4;codecs=\"mp4a.40.2\"",
945
+ "audio/webm;codecs=opus" ],
946
+
947
+ /**
948
+ * Robustnesses used in the {audio,video}Capabilities of the
949
+ * MediaKeySystemConfiguration (DRM).
950
+ *
951
+ * Only used for widevine keysystems.
952
+ *
953
+ * Defined in order of importance (first will be tested first etc.)
954
+ * @type {Array.<string>}
955
+ */
935
956
  EME_DEFAULT_WIDEVINE_ROBUSTNESSES: [ "HW_SECURE_ALL",
936
957
  "HW_SECURE_DECODE",
937
958
  "HW_SECURE_CRYPTO",
@@ -0,0 +1,26 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
3
+ /* eslint-disable @typescript-eslint/no-var-requires */
4
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
5
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
6
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
7
+
8
+ describe("Features list - DEBUG_ELEMENT", () => {
9
+ beforeEach(() => {
10
+ jest.resetModules();
11
+ });
12
+
13
+ it("should add DEBUG_ELEMENT in the current features", () => {
14
+ const feat = {};
15
+ jest.mock("../../../core/api/debug", () => ({ __esModule: true as const,
16
+ default: feat }));
17
+ const addFeature = jest.requireActual("../debug_element").default;
18
+
19
+ const featureObject : {
20
+ createDebugElement? : unknown;
21
+ } = {};
22
+ addFeature(featureObject);
23
+ expect(featureObject).toEqual({ createDebugElement: {} });
24
+ expect(featureObject.createDebugElement).toBe(feat);
25
+ });
26
+ });
@@ -0,0 +1,13 @@
1
+ import createDebugElement from "../../core/api/debug";
2
+ import { IFeaturesObject } from "../../features/types";
3
+
4
+ /**
5
+ * Add ability to parse SAMI text tracks in an HTML textrack mode.
6
+ * @param {Object} features
7
+ */
8
+ function addDebugElementFeature(features : IFeaturesObject) : void {
9
+ features.createDebugElement = createDebugElement;
10
+ }
11
+
12
+ export { addDebugElementFeature as DEBUG_ELEMENT };
13
+ export default addDebugElementFeature;
@@ -15,5 +15,6 @@
15
15
  */
16
16
 
17
17
  export { DASH_WASM } from "./dash_wasm";
18
+ export { DEBUG_ELEMENT } from "./debug_element";
18
19
  export { LOCAL_MANIFEST } from "./local";
19
20
  export { METAPLAYLIST } from "./metaplaylist";
@@ -18,6 +18,7 @@ import { MediaSource_ } from "../../../compat";
18
18
  import { resetMediaSource } from "../../../core/init/utils/create_media_source";
19
19
  import { AudioVideoSegmentBuffer } from "../../../core/segment_buffers/implementations";
20
20
  import log from "../../../log";
21
+ import createCancellablePromise from "../../../utils/create_cancellable_promise";
21
22
  import isNonEmptyString from "../../../utils/is_non_empty_string";
22
23
  import { CancellationSignal } from "../../../utils/task_canceller";
23
24
 
@@ -33,7 +34,7 @@ export default function prepareSourceBuffer(
33
34
  codec: string,
34
35
  cleanUpSignal: CancellationSignal
35
36
  ): Promise<AudioVideoSegmentBuffer> {
36
- return new Promise((resolve, reject) => {
37
+ return createCancellablePromise(cleanUpSignal, (resolve, reject) => {
37
38
  if (MediaSource_ == null) {
38
39
  throw new Error("No MediaSource Object was found in the current browser.");
39
40
  }
@@ -49,15 +50,17 @@ export default function prepareSourceBuffer(
49
50
 
50
51
  log.info("Init: Attaching MediaSource URL to the media element", objectURL);
51
52
  videoElement.src = objectURL;
53
+ cleanUpSignal.register(() => {
54
+ resetMediaSource(videoElement, mediaSource, objectURL);
55
+ });
52
56
 
53
57
  mediaSource.addEventListener("sourceopen", onSourceOpen);
54
58
  mediaSource.addEventListener("webkitsourceopen", onSourceOpen);
55
59
 
56
- cleanUpSignal.register(() => {
60
+ return () => {
57
61
  mediaSource.removeEventListener("sourceopen", onSourceOpen);
58
62
  mediaSource.removeEventListener("webkitsourceopen", onSourceOpen);
59
- resetMediaSource(videoElement, mediaSource, objectURL);
60
- });
63
+ };
61
64
 
62
65
  function onSourceOpen() {
63
66
  try {
@@ -243,15 +243,19 @@ export default class VideoThumbnailLoader {
243
243
  if (pending !== undefined) {
244
244
  promises.push(pending.promise);
245
245
  } else {
246
- const requestCanceller = new TaskCanceller({
247
- cancelOn: lastRepInfo.cleaner.signal,
248
- });
246
+ const requestCanceller = new TaskCanceller();
247
+ const unlinkSignal = requestCanceller
248
+ .linkToSignal(lastRepInfo.cleaner.signal);
249
249
  const segmentInfo = objectAssign({ segment },
250
250
  content);
251
251
  const prom = loadAndPushSegment(segmentInfo,
252
252
  segmentBuffer,
253
253
  lastRepInfo.segmentFetcher,
254
- requestCanceller.signal);
254
+ requestCanceller.signal)
255
+ .then(unlinkSignal, (err) => {
256
+ unlinkSignal();
257
+ throw err;
258
+ });
255
259
  const newReq = {
256
260
  segmentId: segment.id,
257
261
  canceller: requestCanceller,
@@ -48,6 +48,7 @@ describe("Features - initializeFeaturesObject", () => {
48
48
  HTML_VTT: 0,
49
49
  LOCAL_MANIFEST: 0,
50
50
  METAPLAYLIST: 0,
51
+ DEBUG_ELEMENT: 0,
51
52
  NATIVE_SAMI: 0,
52
53
  NATIVE_SRT: 0,
53
54
  NATIVE_TTML: 0,
@@ -78,6 +79,7 @@ describe("Features - initializeFeaturesObject", () => {
78
79
  HTML_VTT: 1,
79
80
  LOCAL_MANIFEST: 1,
80
81
  METAPLAYLIST: 1,
82
+ DEBUG_ELEMENT: 1,
81
83
  NATIVE_SAMI: 1,
82
84
  NATIVE_SRT: 1,
83
85
  NATIVE_TTML: 1,
@@ -114,6 +116,7 @@ describe("Features - initializeFeaturesObject", () => {
114
116
  wasm: null,
115
117
  },
116
118
  ContentDecryptor: jest.requireActual("../../core/decrypt/index").default,
119
+ createDebugElement: jest.requireActual("../../core/api/debug").default,
117
120
  directfile: {
118
121
  initDirectFile: jest.requireActual("../../core/init/directfile_content_initializer").default,
119
122
  mediaElementTrackChoiceManager:
@@ -161,6 +164,7 @@ describe("Features - initializeFeaturesObject", () => {
161
164
  HTML_VTT: 1,
162
165
  LOCAL_MANIFEST: 0,
163
166
  METAPLAYLIST: 0,
167
+ DEBUG_ELEMENT: 0,
164
168
  NATIVE_SAMI: 0,
165
169
  NATIVE_SRT: 0,
166
170
  NATIVE_TTML: 0,
@@ -203,6 +207,7 @@ describe("Features - initializeFeaturesObject", () => {
203
207
  HTML_VTT: 0,
204
208
  LOCAL_MANIFEST: 0,
205
209
  METAPLAYLIST: 0,
210
+ DEBUG_ELEMENT: 0,
206
211
  NATIVE_SAMI: 0,
207
212
  NATIVE_SRT: 0,
208
213
  NATIVE_TTML: 0,
@@ -245,6 +250,7 @@ describe("Features - initializeFeaturesObject", () => {
245
250
  HTML_VTT: 0,
246
251
  LOCAL_MANIFEST: 0,
247
252
  METAPLAYLIST: 0,
253
+ DEBUG_ELEMENT: 0,
248
254
  NATIVE_SAMI: 0,
249
255
  NATIVE_SRT: 0,
250
256
  NATIVE_TTML: 0,
@@ -287,6 +293,7 @@ describe("Features - initializeFeaturesObject", () => {
287
293
  HTML_VTT: 0,
288
294
  LOCAL_MANIFEST: 0,
289
295
  METAPLAYLIST: 0,
296
+ DEBUG_ELEMENT: 0,
290
297
  NATIVE_SAMI: 0,
291
298
  NATIVE_SRT: 0,
292
299
  NATIVE_TTML: 0,
@@ -329,6 +336,7 @@ describe("Features - initializeFeaturesObject", () => {
329
336
  HTML_VTT: 0,
330
337
  LOCAL_MANIFEST: 0,
331
338
  METAPLAYLIST: 0,
339
+ DEBUG_ELEMENT: 0,
332
340
  NATIVE_SAMI: 0,
333
341
  NATIVE_SRT: 0,
334
342
  NATIVE_TTML: 0,
@@ -371,6 +379,7 @@ describe("Features - initializeFeaturesObject", () => {
371
379
  HTML_VTT: 0,
372
380
  LOCAL_MANIFEST: 0,
373
381
  METAPLAYLIST: 0,
382
+ DEBUG_ELEMENT: 0,
374
383
  NATIVE_SAMI: 1,
375
384
  NATIVE_SRT: 0,
376
385
  NATIVE_TTML: 0,
@@ -413,6 +422,7 @@ describe("Features - initializeFeaturesObject", () => {
413
422
  HTML_VTT: 0,
414
423
  LOCAL_MANIFEST: 0,
415
424
  METAPLAYLIST: 0,
425
+ DEBUG_ELEMENT: 0,
416
426
  NATIVE_SAMI: 0,
417
427
  NATIVE_SRT: 0,
418
428
  NATIVE_TTML: 1,
@@ -455,6 +465,7 @@ describe("Features - initializeFeaturesObject", () => {
455
465
  HTML_VTT: 0,
456
466
  LOCAL_MANIFEST: 0,
457
467
  METAPLAYLIST: 0,
468
+ DEBUG_ELEMENT: 0,
458
469
  NATIVE_SAMI: 0,
459
470
  NATIVE_SRT: 1,
460
471
  NATIVE_TTML: 0,
@@ -22,6 +22,7 @@ import { IFeaturesObject } from "./types";
22
22
  */
23
23
  const features : IFeaturesObject = { dashParsers: { wasm: null,
24
24
  js: null },
25
+ createDebugElement: null,
25
26
  directfile: null,
26
27
  ContentDecryptor: null,
27
28
  htmlTextTracksBuffer: null,
@@ -37,10 +37,11 @@ export default function initializeFeaturesObject() : void {
37
37
  }
38
38
 
39
39
  // Feature switching the Native TextTrack implementation
40
- const HAS_NATIVE_MODE = __FEATURES__.NATIVE_VTT ||
41
- __FEATURES__.NATIVE_SAMI ||
42
- __FEATURES__.NATIVE_TTML ||
43
- __FEATURES__.NATIVE_SRT;
40
+ const HAS_NATIVE_MODE =
41
+ __FEATURES__.NATIVE_VTT === __FEATURES__.IS_ENABLED as number ||
42
+ __FEATURES__.NATIVE_SAMI === __FEATURES__.IS_ENABLED as number ||
43
+ __FEATURES__.NATIVE_TTML === __FEATURES__.IS_ENABLED as number ||
44
+ __FEATURES__.NATIVE_SRT === __FEATURES__.IS_ENABLED as number;
44
45
 
45
46
  if (__FEATURES__.SMOOTH === __FEATURES__.IS_ENABLED as number) {
46
47
  features.transports.smooth = require("../transports/smooth/index.ts").default;
@@ -57,8 +58,11 @@ export default function initializeFeaturesObject() : void {
57
58
  features.transports.metaplaylist =
58
59
  require("../transports/metaplaylist/index.ts").default;
59
60
  }
61
+ if (__FEATURES__.DEBUG_ELEMENT === __FEATURES__.IS_ENABLED as number) {
62
+ features.createDebugElement = require("../core/api/debug/index.ts").default;
63
+ }
60
64
 
61
- if (HAS_NATIVE_MODE === __FEATURES__.IS_ENABLED as number) {
65
+ if (HAS_NATIVE_MODE) {
62
66
  features.nativeTextTracksBuffer =
63
67
  require("../core/segment_buffers/implementations/text/native/index.ts").default;
64
68
  if (__FEATURES__.NATIVE_VTT === __FEATURES__.IS_ENABLED as number) {
@@ -83,12 +87,13 @@ export default function initializeFeaturesObject() : void {
83
87
  }
84
88
 
85
89
  // Feature switching the HTML TextTrack implementation
86
- const HAS_HTML_MODE = __FEATURES__.HTML_VTT ||
87
- __FEATURES__.HTML_SAMI ||
88
- __FEATURES__.HTML_TTML ||
89
- __FEATURES__.HTML_SRT;
90
+ const HAS_HTML_MODE =
91
+ __FEATURES__.HTML_VTT === __FEATURES__.IS_ENABLED as number ||
92
+ __FEATURES__.HTML_SAMI === __FEATURES__.IS_ENABLED as number ||
93
+ __FEATURES__.HTML_TTML === __FEATURES__.IS_ENABLED as number ||
94
+ __FEATURES__.HTML_SRT === __FEATURES__.IS_ENABLED as number;
90
95
 
91
- if (HAS_HTML_MODE === __FEATURES__.IS_ENABLED as number) {
96
+ if (HAS_HTML_MODE) {
92
97
  features.htmlTextTracksBuffer =
93
98
  require("../core/segment_buffers/implementations/text/html/index.ts").default;
94
99
  if (__FEATURES__.HTML_SAMI === __FEATURES__.IS_ENABLED as number) {
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import RxPlayer from "../core/api";
17
18
  // eslint-disable-next-line max-len
18
19
  import MediaElementTrackChoiceManager from "../core/api/tracks_management/media_element_track_choice_manager";
19
20
  import type ContentDecryptor from "../core/decrypt";
@@ -29,6 +30,7 @@ import {
29
30
  INativeTextTracksParserFn,
30
31
  } from "../parsers/texttracks";
31
32
  import { ITransportFunction } from "../transports";
33
+ import { CancellationSignal } from "../utils/task_canceller";
32
34
 
33
35
  export type IDirectFileInit = typeof DirectFileContentInitializer;
34
36
 
@@ -78,6 +80,13 @@ export interface IFeaturesObject {
78
80
  mediaElementTrackChoiceManager : IMediaElementTrackChoiceManager; } |
79
81
  null;
80
82
  ContentDecryptor : IContentDecryptorClass|null;
83
+ createDebugElement : (
84
+ (
85
+ parentElt : HTMLElement,
86
+ instance : RxPlayer,
87
+ cancelSignal : CancellationSignal
88
+ ) => void
89
+ ) | null;
81
90
  htmlTextTracksBuffer : IHTMLTextTracksBuffer|null;
82
91
  htmlTextTracksParsers : Partial<Record<string, IHTMLTextTracksParserFn>>;
83
92
  imageBuffer : IImageBuffer|null;
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import log from "../log";
17
18
  import { IParsedAdaptation } from "../parsers/manifest";
18
19
  import { IRepresentationFilter } from "../public_types";
19
20
  import arrayFind from "../utils/array_find";
@@ -164,6 +165,12 @@ export default class Adaptation {
164
165
  if (!isSupported && representation.isSupported) {
165
166
  isSupported = true;
166
167
  }
168
+ } else {
169
+ log.debug("Filtering Representation due to representationFilter",
170
+ this.type,
171
+ `Adaptation: ${this.id}`,
172
+ `Representation: ${representation.id}`,
173
+ `(${representation.bitrate})`);
167
174
  }
168
175
  }
169
176
  representations.sort((a, b) => a.bitrate - b.bitrate);
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import { MediaError } from "../errors";
18
+ import log from "../log";
18
19
  import { IParsedManifest } from "../parsers/manifest";
19
20
  import {
20
21
  IPlayerError,
@@ -786,6 +787,9 @@ function updateDeciperability(
786
787
  const result = isDecipherable(representation);
787
788
  if (result !== representation.decipherable) {
788
789
  updates.push({ manifest, period, adaptation, representation });
790
+ log.debug(`Decipherability changed for "${representation.id}"`,
791
+ `(${representation.bitrate})`,
792
+ String(representation.decipherable));
789
793
  representation.decipherable = result;
790
794
  }
791
795
  }
@@ -145,10 +145,16 @@ class Representation {
145
145
  this.cdnMetadata = args.cdnMetadata;
146
146
 
147
147
  this.index = args.index;
148
- this.isSupported = opts.type === "audio" ||
149
- opts.type === "video" ?
150
- isCodecSupported(this.getMimeTypeString()) :
151
- true; // TODO for other types
148
+ if (opts.type === "audio" || opts.type === "video") {
149
+ const mimeTypeStr = this.getMimeTypeString();
150
+ const isSupported = isCodecSupported(mimeTypeStr);
151
+ if (!isSupported) {
152
+ log.info("Unsupported Representation", mimeTypeStr, this.id, this.bitrate);
153
+ }
154
+ this.isSupported = isSupported;
155
+ } else {
156
+ this.isSupported = true; // TODO for other types
157
+ }
152
158
  }
153
159
 
154
160
  /**