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

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 (184) hide show
  1. package/CHANGELOG.md +22 -10
  2. package/MAINTAINERS.md +2 -1
  3. package/VERSION +1 -1
  4. package/dist/_esm5.processed/compat/browser_detection.d.ts +4 -1
  5. package/dist/_esm5.processed/compat/browser_detection.js +7 -1
  6. package/dist/_esm5.processed/compat/can_reuse_media_keys.d.ts +12 -0
  7. package/dist/_esm5.processed/compat/can_reuse_media_keys.js +15 -0
  8. package/dist/_esm5.processed/compat/enable_audio_track.d.ts +11 -0
  9. package/dist/_esm5.processed/compat/enable_audio_track.js +26 -0
  10. package/dist/_esm5.processed/compat/index.d.ts +4 -2
  11. package/dist/_esm5.processed/compat/index.js +4 -2
  12. package/dist/_esm5.processed/compat/{should_renew_media_keys.d.ts → should_renew_media_key_system_access.d.ts} +3 -3
  13. package/dist/_esm5.processed/compat/{should_renew_media_keys.js → should_renew_media_key_system_access.js} +3 -3
  14. package/dist/_esm5.processed/config.d.ts +1 -0
  15. package/dist/_esm5.processed/core/api/playback_observer.d.ts +14 -5
  16. package/dist/_esm5.processed/core/api/playback_observer.js +54 -22
  17. package/dist/_esm5.processed/core/api/public_api.d.ts +7 -4
  18. package/dist/_esm5.processed/core/api/public_api.js +79 -61
  19. package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +9 -10
  20. package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +1 -1
  21. package/dist/_esm5.processed/core/decrypt/find_key_system.js +3 -3
  22. package/dist/_esm5.processed/core/decrypt/get_media_keys.js +4 -1
  23. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +98 -0
  24. package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +173 -0
  25. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +4 -4
  26. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +2 -1
  27. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +15 -16
  28. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +3 -1
  29. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +5 -2
  30. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.d.ts +103 -0
  31. package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +414 -0
  32. package/dist/_esm5.processed/core/init/content_time_boundaries_observer.d.ts +4 -3
  33. package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +21 -22
  34. package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +18 -4
  35. package/dist/_esm5.processed/core/init/initialize_media_source.js +10 -2
  36. package/dist/_esm5.processed/core/init/load_on_media_source.js +7 -1
  37. package/dist/_esm5.processed/core/init/stall_avoider.js +3 -1
  38. package/dist/_esm5.processed/default_config.d.ts +11 -0
  39. package/dist/_esm5.processed/default_config.js +11 -0
  40. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +1 -1
  41. package/dist/_esm5.processed/manifest/manifest.js +11 -2
  42. package/dist/_esm5.processed/manifest/representation.d.ts +12 -1
  43. package/dist/_esm5.processed/manifest/representation.js +1 -0
  44. package/dist/_esm5.processed/manifest/representation_index/static.d.ts +1 -1
  45. package/dist/_esm5.processed/manifest/representation_index/static.js +2 -2
  46. package/dist/_esm5.processed/manifest/representation_index/types.d.ts +32 -15
  47. package/dist/_esm5.processed/manifest/update_period_in_place.js +1 -0
  48. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +10 -9
  49. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +11 -11
  50. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.d.ts +1 -1
  51. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.js +3 -3
  52. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +1 -1
  53. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +4 -4
  54. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +7 -7
  55. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +12 -8
  56. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +5 -6
  57. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +16 -16
  58. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +11 -10
  59. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +14 -13
  60. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.d.ts +3 -4
  61. package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.js +4 -12
  62. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +2 -4
  63. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +1 -3
  64. package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +6 -2
  65. package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.d.ts +1 -2
  66. package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.js +3 -8
  67. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.d.ts +1 -1
  68. package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.js +2 -20
  69. package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +0 -6
  70. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.js +0 -11
  71. package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/types.d.ts +5 -1
  72. package/dist/_esm5.processed/parsers/manifest/local/parse_local_manifest.js +2 -1
  73. package/dist/_esm5.processed/parsers/manifest/local/representation_index.js +2 -2
  74. package/dist/_esm5.processed/parsers/manifest/metaplaylist/metaplaylist_parser.js +7 -1
  75. package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +17 -11
  76. package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.js +2 -2
  77. package/dist/_esm5.processed/parsers/manifest/types.d.ts +24 -0
  78. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_extent.js +8 -1
  79. package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_origin.js +9 -1
  80. package/dist/_esm5.processed/parsers/texttracks/ttml/html/create_element.js +2 -1
  81. package/dist/_esm5.processed/transports/dash/construct_segment_url.d.ts +18 -0
  82. package/dist/_esm5.processed/transports/dash/construct_segment_url.js +21 -0
  83. package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
  84. package/dist/_esm5.processed/transports/dash/image_pipelines.js +5 -3
  85. package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -2
  86. package/dist/_esm5.processed/transports/dash/text_loader.js +4 -2
  87. package/dist/_esm5.processed/transports/dash/text_parser.js +3 -1
  88. package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
  89. package/dist/_esm5.processed/transports/local/segment_loader.js +2 -2
  90. package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +8 -8
  91. package/dist/_esm5.processed/transports/smooth/pipelines.js +11 -7
  92. package/dist/_esm5.processed/transports/smooth/utils.d.ts +4 -2
  93. package/dist/_esm5.processed/transports/smooth/utils.js +7 -1
  94. package/dist/_esm5.processed/transports/types.d.ts +5 -3
  95. package/dist/_esm5.processed/utils/event_emitter.d.ts +1 -2
  96. package/dist/_esm5.processed/utils/resolve_url.d.ts +7 -4
  97. package/dist/_esm5.processed/utils/resolve_url.js +11 -8
  98. package/dist/mpd-parser.wasm +0 -0
  99. package/dist/rx-player.js +5656 -13236
  100. package/dist/rx-player.min.js +1 -1
  101. package/jest.config.js +28 -23
  102. package/package.json +29 -29
  103. package/sonar-project.properties +1 -1
  104. package/src/compat/__tests__/can_reuse_media_keys.test.ts +54 -0
  105. package/src/compat/__tests__/enable_audio_track.test.ts +341 -0
  106. package/src/compat/__tests__/{should_renew_media_keys.test.ts → should_renew_media_key_system_access.test.ts} +7 -5
  107. package/src/compat/browser_detection.ts +10 -0
  108. package/src/compat/can_reuse_media_keys.ts +19 -0
  109. package/src/compat/enable_audio_track.ts +33 -0
  110. package/src/compat/index.ts +6 -2
  111. package/src/compat/{should_renew_media_keys.ts → should_renew_media_key_system_access.ts} +3 -3
  112. package/src/core/api/playback_observer.ts +97 -33
  113. package/src/core/api/public_api.ts +126 -74
  114. package/src/core/api/tracks_management/media_element_track_choice_manager.ts +3 -11
  115. package/src/core/decrypt/__tests__/__global__/media_keys.test.ts +182 -0
  116. package/src/core/decrypt/__tests__/__global__/utils.ts +2 -0
  117. package/src/core/decrypt/find_key_system.ts +3 -3
  118. package/src/core/decrypt/get_media_keys.ts +5 -1
  119. package/src/core/fetchers/cdn_prioritizer.ts +198 -0
  120. package/src/core/fetchers/manifest/manifest_fetcher.ts +7 -11
  121. package/src/core/fetchers/segment/segment_fetcher.ts +12 -10
  122. package/src/core/fetchers/segment/segment_fetcher_creator.ts +10 -1
  123. package/src/core/fetchers/utils/schedule_request.ts +482 -0
  124. package/src/core/init/content_time_boundaries_observer.ts +12 -12
  125. package/src/core/init/initialize_media_source.ts +31 -4
  126. package/src/core/init/load_on_media_source.ts +11 -2
  127. package/src/core/init/stall_avoider.ts +4 -1
  128. package/src/core/stream/orchestrator/stream_orchestrator.ts +0 -1
  129. package/src/default_config.ts +12 -0
  130. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +1 -0
  131. package/src/manifest/manifest.ts +11 -2
  132. package/src/manifest/representation.ts +15 -0
  133. package/src/manifest/representation_index/__tests__/static.test.ts +1 -1
  134. package/src/manifest/representation_index/static.ts +3 -3
  135. package/src/manifest/representation_index/types.ts +33 -15
  136. package/src/manifest/update_period_in_place.ts +1 -0
  137. package/src/parsers/manifest/dash/common/indexes/base.ts +22 -23
  138. package/src/parsers/manifest/dash/common/indexes/get_init_segment.ts +6 -4
  139. package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +5 -5
  140. package/src/parsers/manifest/dash/common/indexes/list.ts +19 -20
  141. package/src/parsers/manifest/dash/common/indexes/template.ts +23 -27
  142. package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +25 -23
  143. package/src/parsers/manifest/dash/common/indexes/tokens.ts +7 -18
  144. package/src/parsers/manifest/dash/common/parse_mpd.ts +2 -4
  145. package/src/parsers/manifest/dash/common/parse_representation_index.ts +1 -6
  146. package/src/parsers/manifest/dash/common/parse_representations.ts +9 -0
  147. package/src/parsers/manifest/dash/common/resolve_base_urls.ts +5 -9
  148. package/src/parsers/manifest/dash/js-parser/node_parsers/BaseURL.ts +2 -29
  149. package/src/parsers/manifest/dash/js-parser/node_parsers/__tests__/AdaptationSet.test.ts +7 -11
  150. package/src/parsers/manifest/dash/node_parser_types.ts +0 -7
  151. package/src/parsers/manifest/dash/wasm-parser/rs/events.rs +3 -1
  152. package/src/parsers/manifest/dash/wasm-parser/rs/processor/attributes.rs +1 -8
  153. package/src/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.ts +0 -13
  154. package/src/parsers/manifest/dash/wasm-parser/ts/types.ts +8 -0
  155. package/src/parsers/manifest/local/parse_local_manifest.ts +1 -0
  156. package/src/parsers/manifest/local/representation_index.ts +2 -2
  157. package/src/parsers/manifest/metaplaylist/metaplaylist_parser.ts +7 -1
  158. package/src/parsers/manifest/smooth/create_parser.ts +17 -13
  159. package/src/parsers/manifest/smooth/representation_index.ts +2 -2
  160. package/src/parsers/manifest/types.ts +26 -1
  161. package/src/parsers/manifest/utils/__tests__/get_first_time_from_adaptations.test.ts +15 -0
  162. package/src/parsers/manifest/utils/__tests__/get_last_time_from_adaptation.test.ts +15 -0
  163. package/src/parsers/texttracks/ttml/html/apply_extent.ts +8 -1
  164. package/src/parsers/texttracks/ttml/html/apply_origin.ts +9 -1
  165. package/src/parsers/texttracks/ttml/html/create_element.ts +2 -2
  166. package/src/transports/dash/construct_segment_url.ts +28 -0
  167. package/src/transports/dash/image_pipelines.ts +5 -2
  168. package/src/transports/dash/segment_loader.ts +5 -2
  169. package/src/transports/dash/text_loader.ts +5 -2
  170. package/src/transports/dash/text_parser.ts +3 -1
  171. package/src/transports/local/segment_loader.ts +3 -2
  172. package/src/transports/metaplaylist/pipelines.ts +28 -9
  173. package/src/transports/smooth/pipelines.ts +12 -6
  174. package/src/transports/smooth/utils.ts +13 -1
  175. package/src/transports/types.ts +6 -3
  176. package/src/utils/__tests__/event_emitter.test.ts +72 -67
  177. package/src/utils/__tests__/initialization_segment_cache.test.ts +7 -7
  178. package/src/utils/__tests__/resolve_url.test.ts +27 -23
  179. package/src/utils/event_emitter.ts +1 -3
  180. package/src/utils/resolve_url.ts +11 -8
  181. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.d.ts +0 -85
  182. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +0 -264
  183. package/dummy +0 -1
  184. package/src/core/fetchers/utils/try_urls_with_backoff.ts +0 -287
