rx-player 3.29.0-dev.2022090500 → 3.29.0-dev.2022091600

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 (142) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/core/api/option_utils.js +7 -11
  4. package/dist/_esm5.processed/core/api/public_api.d.ts +4 -4
  5. package/dist/_esm5.processed/core/api/public_api.js +18 -19
  6. package/dist/_esm5.processed/core/api/{media_element_track_choice_manager.d.ts → tracks_management/media_element_track_choice_manager.d.ts} +2 -2
  7. package/dist/_esm5.processed/core/api/{media_element_track_choice_manager.js → tracks_management/media_element_track_choice_manager.js} +7 -4
  8. package/dist/_esm5.processed/core/api/{track_choice_manager.d.ts → tracks_management/track_choice_manager.d.ts} +2 -2
  9. package/dist/_esm5.processed/core/api/{track_choice_manager.js → tracks_management/track_choice_manager.js} +7 -7
  10. package/dist/_esm5.processed/core/api/{emit_seek_events.d.ts → utils.d.ts} +24 -1
  11. package/dist/_esm5.processed/core/api/{emit_seek_events.js → utils.js} +32 -1
  12. package/dist/_esm5.processed/core/decrypt/content_decryptor.d.ts +26 -0
  13. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +101 -9
  14. package/dist/_esm5.processed/core/decrypt/session_events_listener.d.ts +15 -18
  15. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +9 -7
  16. package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.d.ts +19 -22
  17. package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +87 -16
  18. package/dist/_esm5.processed/core/decrypt/utils/persistent_sessions_store.d.ts +1 -2
  19. package/dist/_esm5.processed/core/decrypt/utils/persistent_sessions_store.js +1 -2
  20. package/dist/_esm5.processed/core/fetchers/index.d.ts +2 -2
  21. package/dist/_esm5.processed/core/fetchers/segment/index.d.ts +2 -3
  22. package/dist/_esm5.processed/core/fetchers/segment/prioritized_segment_fetcher.d.ts +9 -9
  23. package/dist/_esm5.processed/core/fetchers/segment/prioritized_segment_fetcher.js +17 -15
  24. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +33 -40
  25. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +156 -153
  26. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +3 -3
  27. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +2 -2
  28. package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.d.ts +145 -0
  29. package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +325 -0
  30. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.d.ts +2 -2
  31. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +3 -3
  32. package/dist/_esm5.processed/core/init/create_media_source.d.ts +10 -0
  33. package/dist/_esm5.processed/core/init/create_media_source.js +1 -1
  34. package/dist/_esm5.processed/core/init/stall_avoider.d.ts +2 -1
  35. package/dist/_esm5.processed/core/init/stall_avoider.js +2 -1
  36. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +1 -1
  37. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +3 -3
  38. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +6 -2
  39. package/dist/_esm5.processed/core/stream/orchestrator/{get_blacklisted_ranges.d.ts → get_time_ranges_for_content.d.ts} +1 -1
  40. package/dist/_esm5.processed/core/stream/orchestrator/{get_blacklisted_ranges.js → get_time_ranges_for_content.js} +1 -1
  41. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +61 -19
  42. package/dist/_esm5.processed/core/stream/representation/downloading_queue.d.ts +8 -4
  43. package/dist/_esm5.processed/core/stream/representation/downloading_queue.js +200 -83
  44. package/dist/_esm5.processed/core/stream/types.d.ts +3 -1
  45. package/dist/_esm5.processed/errors/encrypted_media_error.d.ts +6 -1
  46. package/dist/_esm5.processed/errors/encrypted_media_error.js +4 -5
  47. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/index.d.ts +1 -1
  48. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/index.js +1 -1
  49. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.d.ts +26 -0
  50. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.js +60 -0
  51. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.d.ts +6 -5
  52. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +40 -9
  53. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.d.ts +3 -2
  54. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.js +7 -14
  55. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/types.d.ts +1 -1
  56. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/{thumbnail_loader.d.ts → video_thumbnail_loader.d.ts} +1 -13
  57. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +331 -0
  58. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.d.ts +1 -2
  59. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.js +1 -2
  60. package/dist/_esm5.processed/features/initialize_features.js +2 -1
  61. package/dist/_esm5.processed/features/list/directfile.js +1 -1
  62. package/dist/_esm5.processed/features/types.d.ts +1 -1
  63. package/dist/_esm5.processed/manifest/index.d.ts +2 -2
  64. package/dist/_esm5.processed/public_types.d.ts +47 -0
  65. package/dist/_esm5.processed/utils/reference.d.ts +23 -3
  66. package/dist/_esm5.processed/utils/reference.js +23 -2
  67. package/dist/rx-player.js +1253 -1014
  68. package/dist/rx-player.min.js +1 -1
  69. package/package.json +1 -1
  70. package/sonar-project.properties +1 -1
  71. package/src/core/api/README.md +1 -1
  72. package/src/core/api/__tests__/{get_player_state.test.ts → utils.test.ts} +1 -1
  73. package/src/core/api/option_utils.ts +1 -5
  74. package/src/core/api/public_api.ts +15 -13
  75. package/src/core/api/{__tests__ → tracks_management/__tests__}/media_element_track_choice_manager.test.ts +0 -0
  76. package/src/core/api/{media_element_track_choice_manager.ts → tracks_management/media_element_track_choice_manager.ts} +10 -7
  77. package/src/core/api/{track_choice_manager.ts → tracks_management/track_choice_manager.ts} +9 -9
  78. package/src/core/api/{get_player_state.ts → utils.ts} +62 -11
  79. package/src/core/decrypt/content_decryptor.ts +112 -13
  80. package/src/core/decrypt/session_events_listener.ts +34 -30
  81. package/src/core/decrypt/utils/check_key_statuses.ts +89 -45
  82. package/src/core/decrypt/utils/persistent_sessions_store.ts +1 -2
  83. package/src/core/fetchers/index.ts +0 -12
  84. package/src/core/fetchers/segment/__tests__/task_prioritizer.test.ts +763 -0
  85. package/src/core/fetchers/segment/index.ts +0 -12
  86. package/src/core/fetchers/segment/prioritized_segment_fetcher.ts +40 -47
  87. package/src/core/fetchers/segment/segment_fetcher.ts +249 -268
  88. package/src/core/fetchers/segment/segment_fetcher_creator.ts +6 -7
  89. package/src/core/fetchers/segment/task_prioritizer.ts +460 -0
  90. package/src/core/fetchers/utils/try_urls_with_backoff.ts +3 -3
  91. package/src/core/init/create_media_source.ts +1 -1
  92. package/src/core/init/stall_avoider.ts +2 -1
  93. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +1 -1
  94. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +3 -3
  95. package/src/core/segment_buffers/implementations/types.ts +6 -2
  96. package/src/core/stream/orchestrator/{get_blacklisted_ranges.ts → get_time_ranges_for_content.ts} +1 -1
  97. package/src/core/stream/orchestrator/stream_orchestrator.ts +115 -56
  98. package/src/core/stream/representation/downloading_queue.ts +269 -142
  99. package/src/core/stream/types.ts +3 -1
  100. package/src/errors/encrypted_media_error.ts +20 -1
  101. package/src/experimental/tools/VideoThumbnailLoader/index.ts +1 -1
  102. package/src/experimental/tools/VideoThumbnailLoader/load_and_push_segment.ts +74 -0
  103. package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +50 -16
  104. package/src/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.ts +14 -21
  105. package/src/experimental/tools/VideoThumbnailLoader/types.ts +7 -4
  106. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +407 -0
  107. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.ts +1 -2
  108. package/src/features/__tests__/initialize_features.test.ts +3 -1
  109. package/src/features/initialize_features.ts +2 -1
  110. package/src/features/list/__tests__/directfile.test.ts +1 -1
  111. package/src/features/list/directfile.ts +1 -1
  112. package/src/features/types.ts +1 -1
  113. package/src/manifest/index.ts +2 -0
  114. package/src/public_types.ts +53 -0
  115. package/src/utils/reference.ts +58 -4
  116. package/dist/_esm5.processed/core/api/get_player_state.d.ts +0 -28
  117. package/dist/_esm5.processed/core/api/get_player_state.js +0 -56
  118. package/dist/_esm5.processed/core/fetchers/segment/prioritizer.d.ts +0 -232
  119. package/dist/_esm5.processed/core/fetchers/segment/prioritizer.js +0 -422
  120. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/create_request.d.ts +0 -29
  121. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/create_request.js +0 -68
  122. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_complete_segment_id.d.ts +0 -24
  123. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_complete_segment_id.js +0 -29
  124. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_content_infos.d.ts +0 -25
  125. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_content_infos.js +0 -40
  126. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.d.ts +0 -33
  127. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +0 -124
  128. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_segments.d.ts +0 -17
  129. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_segments.js +0 -41
  130. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.d.ts +0 -22
  131. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.js +0 -21
  132. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +0 -212
  133. package/src/core/api/emit_seek_events.ts +0 -66
  134. package/src/core/fetchers/segment/__tests__/prioritizer.test.ts +0 -962
  135. package/src/core/fetchers/segment/prioritizer.ts +0 -558
  136. package/src/experimental/tools/VideoThumbnailLoader/create_request.ts +0 -113
  137. package/src/experimental/tools/VideoThumbnailLoader/get_complete_segment_id.ts +0 -34
  138. package/src/experimental/tools/VideoThumbnailLoader/get_content_infos.ts +0 -48
  139. package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +0 -171
  140. package/src/experimental/tools/VideoThumbnailLoader/load_segments.ts +0 -69
  141. package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +0 -48
  142. package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +0 -311
@@ -13,12 +13,11 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { map, } from "rxjs";
17
16
  import log from "../../../log";
18
17
  /**
19
18
  * This function basically put in relation:
20
19
  * - an `ISegmentFetcher`, which will be used to perform the segment requests
21
- * - a prioritizer, which will handle the priority of a segment request
20
+ * - a `TaskPrioritizer`, which will handle the priority of a segment request
22
21
  *
23
22
  * and returns functions to fetch segments with a given priority.
24
23
  * @param {Object} prioritizer
@@ -26,7 +25,11 @@ import log from "../../../log";
26
25
  * @returns {Object}
27
26
  */
28
27
  export default function applyPrioritizerToSegmentFetcher(prioritizer, fetcher) {
29
- /** Map returned task to the task as returned by the `ObservablePrioritizer`. */
28
+ /**
29
+ * Map Promises returned by the `createRequest` method into the actual tasks
30
+ * used by the `TaskPrioritizer`, allowing to update task priorities just by
31
+ * using the Promise.
32
+ */
30
33
  var taskHandlers = new WeakMap();
31
34
  return {
32
35
  /**
@@ -34,26 +37,25 @@ export default function applyPrioritizerToSegmentFetcher(prioritizer, fetcher) {
34
37
  * @param {Object} content - content to request
35
38
  * @param {Number} priority - priority at which the content should be requested.
36
39
  * Lower number == higher priority.
37
- * @returns {Observable}
40
+ * @returns {Promise}
38
41
  */
39
- createRequest: function (content, priority) {
42
+ createRequest: function (content, priority, callbacks, cancelSignal) {
40
43
  if (priority === void 0) { priority = 0; }
41
- var task = prioritizer.create(fetcher(content), priority);
42
- var flattenTask = task.pipe(map(function (evt) {
43
- return evt.type === "data" ? evt.value :
44
- evt;
45
- }));
46
- taskHandlers.set(flattenTask, task);
47
- return flattenTask;
44
+ var givenTask = function (innerCancelSignal) {
45
+ return fetcher(content, callbacks, innerCancelSignal);
46
+ };
47
+ var ret = prioritizer.create(givenTask, priority, callbacks, cancelSignal);
48
+ taskHandlers.set(ret, givenTask);
49
+ return ret;
48
50
  },
49
51
  /**
50
52
  * Update the priority of a pending request, created through
51
53
  * `createRequest`.
52
- * @param {Observable} observable - The Observable returned by `createRequest`.
54
+ * @param {Promise} task - The Promise returned by `createRequest`.
53
55
  * @param {Number} priority - The new priority value.
54
56
  */
55
- updatePriority: function (observable, priority) {
56
- var correspondingTask = taskHandlers.get(observable);
57
+ updatePriority: function (task, priority) {
58
+ var correspondingTask = taskHandlers.get(task);
57
59
  if (correspondingTask === undefined) {
58
60
  log.warn("Fetchers: Cannot update the priority of a request: task not found.");
59
61
  return;
@@ -13,10 +13,10 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Observable } from "rxjs";
17
16
  import Manifest, { Adaptation, ISegment, Period, Representation } from "../../../manifest";
18
17
  import { IPlayerError } from "../../../public_types";
19
18
  import { ISegmentParserParsedInitChunk, ISegmentParserParsedMediaChunk, ISegmentPipeline } from "../../../transports";
19
+ import { CancellationSignal } from "../../../utils/task_canceller";
20
20
  import { IMetricsCallbackPayload, IRequestBeginCallbackPayload, IRequestEndCallbackPayload, IRequestProgressCallbackPayload } from "../../adaptive";
21
21
  import { IBufferType } from "../../segment_buffers";
22
22
  /**
@@ -27,40 +27,42 @@ import { IBufferType } from "../../segment_buffers";
27
27
  *
28
28
  * @param {string} bufferType
29
29
  * @param {Object} pipeline
30
- * @param {Object} callbacks
30
+ * @param {Object} lifecycleCallbacks
31
31
  * @param {Object} options
32
32
  * @returns {Function}
33
33
  */
34
- export default function createSegmentFetcher<TLoadedFormat, TSegmentDataType>(bufferType: IBufferType, pipeline: ISegmentPipeline<TLoadedFormat, TSegmentDataType>, callbacks: ISegmentFetcherCreatorCallbacks, options: ISegmentFetcherOptions): ISegmentFetcher<TSegmentDataType>;
35
- export declare type ISegmentFetcher<TSegmentDataType> = (content: ISegmentLoaderContent) => Observable<ISegmentFetcherEvent<TSegmentDataType>>;
36
- /** Event sent by the SegmentFetcher when fetching a segment. */
37
- export declare type ISegmentFetcherEvent<TSegmentDataType> = ISegmentFetcherChunkEvent<TSegmentDataType> | ISegmentFetcherChunkCompleteEvent | ISegmentFetcherRetry;
34
+ export default function createSegmentFetcher<TLoadedFormat, TSegmentDataType>(bufferType: IBufferType, pipeline: ISegmentPipeline<TLoadedFormat, TSegmentDataType>, lifecycleCallbacks: ISegmentFetcherLifecycleCallbacks, options: ISegmentFetcherOptions): ISegmentFetcher<TSegmentDataType>;
38
35
  /**
39
- * Event sent when a new "chunk" of the segment is available.
40
- * A segment can contain n chunk(s) for n >= 0.
36
+ * Defines the `ISegmentFetcher` function which allows to load a single segment.
37
+ *
38
+ * Loaded data is entirely communicated through callbacks present in the
39
+ * `callbacks` arguments.
40
+ *
41
+ * The returned Promise only gives an indication of if the request ended with
42
+ * success or on error.
41
43
  */
42
- export interface ISegmentFetcherChunkEvent<TSegmentDataType> {
43
- type: "chunk";
44
- /** Parse the downloaded chunk. */
45
- /**
46
- * Parse the downloaded chunk.
47
- *
48
- * Take in argument the timescale value that might have been obtained by
49
- * parsing an initialization segment from the same Representation.
50
- * Can be left to `undefined` if unknown or inexistant, segment parsers should
51
- * be resilient and still work without that information.
52
- *
53
- * @param {number} initTimescale
54
- * @returns {Object}
55
- */
56
- parse(initTimescale?: number): ISegmentParserParsedInitChunk<TSegmentDataType> | ISegmentParserParsedMediaChunk<TSegmentDataType>;
57
- }
44
+ export declare type ISegmentFetcher<TSegmentDataType> = (
45
+ /** Information on the segment wanted. */
46
+ content: ISegmentLoaderContent,
47
+ /** Callbacks the `ISegmentFetcher` will call as it loads the data. */
48
+ callbacks: ISegmentFetcherCallbacks<TSegmentDataType>,
49
+ /** CancellationSignal allowing to cancel the request. */
50
+ cancellationSignal: CancellationSignal) => Promise<void>;
58
51
  /**
59
- * Event sent when all "chunk" of the segments have been communicated through
60
- * `ISegmentFetcherChunkEvent` events.
52
+ * Callbacks given to an `ISegmentFetcher` allowing to be notified on its
53
+ * inner request's various events.
61
54
  */
62
- export interface ISegmentFetcherChunkCompleteEvent {
63
- type: "chunk-complete";
55
+ export interface ISegmentFetcherCallbacks<TSegmentDataType> {
56
+ /** Called when a decodable chunk of the whole segment is available. */
57
+ onChunk(parse: (initTimescale: number | undefined) => ISegmentParserParsedInitChunk<TSegmentDataType> | ISegmentParserParsedMediaChunk<TSegmentDataType>): void;
58
+ /**
59
+ * Callback called when all decodable chunks of the loaded segment have been
60
+ * communicated through the `onChunk` callback.
61
+ */
62
+ onAllChunksReceived(): void;
63
+ /**
64
+ * Callback called when the segment request has to restart from scratch. */
65
+ onRetry(error: IPlayerError): void;
64
66
  }
65
67
  /** Content used by the segment loader as a context to load a new segment. */
66
68
  export interface ISegmentLoaderContent {
@@ -71,19 +73,10 @@ export interface ISegmentLoaderContent {
71
73
  segment: ISegment;
72
74
  }
73
75
  /**
74
- * An Error happened while loading which led to a retry.
75
- * The request is retried from scratch.
76
- */
77
- export interface ISegmentFetcherRetry {
78
- type: "retry";
79
- value: IPlayerError;
80
- }
81
- /**
82
- * Callbacks that can be bound when creating an `ISegmentFetcher`.
83
- * Those allows to be notified of an `ISegmentFetcher` various lifecycles and of
84
- * network information.
76
+ * Callbacks given when creating an `ISegmentFetcher`, allowing to be notified
77
+ * on high-level metadata about performed requests.
85
78
  */
86
- export interface ISegmentFetcherCreatorCallbacks {
79
+ export interface ISegmentFetcherLifecycleCallbacks {
87
80
  /** Called when a segment request begins. */
88
81
  onRequestBegin?: (arg: IRequestBeginCallbackPayload) => void;
89
82
  /** Called when progress information is available on a pending segment request. */
@@ -13,7 +13,42 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Observable } from "rxjs";
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __generator = (this && this.__generator) || function (thisArg, body) {
26
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
+ function verb(n) { return function (v) { return step([n, v]); }; }
29
+ function step(op) {
30
+ if (f) throw new TypeError("Generator is already executing.");
31
+ while (_) try {
32
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
+ if (y = 0, t) op = [op[0] & 2, t.value];
34
+ switch (op[0]) {
35
+ case 0: case 1: t = op; break;
36
+ case 4: _.label++; return { value: op[1], done: false };
37
+ case 5: _.label++; y = op[1]; op = [0]; continue;
38
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
+ default:
40
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
+ if (t[2]) _.ops.pop();
45
+ _.trys.pop(); continue;
46
+ }
47
+ op = body.call(thisArg, _);
48
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
+ }
51
+ };
17
52
  import config from "../../../config";
18
53
  import { formatError } from "../../../errors";
19
54
  import log from "../../../log";
@@ -23,9 +58,10 @@ import idGenerator from "../../../utils/id_generator";
23
58
  import InitializationSegmentCache from "../../../utils/initialization_segment_cache";
24
59
  import isNullOrUndefined from "../../../utils/is_null_or_undefined";
25
60
  import objectAssign from "../../../utils/object_assign";
26
- import TaskCanceller from "../../../utils/task_canceller";
61
+ import { CancellationError, } from "../../../utils/task_canceller";
27
62
  import errorSelector from "../utils/error_selector";
28
63
  import { tryURLsWithBackoff } from "../utils/try_urls_with_backoff";
64
+ /** Allows to generate a unique identifies for each request. */
29
65
  var generateRequestID = idGenerator();
30
66
  /**
31
67
  * Create an `ISegmentFetcher` object which will allow to easily fetch and parse
@@ -35,11 +71,11 @@ var generateRequestID = idGenerator();
35
71
  *
36
72
  * @param {string} bufferType
37
73
  * @param {Object} pipeline
38
- * @param {Object} callbacks
74
+ * @param {Object} lifecycleCallbacks
39
75
  * @param {Object} options
40
76
  * @returns {Function}
41
77
  */
42
- export default function createSegmentFetcher(bufferType, pipeline, callbacks, options) {
78
+ export default function createSegmentFetcher(bufferType, pipeline, lifecycleCallbacks, options) {
43
79
  var requestOptions = {
44
80
  timeout: options.requestTimeout < 0 ? undefined :
45
81
  options.requestTimeout,
@@ -55,158 +91,20 @@ export default function createSegmentFetcher(bufferType, pipeline, callbacks, op
55
91
  var loadSegment = pipeline.loadSegment, parseSegment = pipeline.parseSegment;
56
92
  /**
57
93
  * Fetch a specific segment.
58
- *
59
- * This function returns an Observable which will fetch segments on
60
- * subscription.
61
- * If the corresponding request fails, it may retry it based on the given
62
- * options.
63
- *
64
- * This Observable will emit various events during that request lifecycle and
65
- * throw if the segment request(s) (including potential retries) fail.
66
- * The Observable will automatically complete once no events are left to be
67
- * sent.
68
94
  * @param {Object} content
69
- * @returns {Observable}
95
+ * @param {Object} fetcherCallbacks
96
+ * @param {Object} cancellationSignal
97
+ * @returns {Promise}
70
98
  */
71
- return function fetchSegment(content) {
72
- var segment = content.segment;
73
- // used by logs
74
- var segmentIdString = getLoggableSegmentId(content);
75
- return new Observable(function (obs) {
76
- var _a, _b;
77
- var requestId = generateRequestID();
78
- var canceller = new TaskCanceller();
79
- /**
80
- * If the request succeeded, set to the corresponding
81
- * `IChunkCompleteInformation` object.
82
- * For any other completion cases: if the request either failed, was
83
- * cancelled or just if no request was needed, set to `null`.
84
- *
85
- * Stays to `undefined` when the request is still pending.
86
- */
87
- var requestInfo;
88
- /**
89
- * Array containing one entry per loaded chunk, in chronological order.
90
- * The boolean indicates if the chunk has been parsed at least once.
91
- *
92
- * This is used to know when all loaded chunks have been parsed, which
93
- * can be useful to e.g. construct metrics about the loaded segment.
94
- */
95
- var parsedChunks = [];
96
- /**
97
- * Addition of the duration of each encountered and parsed chunks.
98
- * Allows to have an idea of the real duration of the full segment once
99
- * all chunks have been parsed.
100
- *
101
- * `undefined` if at least one of the parsed chunks has unknown duration.
102
- */
103
- var segmentDurationAcc = 0;
104
- /** Set to `true` once network metrics have been sent. */
105
- var metricsSent = false;
106
- var loaderCallbacks = {
107
- /**
108
- * Callback called when the segment loader has progress information on
109
- * the request.
110
- * @param {Object} info
111
- */
112
- onProgress: function (info) {
113
- var _a;
114
- if (requestInfo !== undefined) {
115
- return; // Request already terminated
116
- }
117
- if (info.totalSize !== undefined && info.size < info.totalSize) {
118
- (_a = callbacks.onProgress) === null || _a === void 0 ? void 0 : _a.call(callbacks, { duration: info.duration,
119
- size: info.size,
120
- totalSize: info.totalSize,
121
- timestamp: performance.now(),
122
- id: requestId });
123
- }
124
- },
125
- /**
126
- * Callback called when the segment is communicated by the loader
127
- * through decodable sub-segment(s) called chunk(s), with a chunk in
128
- * argument.
129
- * @param {*} chunkData
130
- */
131
- onNewChunk: function (chunkData) {
132
- obs.next({ type: "chunk",
133
- parse: generateParserFunction(chunkData, true) });
134
- },
135
- };
136
- // Retrieve from cache if it exists
137
- var cached = cache !== undefined ? cache.get(content) :
138
- null;
139
- if (cached !== null) {
140
- log.debug("SF: Found wanted segment in cache", segmentIdString);
141
- obs.next({ type: "chunk",
142
- parse: generateParserFunction(cached, false) });
143
- obs.next({ type: "chunk-complete" });
144
- obs.complete();
145
- return undefined;
146
- }
147
- log.debug("SF: Beginning request", segmentIdString);
148
- (_a = callbacks.onRequestBegin) === null || _a === void 0 ? void 0 : _a.call(callbacks, { requestTimestamp: performance.now(),
149
- id: requestId, content: content });
150
- tryURLsWithBackoff((_b = segment.mediaURLs) !== null && _b !== void 0 ? _b : [null], callLoaderWithUrl, objectAssign({ onRetry: onRetry }, options), canceller.signal)
151
- .then(function (res) {
152
- var _a;
153
- log.debug("SF: Segment request ended with success", segmentIdString);
154
- if (res.resultType === "segment-loaded") {
155
- var loadedData = res.resultData.responseData;
156
- if (cache !== undefined) {
157
- cache.add(content, res.resultData.responseData);
158
- }
159
- obs.next({ type: "chunk",
160
- parse: generateParserFunction(loadedData, false) });
161
- }
162
- else if (res.resultType === "segment-created") {
163
- obs.next({ type: "chunk",
164
- parse: generateParserFunction(res.resultData, false) });
165
- }
166
- log.debug("SF: Segment request ended with success", segmentIdString);
167
- obs.next({ type: "chunk-complete" });
168
- if (res.resultType !== "segment-created") {
169
- requestInfo = res.resultData;
170
- sendNetworkMetricsIfAvailable();
171
- }
172
- else {
173
- requestInfo = null;
174
- }
175
- if (!canceller.isUsed) {
176
- // The current Observable could have been canceled as a result of one
177
- // of the previous `next` calls. In that case, we don't want to send
178
- // a "requestEnd" again as it has already been sent on cancellation.
179
- //
180
- // Note that we only perform this check for `onRequestEnd` on
181
- // purpose. Observable's events should have been ignored by RxJS if
182
- // the Observable has already been canceled and we don't care if
183
- // `"metrics"` is sent there.
184
- (_a = callbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(callbacks, { id: requestId });
185
- }
186
- obs.complete();
187
- })
188
- .catch(function (err) {
189
- log.debug("SF: Segment request failed", segmentIdString);
190
- requestInfo = null;
191
- obs.error(errorSelector(err));
192
- });
193
- return function () {
194
- var _a;
195
- if (requestInfo !== undefined) {
196
- return; // Request already terminated
197
- }
198
- log.debug("SF: Segment request cancelled", segmentIdString);
199
- requestInfo = null;
200
- canceller.cancel();
201
- (_a = callbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(callbacks, { id: requestId });
202
- };
99
+ return function fetchSegment(content, fetcherCallbacks, cancellationSignal) {
100
+ var _a, _b, _c;
101
+ return __awaiter(this, void 0, void 0, function () {
203
102
  /**
204
103
  * Call a segment loader for the given URL with the right arguments.
205
104
  * @param {string|null} url
206
- * @param {Object} cancellationSignal
207
105
  * @returns {Promise}
208
106
  */
209
- function callLoaderWithUrl(url, cancellationSignal) {
107
+ function callLoaderWithUrl(url) {
210
108
  return loadSegment(url, content, requestOptions, cancellationSignal, loaderCallbacks);
211
109
  }
212
110
  /**
@@ -245,8 +143,7 @@ export default function createSegmentFetcher(bufferType, pipeline, callbacks, op
245
143
  * @param {*} err
246
144
  */
247
145
  function onRetry(err) {
248
- obs.next({ type: "retry",
249
- value: errorSelector(err) });
146
+ fetcherCallbacks.onRetry(errorSelector(err));
250
147
  }
251
148
  /**
252
149
  * Send netork metrics if they haven't yet been sent and if all data to
@@ -263,10 +160,116 @@ export default function createSegmentFetcher(bufferType, pipeline, callbacks, op
263
160
  parsedChunks.length > 0 &&
264
161
  parsedChunks.every(function (isParsed) { return isParsed; })) {
265
162
  metricsSent = true;
266
- (_a = callbacks.onMetrics) === null || _a === void 0 ? void 0 : _a.call(callbacks, { size: requestInfo.size,
267
- requestDuration: requestInfo.requestDuration, content: content, segmentDuration: segmentDurationAcc });
163
+ (_a = lifecycleCallbacks.onMetrics) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, {
164
+ size: requestInfo.size,
165
+ requestDuration: requestInfo.requestDuration,
166
+ content: content,
167
+ segmentDuration: segmentDurationAcc,
168
+ });
268
169
  }
269
170
  }
171
+ var segment, segmentIdString, requestId, requestInfo, parsedChunks, segmentDurationAcc, metricsSent, loaderCallbacks, cached, res, loadedData, err_1;
172
+ return __generator(this, function (_d) {
173
+ switch (_d.label) {
174
+ case 0:
175
+ segment = content.segment;
176
+ segmentIdString = getLoggableSegmentId(content);
177
+ requestId = generateRequestID();
178
+ parsedChunks = [];
179
+ segmentDurationAcc = 0;
180
+ metricsSent = false;
181
+ loaderCallbacks = {
182
+ /**
183
+ * Callback called when the segment loader has progress information on
184
+ * the request.
185
+ * @param {Object} info
186
+ */
187
+ onProgress: function (info) {
188
+ var _a;
189
+ if (requestInfo !== undefined) {
190
+ return; // request already termminated
191
+ }
192
+ if (info.totalSize !== undefined && info.size < info.totalSize) {
193
+ (_a = lifecycleCallbacks.onProgress) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, { duration: info.duration,
194
+ size: info.size,
195
+ totalSize: info.totalSize,
196
+ timestamp: performance.now(),
197
+ id: requestId });
198
+ }
199
+ },
200
+ /**
201
+ * Callback called when the segment is communicated by the loader
202
+ * through decodable sub-segment(s) called chunk(s), with a chunk in
203
+ * argument.
204
+ * @param {*} chunkData
205
+ */
206
+ onNewChunk: function (chunkData) {
207
+ fetcherCallbacks.onChunk(generateParserFunction(chunkData, true));
208
+ },
209
+ };
210
+ cached = cache !== undefined ? cache.get(content) :
211
+ null;
212
+ if (cached !== null) {
213
+ log.debug("SF: Found wanted segment in cache", segmentIdString);
214
+ fetcherCallbacks.onChunk(generateParserFunction(cached, false));
215
+ return [2 /*return*/, Promise.resolve()];
216
+ }
217
+ log.debug("SF: Beginning request", segmentIdString);
218
+ (_a = lifecycleCallbacks.onRequestBegin) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, { requestTimestamp: performance.now(),
219
+ id: requestId, content: content });
220
+ cancellationSignal.register(function () {
221
+ var _a;
222
+ if (requestInfo !== undefined) {
223
+ return; // Request already terminated
224
+ }
225
+ log.debug("SF: Segment request cancelled", segmentIdString);
226
+ requestInfo = null;
227
+ (_a = lifecycleCallbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, { id: requestId });
228
+ });
229
+ _d.label = 1;
230
+ case 1:
231
+ _d.trys.push([1, 3, , 4]);
232
+ return [4 /*yield*/, tryURLsWithBackoff((_b = segment.mediaURLs) !== null && _b !== void 0 ? _b : [null], callLoaderWithUrl, objectAssign({ onRetry: onRetry }, options), cancellationSignal)];
233
+ case 2:
234
+ res = _d.sent();
235
+ if (res.resultType === "segment-loaded") {
236
+ loadedData = res.resultData.responseData;
237
+ if (cache !== undefined) {
238
+ cache.add(content, res.resultData.responseData);
239
+ }
240
+ fetcherCallbacks.onChunk(generateParserFunction(loadedData, false));
241
+ }
242
+ else if (res.resultType === "segment-created") {
243
+ fetcherCallbacks.onChunk(generateParserFunction(res.resultData, false));
244
+ }
245
+ log.debug("SF: Segment request ended with success", segmentIdString);
246
+ fetcherCallbacks.onAllChunksReceived();
247
+ if (res.resultType !== "segment-created") {
248
+ requestInfo = res.resultData;
249
+ sendNetworkMetricsIfAvailable();
250
+ }
251
+ else {
252
+ requestInfo = null;
253
+ }
254
+ if (!cancellationSignal.isCancelled) {
255
+ // The current task could have been canceled as a result of one
256
+ // of the previous callbacks call. In that case, we don't want to send
257
+ // a "requestEnd" again as it has already been sent on cancellation.
258
+ (_c = lifecycleCallbacks.onRequestEnd) === null || _c === void 0 ? void 0 : _c.call(lifecycleCallbacks, { id: requestId });
259
+ }
260
+ return [3 /*break*/, 4];
261
+ case 3:
262
+ err_1 = _d.sent();
263
+ requestInfo = null;
264
+ if (err_1 instanceof CancellationError) {
265
+ log.debug("SF: Segment request aborted", segmentIdString);
266
+ throw err_1;
267
+ }
268
+ log.debug("SF: Segment request failed", segmentIdString);
269
+ throw errorSelector(err_1);
270
+ case 4: return [2 /*return*/];
271
+ }
272
+ });
270
273
  });
271
274
  };
272
275
  }
@@ -16,7 +16,7 @@
16
16
  import { ITransportPipelines } from "../../../transports";
17
17
  import { IBufferType } from "../../segment_buffers";
18
18
  import { IPrioritizedSegmentFetcher } from "./prioritized_segment_fetcher";
19
- import { ISegmentFetcherCreatorCallbacks } from "./segment_fetcher";
19
+ import { ISegmentFetcherLifecycleCallbacks } from "./segment_fetcher";
20
20
  /**
21
21
  * Interact with the transport pipelines to download segments with the right
22
22
  * priority.
@@ -54,7 +54,7 @@ export default class SegmentFetcherCreator {
54
54
  */
55
55
  private readonly _transport;
56
56
  /**
57
- * `ObservablePrioritizer` linked to this SegmentFetcherCreator.
57
+ * `TaskPrioritizer` linked to this SegmentFetcherCreator.
58
58
  *
59
59
  * Note: this is typed as `any` because segment loaders / parsers can use
60
60
  * different types depending on the type of buffer. We could maybe be smarter
@@ -78,7 +78,7 @@ export default class SegmentFetcherCreator {
78
78
  * @param {Object} callbacks
79
79
  * @returns {Object}
80
80
  */
81
- createSegmentFetcher(bufferType: IBufferType, callbacks: ISegmentFetcherCreatorCallbacks): IPrioritizedSegmentFetcher<unknown>;
81
+ createSegmentFetcher(bufferType: IBufferType, callbacks: ISegmentFetcherLifecycleCallbacks): IPrioritizedSegmentFetcher<unknown>;
82
82
  }
83
83
  /** Options used by the `SegmentFetcherCreator`. */
84
84
  export interface ISegmentFetcherCreatorBackoffOptions {
@@ -15,8 +15,8 @@
15
15
  */
16
16
  import config from "../../../config";
17
17
  import applyPrioritizerToSegmentFetcher from "./prioritized_segment_fetcher";
18
- import ObservablePrioritizer from "./prioritizer";
19
18
  import createSegmentFetcher, { getSegmentFetcherOptions, } from "./segment_fetcher";
19
+ import TaskPrioritizer from "./task_prioritizer";
20
20
  /**
21
21
  * Interact with the transport pipelines to download segments with the right
22
22
  * priority.
@@ -54,7 +54,7 @@ var SegmentFetcherCreator = /** @class */ (function () {
54
54
  function SegmentFetcherCreator(transport, options) {
55
55
  var _a = config.getCurrent(), MIN_CANCELABLE_PRIORITY = _a.MIN_CANCELABLE_PRIORITY, MAX_HIGH_PRIORITY_LEVEL = _a.MAX_HIGH_PRIORITY_LEVEL;
56
56
  this._transport = transport;
57
- this._prioritizer = new ObservablePrioritizer({
57
+ this._prioritizer = new TaskPrioritizer({
58
58
  prioritySteps: { high: MAX_HIGH_PRIORITY_LEVEL,
59
59
  low: MIN_CANCELABLE_PRIORITY },
60
60
  });