@@ -1,85 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { CancellationSignal } from "../../../utils/task_canceller";
17
- /** Settings to give to the backoff functions to configure their behavior. */
18
- export interface IBackoffSettings {
19
- /**
20
- * Initial delay to wait if a request fails before making a new request, in
21
- * milliseconds.
22
- */
23
- baseDelay: number;
24
- /**
25
- * Maximum delay to wait if a request fails before making a new request, in
26
- * milliseconds.
27
- */
28
- maxDelay: number;
29
- /**
30
- * Maximum number of retries to perform on "regular" errors (e.g. due to HTTP
31
- * status, integrity errors, timeouts...).
32
- */
33
- maxRetryRegular: number;
34
- /**
35
- * Maximum number of retries to perform when it appears that the user is
36
- * currently offline.
37
- */
38
- maxRetryOffline: number;
39
- /** Callback called when a request is retried. */
40
- onRetry: (err: unknown) => void;
41
- }
42
- /**
43
- * Specific algorithm used to perform segment and manifest requests.
44
- *
45
- * Here how it works:
46
- *
47
- * 1. You give it one or multiple URLs available for the resource you want to
48
- * request (from the most important URL to the least important), the
49
- * request callback itself, and some options.
50
- *
51
- * 2. it tries to call the request callback with the first URL:
52
- * - if it works as expected, it resolves the returned Promise with that
53
- * request's response.
54
- * - if it fails, it calls ther `onRetry` callback given with the
55
- * corresponding error and try with the next URL.
56
- *
57
- * 3. When all URLs have been tested (and failed), it decides - according to
58
- * the error counters, configuration and errors received - if it can retry
59
- * at least one of them, in the same order:
60
- * - If it can, it increments the corresponding error counter, wait a
61
- * delay (based on an exponential backoff) and restart the same logic
62
- * for all retry-able URL.
63
- * - If it can't it just reject the error through the returned Promise.
64
- *
65
- * Note that there are in fact two separate counters:
66
- * - one for "offline" errors
67
- * - one for other xhr errors
68
- * Both counters are resetted if the error type changes from an error to the
69
- * next.
70
- *
71
- * @param {Array.<string>} urls
72
- * @param {Function} performRequest
73
- * @param {Object} options - Configuration options.
74
- * @param {Object} cancellationSignal
75
- * @returns {Promise}
76
- */
77
- export declare function tryURLsWithBackoff<T>(urls: Array<string | null>, performRequest: (url: string | null, cancellationSignal: CancellationSignal) => Promise<T>, options: IBackoffSettings, cancellationSignal: CancellationSignal): Promise<T>;
78
- /**
79
- * Lightweight version of the request algorithm, this time with only a simple
80
- * Promise given.
81
- * @param {Function} performRequest
82
- * @param {Object} options
83
- * @returns {Promise}
84
- */
85
- export declare function tryRequestPromiseWithBackoff<T>(performRequest: () => Promise<T>, options: IBackoffSettings, cancellationSignal: CancellationSignal): Promise<T>;
@@ -1,264 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- 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
- };
52
- import { isOffline } from "../../../compat";
53
- import { CustomLoaderError, isKnownError, NetworkErrorTypes, RequestError, } from "../../../errors";
54
- import log from "../../../log";
55
- import cancellableSleep from "../../../utils/cancellable_sleep";
56
- import getFuzzedDelay from "../../../utils/get_fuzzed_delay";
57
- import TaskCanceller from "../../../utils/task_canceller";
58
- /**
59
- * Called on a loader error.
60
- * Returns whether the loader request should be retried.
61
- *
62
- * TODO the notion of retrying or not could be transport-specific (e.g. 412 are
63
- * mainly used for Smooth contents) and thus as part of the transport code (e.g.
64
- * by rejecting with an error always having a `canRetry` property?).
65
- * Or not, to ponder.
66
- *
67
- * @param {Error} error
68
- * @returns {Boolean} - If true, the request can be retried.
69
- */
70
- function shouldRetry(error) {
71
- if (error instanceof RequestError) {
72
- if (error.type === NetworkErrorTypes.ERROR_HTTP_CODE) {
73
- return error.status >= 500 ||
74
- error.status === 404 ||
75
- error.status === 415 || // some CDN seems to use that code when
76
- // requesting low-latency segments too much
77
- // in advance
78
- error.status === 412;
79
- }
80
- return error.type === NetworkErrorTypes.TIMEOUT ||
81
- error.type === NetworkErrorTypes.ERROR_EVENT;
82
- }
83
- else if (error instanceof CustomLoaderError) {
84
- if (typeof error.canRetry === "boolean") {
85
- return error.canRetry;
86
- }
87
- if (error.xhr !== undefined) {
88
- return error.xhr.status >= 500 ||
89
- error.xhr.status === 404 ||
90
- error.xhr.status === 415 || // some CDN seems to use that code when
91
- // requesting low-latency segments too much
92
- // in advance
93
- error.xhr.status === 412;
94
- }
95
- return false;
96
- }
97
- return isKnownError(error) && error.code === "INTEGRITY_ERROR";
98
- }
99
- /**
100
- * Returns true if we're pretty sure that the current error is due to the
101
- * user being offline.
102
- * @param {Error} error
103
- * @returns {Boolean}
104
- */
105
- function isOfflineRequestError(error) {
106
- if (error instanceof RequestError) {
107
- return error.type === NetworkErrorTypes.ERROR_EVENT &&
108
- isOffline();
109
- }
110
- else if (error instanceof CustomLoaderError) {
111
- return error.isOfflineError;
112
- }
113
- return false; // under doubt, return false
114
- }
115
- /**
116
- * Guess the type of error obtained.
117
- * @param {*} error
118
- * @returns {number}
119
- */
120
- function getRequestErrorType(error) {
121
- return isOfflineRequestError(error) ? 2 /* REQUEST_ERROR_TYPES.Offline */ :
122
- 1 /* REQUEST_ERROR_TYPES.Regular */;
123
- }
124
- /**
125
- * Specific algorithm used to perform segment and manifest requests.
126
- *
127
- * Here how it works:
128
- *
129
- * 1. You give it one or multiple URLs available for the resource you want to
130
- * request (from the most important URL to the least important), the
131
- * request callback itself, and some options.
132
- *
133
- * 2. it tries to call the request callback with the first URL:
134
- * - if it works as expected, it resolves the returned Promise with that
135
- * request's response.
136
- * - if it fails, it calls ther `onRetry` callback given with the
137
- * corresponding error and try with the next URL.
138
- *
139
- * 3. When all URLs have been tested (and failed), it decides - according to
140
- * the error counters, configuration and errors received - if it can retry
141
- * at least one of them, in the same order:
142
- * - If it can, it increments the corresponding error counter, wait a
143
- * delay (based on an exponential backoff) and restart the same logic
144
- * for all retry-able URL.
145
- * - If it can't it just reject the error through the returned Promise.
146
- *
147
- * Note that there are in fact two separate counters:
148
- * - one for "offline" errors
149
- * - one for other xhr errors
150
- * Both counters are resetted if the error type changes from an error to the
151
- * next.
152
- *
153
- * @param {Array.<string>} urls
154
- * @param {Function} performRequest
155
- * @param {Object} options - Configuration options.
156
- * @param {Object} cancellationSignal
157
- * @returns {Promise}
158
- */
159
- export function tryURLsWithBackoff(urls, performRequest, options, cancellationSignal) {
160
- if (cancellationSignal.isCancelled) {
161
- return Promise.reject(cancellationSignal.cancellationError);
162
- }
163
- var baseDelay = options.baseDelay, maxDelay = options.maxDelay, maxRetryRegular = options.maxRetryRegular, maxRetryOffline = options.maxRetryOffline, onRetry = options.onRetry;
164
- var retryCount = 0;
165
- var lastError = 0 /* REQUEST_ERROR_TYPES.None */;
166
- var urlsToTry = urls.slice();
167
- if (urlsToTry.length === 0) {
168
- log.warn("Fetchers: no URL given to `tryURLsWithBackoff`.");
169
- return Promise.reject(new Error("No URL to request"));
170
- }
171
- return tryURLsRecursively(urlsToTry[0], 0);
172
- /**
173
- * Try to do the request of a given `url` which corresponds to the `index`
174
- * argument in the `urlsToTry` Array.
175
- *
176
- * If it fails try the next one.
177
- *
178
- * If all URLs fail, start a timer and retry the first element in that array
179
- * by following the configuration.
180
- *
181
- * @param {string|null} url
182
- * @param {number} index
183
- * @returns {Promise}
184
- */
185
- function tryURLsRecursively(url, index) {
186
- return __awaiter(this, void 0, void 0, function () {
187
- var res, error_1, newIndex, currentError, maxRetry, newIndex, delay, fuzzedDelay, nextURL;
188
- return __generator(this, function (_a) {
189
- switch (_a.label) {
190
- case 0:
191
- _a.trys.push([0, 2, , 4]);
192
- return [4 /*yield*/, performRequest(url, cancellationSignal)];
193
- case 1:
194
- res = _a.sent();
195
- return [2 /*return*/, res];
196
- case 2:
197
- error_1 = _a.sent();
198
- if (TaskCanceller.isCancellationError(error_1)) {
199
- throw error_1;
200
- }
201
- if (!shouldRetry(error_1)) {
202
- // ban this URL
203
- if (urlsToTry.length <= 1) { // This was the last one, throw
204
- throw error_1;
205
- }
206
- // else, remove that element from the array and go the next URL
207
- urlsToTry.splice(index, 1);
208
- newIndex = index >= urlsToTry.length - 1 ? 0 :
209
- index;
210
- onRetry(error_1);
211
- if (cancellationSignal.isCancelled) {
212
- throw cancellationSignal.cancellationError;
213
- }
214
- return [2 /*return*/, tryURLsRecursively(urlsToTry[newIndex], newIndex)];
215
- }
216
- currentError = getRequestErrorType(error_1);
217
- maxRetry = currentError === 2 /* REQUEST_ERROR_TYPES.Offline */ ? maxRetryOffline :
218
- maxRetryRegular;
219
- if (currentError !== lastError) {
220
- retryCount = 0;
221
- lastError = currentError;
222
- }
223
- if (index < urlsToTry.length - 1) { // there is still URLs to test
224
- newIndex = index + 1;
225
- onRetry(error_1);
226
- if (cancellationSignal.isCancelled) {
227
- throw cancellationSignal.cancellationError;
228
- }
229
- return [2 /*return*/, tryURLsRecursively(urlsToTry[newIndex], newIndex)];
230
- }
231
- // Here, we were using the last element of the `urlsToTry` array.
232
- // Increment counter and restart with the first URL
233
- retryCount++;
234
- if (retryCount > maxRetry) {
235
- throw error_1;
236
- }
237
- delay = Math.min(baseDelay * Math.pow(2, retryCount - 1), maxDelay);
238
- fuzzedDelay = getFuzzedDelay(delay);
239
- nextURL = urlsToTry[0];
240
- onRetry(error_1);
241
- if (cancellationSignal.isCancelled) {
242
- throw cancellationSignal.cancellationError;
243
- }
244
- return [4 /*yield*/, cancellableSleep(fuzzedDelay, cancellationSignal)];
245
- case 3:
246
- _a.sent();
247
- return [2 /*return*/, tryURLsRecursively(nextURL, 0)];
248
- case 4: return [2 /*return*/];
249
- }
250
- });
251
- });
252
- }
253
- }
254
- /**
255
- * Lightweight version of the request algorithm, this time with only a simple
256
- * Promise given.
257
- * @param {Function} performRequest
258
- * @param {Object} options
259
- * @returns {Promise}
260
- */
261
- export function tryRequestPromiseWithBackoff(performRequest, options, cancellationSignal) {
262
- // same than for a single unknown URL
263
- return tryURLsWithBackoff([null], performRequest, options, cancellationSignal);
264
- }
package/dummy DELETED
@@ -1 +0,0 @@
1
- This is an unnecessary file, just added to trigger the integration tests in a PR through GitHub actions.
@@ -1,287 +0,0 @@
1
- /**
2
- * Copyright 2015 CANAL+ Group
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
-
17
- import { isOffline } from "../../../compat";
18
- import {
19
- CustomLoaderError,
20
- isKnownError,
21
- NetworkErrorTypes,
22
- RequestError,
23
- } from "../../../errors";
24
- import log from "../../../log";
25
- import cancellableSleep from "../../../utils/cancellable_sleep";
26
- import getFuzzedDelay from "../../../utils/get_fuzzed_delay";
27
- import TaskCanceller, {
28
- CancellationSignal,
29
- } from "../../../utils/task_canceller";
30
-
31
- /**
32
- * Called on a loader error.
33
- * Returns whether the loader request should be retried.
34
- *
35
- * TODO the notion of retrying or not could be transport-specific (e.g. 412 are
36
- * mainly used for Smooth contents) and thus as part of the transport code (e.g.
37
- * by rejecting with an error always having a `canRetry` property?).
38
- * Or not, to ponder.
39
- *
40
- * @param {Error} error
41
- * @returns {Boolean} - If true, the request can be retried.
42
- */
43
- function shouldRetry(error : unknown) : boolean {
44
- if (error instanceof RequestError) {
45
- if (error.type === NetworkErrorTypes.ERROR_HTTP_CODE) {
46
- return error.status >= 500 ||
47
- error.status === 404 ||
48
- error.status === 415 || // some CDN seems to use that code when
49
- // requesting low-latency segments too much
50
- // in advance
51
- error.status === 412;
52
- }
53
- return error.type === NetworkErrorTypes.TIMEOUT ||
54
- error.type === NetworkErrorTypes.ERROR_EVENT;
55
- } else if (error instanceof CustomLoaderError) {
56
- if (typeof error.canRetry === "boolean") {
57
- return error.canRetry;
58
- }
59
- if (error.xhr !== undefined) {
60
- return error.xhr.status >= 500 ||
61
- error.xhr.status === 404 ||
62
- error.xhr.status === 415 || // some CDN seems to use that code when
63
- // requesting low-latency segments too much
64
- // in advance
65
- error.xhr.status === 412;
66
- }
67
- return false;
68
- }
69
- return isKnownError(error) && error.code === "INTEGRITY_ERROR";
70
- }
71
-
72
- /**
73
- * Returns true if we're pretty sure that the current error is due to the
74
- * user being offline.
75
- * @param {Error} error
76
- * @returns {Boolean}
77
- */
78
- function isOfflineRequestError(error : unknown) : boolean {
79
- if (error instanceof RequestError) {
80
- return error.type === NetworkErrorTypes.ERROR_EVENT &&
81
- isOffline();
82
- } else if (error instanceof CustomLoaderError) {
83
- return error.isOfflineError;
84
- }
85
- return false; // under doubt, return false
86
- }
87
-
88
- /** Settings to give to the backoff functions to configure their behavior. */
89
- export interface IBackoffSettings {
90
- /**
91
- * Initial delay to wait if a request fails before making a new request, in
92
- * milliseconds.
93
- */
94
- baseDelay : number;
95
- /**
96
- * Maximum delay to wait if a request fails before making a new request, in
97
- * milliseconds.
98
- */
99
- maxDelay : number;
100
- /**
101
- * Maximum number of retries to perform on "regular" errors (e.g. due to HTTP
102
- * status, integrity errors, timeouts...).
103
- */
104
- maxRetryRegular : number;
105
- /**
106
- * Maximum number of retries to perform when it appears that the user is
107
- * currently offline.
108
- */
109
- maxRetryOffline : number;
110
- /** Callback called when a request is retried. */
111
- onRetry : (err : unknown) => void;
112
- }
113
-
114
- const enum REQUEST_ERROR_TYPES { None,
115
- Regular,
116
- Offline }
117
-
118
- /**
119
- * Guess the type of error obtained.
120
- * @param {*} error
121
- * @returns {number}
122
- */
123
- function getRequestErrorType(error : unknown) : REQUEST_ERROR_TYPES {
124
- return isOfflineRequestError(error) ? REQUEST_ERROR_TYPES.Offline :
125
- REQUEST_ERROR_TYPES.Regular;
126
- }
127
-
128
- /**
129
- * Specific algorithm used to perform segment and manifest requests.
130
- *
131
- * Here how it works:
132
- *
133
- * 1. You give it one or multiple URLs available for the resource you want to
134
- * request (from the most important URL to the least important), the
135
- * request callback itself, and some options.
136
- *
137
- * 2. it tries to call the request callback with the first URL:
138
- * - if it works as expected, it resolves the returned Promise with that
139
- * request's response.
140
- * - if it fails, it calls ther `onRetry` callback given with the
141
- * corresponding error and try with the next URL.
142
- *
143
- * 3. When all URLs have been tested (and failed), it decides - according to
144
- * the error counters, configuration and errors received - if it can retry
145
- * at least one of them, in the same order:
146
- * - If it can, it increments the corresponding error counter, wait a
147
- * delay (based on an exponential backoff) and restart the same logic
148
- * for all retry-able URL.
149
- * - If it can't it just reject the error through the returned Promise.
150
- *
151
- * Note that there are in fact two separate counters:
152
- * - one for "offline" errors
153
- * - one for other xhr errors
154
- * Both counters are resetted if the error type changes from an error to the
155
- * next.
156
- *
157
- * @param {Array.<string>} urls
158
- * @param {Function} performRequest
159
- * @param {Object} options - Configuration options.
160
- * @param {Object} cancellationSignal
161
- * @returns {Promise}
162
- */
163
- export function tryURLsWithBackoff<T>(
164
- urls : Array<string|null>,
165
- performRequest : (
166
- url : string | null,
167
- cancellationSignal : CancellationSignal
168
- ) => Promise<T>,
169
- options : IBackoffSettings,
170
- cancellationSignal : CancellationSignal
171
- ) : Promise<T> {
172
- if (cancellationSignal.isCancelled) {
173
- return Promise.reject(cancellationSignal.cancellationError);
174
- }
175
-
176
- const { baseDelay,
177
- maxDelay,
178
- maxRetryRegular,
179
- maxRetryOffline,
180
- onRetry } = options;
181
- let retryCount = 0;
182
- let lastError = REQUEST_ERROR_TYPES.None;
183
-
184
- const urlsToTry = urls.slice();
185
- if (urlsToTry.length === 0) {
186
- log.warn("Fetchers: no URL given to `tryURLsWithBackoff`.");
187
- return Promise.reject(new Error("No URL to request"));
188
- }
189
- return tryURLsRecursively(urlsToTry[0], 0);
190
-
191
- /**
192
- * Try to do the request of a given `url` which corresponds to the `index`
193
- * argument in the `urlsToTry` Array.
194
- *
195
- * If it fails try the next one.
196
- *
197
- * If all URLs fail, start a timer and retry the first element in that array
198
- * by following the configuration.
199
- *
200
- * @param {string|null} url
201
- * @param {number} index
202
- * @returns {Promise}
203
- */
204
- async function tryURLsRecursively(
205
- url : string | null,
206
- index : number
207
- ) : Promise<T> {
208
- try {
209
- const res = await performRequest(url, cancellationSignal);
210
- return res;
211
- } catch (error : unknown) {
212
- if (TaskCanceller.isCancellationError(error)) {
213
- throw error;
214
- }
215
-
216
- if (!shouldRetry(error)) {
217
- // ban this URL
218
- if (urlsToTry.length <= 1) { // This was the last one, throw
219
- throw error;
220
- }
221
-
222
- // else, remove that element from the array and go the next URL
223
- urlsToTry.splice(index, 1);
224
- const newIndex = index >= urlsToTry.length - 1 ? 0 :
225
- index;
226
- onRetry(error);
227
- if (cancellationSignal.isCancelled) {
228
- throw cancellationSignal.cancellationError;
229
- }
230
- return tryURLsRecursively(urlsToTry[newIndex], newIndex);
231
- }
232
-
233
- const currentError = getRequestErrorType(error);
234
- const maxRetry = currentError === REQUEST_ERROR_TYPES.Offline ? maxRetryOffline :
235
- maxRetryRegular;
236
-
237
- if (currentError !== lastError) {
238
- retryCount = 0;
239
- lastError = currentError;
240
- }
241
-
242
- if (index < urlsToTry.length - 1) { // there is still URLs to test
243
- const newIndex = index + 1;
244
- onRetry(error);
245
- if (cancellationSignal.isCancelled) {
246
- throw cancellationSignal.cancellationError;
247
- }
248
- return tryURLsRecursively(urlsToTry[newIndex], newIndex);
249
- }
250
-
251
- // Here, we were using the last element of the `urlsToTry` array.
252
- // Increment counter and restart with the first URL
253
-
254
- retryCount++;
255
- if (retryCount > maxRetry) {
256
- throw error;
257
- }
258
- const delay = Math.min(baseDelay * Math.pow(2, retryCount - 1),
259
- maxDelay);
260
- const fuzzedDelay = getFuzzedDelay(delay);
261
- const nextURL = urlsToTry[0];
262
- onRetry(error);
263
- if (cancellationSignal.isCancelled) {
264
- throw cancellationSignal.cancellationError;
265
- }
266
-
267
- await cancellableSleep(fuzzedDelay, cancellationSignal);
268
- return tryURLsRecursively(nextURL, 0);
269
- }
270
- }
271
- }
272
-
273
- /**
274
- * Lightweight version of the request algorithm, this time with only a simple
275
- * Promise given.
276
- * @param {Function} performRequest
277
- * @param {Object} options
278
- * @returns {Promise}
279
- */
280
- export function tryRequestPromiseWithBackoff<T>(
281
- performRequest : () => Promise<T>,
282
- options : IBackoffSettings,
283
- cancellationSignal : CancellationSignal
284
- ) : Promise<T> {
285
- // same than for a single unknown URL
286
- return tryURLsWithBackoff([null], performRequest, options, cancellationSignal);
287
- }