rx-player 3.28.1-dev.2022083000 → 3.29.0-dev.2022090500

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 (139) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/event_listeners.d.ts +18 -2
  4. package/dist/_esm5.processed/compat/event_listeners.js +64 -2
  5. package/dist/_esm5.processed/compat/on_height_width_change.d.ts +5 -4
  6. package/dist/_esm5.processed/compat/on_height_width_change.js +43 -34
  7. package/dist/_esm5.processed/core/api/playback_observer.d.ts +12 -2
  8. package/dist/_esm5.processed/core/api/playback_observer.js +27 -12
  9. package/dist/_esm5.processed/core/api/public_api.js +14 -14
  10. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.d.ts +7 -0
  11. package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +10 -2
  12. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +8 -1
  13. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +10 -4
  14. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +7 -0
  15. package/dist/_esm5.processed/core/init/initialize_directfile.js +1 -1
  16. package/dist/_esm5.processed/core/init/load_on_media_source.js +1 -1
  17. package/dist/_esm5.processed/core/init/stall_avoider.d.ts +4 -2
  18. package/dist/_esm5.processed/core/init/stall_avoider.js +32 -26
  19. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.d.ts +12 -6
  20. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +142 -78
  21. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -16
  22. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +53 -41
  23. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.d.ts +6 -5
  24. package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +37 -39
  25. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +23 -22
  26. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +84 -72
  27. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +6 -12
  28. package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +33 -43
  29. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +12 -9
  30. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.d.ts +7 -6
  31. package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +17 -10
  32. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +20 -9
  33. package/dist/_esm5.processed/core/stream/period/period_stream.js +25 -14
  34. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.d.ts +4 -7
  35. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +80 -23
  36. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.d.ts +5 -4
  37. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +78 -26
  38. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +7 -3
  39. package/dist/_esm5.processed/core/stream/representation/push_init_segment.js +7 -1
  40. package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +7 -1
  41. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -8
  42. package/dist/_esm5.processed/default_config.js +1 -1
  43. package/dist/_esm5.processed/errors/custom_loader_error.d.ts +3 -2
  44. package/dist/_esm5.processed/errors/custom_loader_error.js +3 -2
  45. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +5 -2
  46. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.js +5 -2
  47. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.js +9 -2
  48. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +3 -1
  49. package/dist/_esm5.processed/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +4 -3
  50. package/dist/_esm5.processed/public_types.d.ts +22 -3
  51. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +2 -2
  52. package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
  53. package/dist/_esm5.processed/transports/dash/image_pipelines.js +3 -1
  54. package/dist/_esm5.processed/transports/dash/init_segment_loader.d.ts +3 -2
  55. package/dist/_esm5.processed/transports/dash/init_segment_loader.js +12 -6
  56. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.d.ts +3 -2
  57. package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +3 -2
  58. package/dist/_esm5.processed/transports/dash/manifest_parser.js +6 -2
  59. package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +3 -2
  60. package/dist/_esm5.processed/transports/dash/segment_loader.js +12 -9
  61. package/dist/_esm5.processed/transports/dash/text_loader.js +6 -3
  62. package/dist/_esm5.processed/transports/local/pipelines.d.ts +2 -2
  63. package/dist/_esm5.processed/transports/local/pipelines.js +6 -6
  64. package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
  65. package/dist/_esm5.processed/transports/local/segment_loader.js +4 -3
  66. package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.d.ts +2 -2
  67. package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.js +5 -2
  68. package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +15 -10
  69. package/dist/_esm5.processed/transports/smooth/pipelines.d.ts +1 -1
  70. package/dist/_esm5.processed/transports/smooth/pipelines.js +18 -14
  71. package/dist/_esm5.processed/transports/smooth/segment_loader.d.ts +2 -2
  72. package/dist/_esm5.processed/transports/smooth/segment_loader.js +8 -6
  73. package/dist/_esm5.processed/transports/types.d.ts +25 -2
  74. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.d.ts +2 -2
  75. package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
  76. package/dist/_esm5.processed/transports/utils/generate_manifest_loader.d.ts +2 -2
  77. package/dist/_esm5.processed/transports/utils/generate_manifest_loader.js +9 -6
  78. package/dist/_esm5.processed/utils/request/fetch.js +7 -8
  79. package/dist/_esm5.processed/utils/request/xhr.d.ts +1 -1
  80. package/dist/_esm5.processed/utils/request/xhr.js +28 -14
  81. package/dist/_esm5.processed/utils/task_canceller.d.ts +1 -2
  82. package/dist/_esm5.processed/utils/task_canceller.js +1 -2
  83. package/dist/mpd-parser.wasm +0 -0
  84. package/dist/rx-player.js +1116 -695
  85. package/dist/rx-player.min.js +1 -1
  86. package/package.json +7 -7
  87. package/sonar-project.properties +1 -1
  88. package/src/compat/event_listeners.ts +86 -1
  89. package/src/compat/on_height_width_change.ts +48 -49
  90. package/src/core/api/playback_observer.ts +34 -14
  91. package/src/core/api/public_api.ts +23 -18
  92. package/src/core/fetchers/manifest/manifest_fetcher.ts +20 -2
  93. package/src/core/fetchers/segment/segment_fetcher.ts +23 -3
  94. package/src/core/fetchers/segment/segment_fetcher_creator.ts +7 -0
  95. package/src/core/init/initialize_directfile.ts +1 -1
  96. package/src/core/init/load_on_media_source.ts +1 -0
  97. package/src/core/init/stall_avoider.ts +40 -26
  98. package/src/core/segment_buffers/garbage_collector.ts +55 -47
  99. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +92 -70
  100. package/src/core/segment_buffers/implementations/image/image_segment_buffer.ts +37 -42
  101. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +103 -105
  102. package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +35 -46
  103. package/src/core/segment_buffers/implementations/types.ts +22 -9
  104. package/src/core/segment_buffers/segment_buffers_store.ts +23 -14
  105. package/src/core/stream/orchestrator/stream_orchestrator.ts +31 -12
  106. package/src/core/stream/period/period_stream.ts +31 -18
  107. package/src/core/stream/representation/append_segment_to_buffer.ts +27 -42
  108. package/src/core/stream/representation/force_garbage_collection.ts +28 -32
  109. package/src/core/stream/representation/get_buffer_status.ts +7 -3
  110. package/src/core/stream/representation/push_init_segment.ts +12 -6
  111. package/src/core/stream/representation/push_media_segment.ts +12 -6
  112. package/src/core/stream/representation/representation_stream.ts +11 -5
  113. package/src/default_config.ts +17 -17
  114. package/src/errors/custom_loader_error.ts +3 -2
  115. package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +7 -2
  116. package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +6 -2
  117. package/src/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.ts +10 -2
  118. package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +3 -1
  119. package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +4 -3
  120. package/src/public_types.ts +28 -4
  121. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +2 -2
  122. package/src/transports/dash/image_pipelines.ts +4 -0
  123. package/src/transports/dash/init_segment_loader.ts +8 -0
  124. package/src/transports/dash/low_latency_segment_loader.ts +4 -0
  125. package/src/transports/dash/manifest_parser.ts +4 -0
  126. package/src/transports/dash/segment_loader.ts +21 -5
  127. package/src/transports/dash/text_loader.ts +7 -2
  128. package/src/transports/local/pipelines.ts +7 -5
  129. package/src/transports/local/segment_loader.ts +4 -2
  130. package/src/transports/metaplaylist/manifest_loader.ts +9 -2
  131. package/src/transports/metaplaylist/pipelines.ts +16 -6
  132. package/src/transports/smooth/pipelines.ts +17 -9
  133. package/src/transports/smooth/segment_loader.ts +8 -0
  134. package/src/transports/types.ts +27 -0
  135. package/src/transports/utils/call_custom_manifest_loader.ts +8 -2
  136. package/src/transports/utils/generate_manifest_loader.ts +18 -5
  137. package/src/utils/request/fetch.ts +7 -8
  138. package/src/utils/request/xhr.ts +31 -15
  139. package/src/utils/task_canceller.ts +1 -2
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import config from "../../config";
17
18
  import features from "../../features";
18
19
  import Manifest, {
19
20
  Adaptation,
@@ -41,6 +42,7 @@ import {
41
42
  IRequestedData,
42
43
  ISegmentContext,
43
44
  ISegmentLoaderCallbacks,
45
+ ISegmentLoaderOptions,
44
46
  ISegmentLoaderResultChunkedComplete,
45
47
  ISegmentLoaderResultSegmentCreated,
46
48
  ISegmentLoaderResultSegmentLoaded,
@@ -171,7 +173,12 @@ export default function(options : ITransportOptions): ITransportPipelines {
171
173
  cancelSignal,
172
174
  scheduleRequest));
173
175
  function loadSubManifest() {
174
- return transport.manifest.loadManifest(resource.url, cancelSignal);
176
+ /*
177
+ * Whether a ManifestLoader's timeout should be relied on here
178
+ * is ambiguous.
179
+ */
180
+ const manOpts = { timeout: config.getCurrent().DEFAULT_REQUEST_TIMEOUT };
181
+ return transport.manifest.loadManifest(resource.url, manOpts, cancelSignal);
175
182
  }
176
183
  });
177
184
 
@@ -185,7 +192,6 @@ export default function(options : ITransportOptions): ITransportPipelines {
185
192
 
186
193
  /**
187
194
  * @param {Object} segment
188
- * @param {Object} transports
189
195
  * @returns {Object}
190
196
  */
191
197
  function getTransportPipelinesFromSegment(
@@ -244,6 +250,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
244
250
  loadSegment(
245
251
  url : string | null,
246
252
  content : ISegmentContext,
253
+ loaderOptions : ISegmentLoaderOptions,
247
254
  cancelToken : CancellationSignal,
248
255
  callbacks : ISegmentLoaderCallbacks<ILoadedAudioVideoSegmentFormat>
249
256
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedAudioVideoSegmentFormat> |
@@ -253,7 +260,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
253
260
  const { segment } = content;
254
261
  const { audio } = getTransportPipelinesFromSegment(segment);
255
262
  const ogContent = getOriginalContent(segment);
256
- return audio.loadSegment(url, ogContent, cancelToken, callbacks);
263
+ return audio.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
257
264
  },
258
265
 
259
266
  parseSegment(
@@ -281,6 +288,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
281
288
  loadSegment(
282
289
  url : string | null,
283
290
  content : ISegmentContext,
291
+ loaderOptions : ISegmentLoaderOptions,
284
292
  cancelToken : CancellationSignal,
285
293
  callbacks : ISegmentLoaderCallbacks<ILoadedAudioVideoSegmentFormat>
286
294
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedAudioVideoSegmentFormat> |
@@ -290,7 +298,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
290
298
  const { segment } = content;
291
299
  const { video } = getTransportPipelinesFromSegment(segment);
292
300
  const ogContent = getOriginalContent(segment);
293
- return video.loadSegment(url, ogContent, cancelToken, callbacks);
301
+ return video.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
294
302
  },
295
303
 
296
304
  parseSegment(
@@ -318,6 +326,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
318
326
  loadSegment(
319
327
  url : string | null,
320
328
  content : ISegmentContext,
329
+ loaderOptions : ISegmentLoaderOptions,
321
330
  cancelToken : CancellationSignal,
322
331
  callbacks : ISegmentLoaderCallbacks<ILoadedTextSegmentFormat>
323
332
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedTextSegmentFormat> |
@@ -327,7 +336,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
327
336
  const { segment } = content;
328
337
  const { text } = getTransportPipelinesFromSegment(segment);
329
338
  const ogContent = getOriginalContent(segment);
330
- return text.loadSegment(url, ogContent, cancelToken, callbacks);
339
+ return text.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
331
340
  },
332
341
 
333
342
  parseSegment(
@@ -355,6 +364,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
355
364
  loadSegment(
356
365
  url : string | null,
357
366
  content : ISegmentContext,
367
+ loaderOptions : ISegmentLoaderOptions,
358
368
  cancelToken : CancellationSignal,
359
369
  callbacks : ISegmentLoaderCallbacks<ILoadedImageSegmentFormat>
360
370
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedImageSegmentFormat> |
@@ -364,7 +374,7 @@ export default function(options : ITransportOptions): ITransportPipelines {
364
374
  const { segment } = content;
365
375
  const { image } = getTransportPipelinesFromSegment(segment);
366
376
  const ogContent = getOriginalContent(segment);
367
- return image.loadSegment(url, ogContent, cancelToken, callbacks);
377
+ return image.loadSegment(url, ogContent, loaderOptions, cancelToken, callbacks);
368
378
  },
369
379
 
370
380
  parseSegment(
@@ -42,6 +42,7 @@ import {
42
42
  IRequestedData,
43
43
  ISegmentContext,
44
44
  ISegmentLoaderCallbacks,
45
+ ISegmentLoaderOptions,
45
46
  ISegmentLoaderResultSegmentCreated,
46
47
  ISegmentLoaderResultSegmentLoaded,
47
48
  ISegmentParserParsedInitChunk,
@@ -92,11 +93,11 @@ function addNextSegments(
92
93
  }
93
94
  }
94
95
 
95
- export default function(options : ITransportOptions) : ITransportPipelines {
96
- const smoothManifestParser = createSmoothManifestParser(options);
97
- const segmentLoader = generateSegmentLoader(options);
96
+ export default function(transportOptions : ITransportOptions) : ITransportPipelines {
97
+ const smoothManifestParser = createSmoothManifestParser(transportOptions);
98
+ const segmentLoader = generateSegmentLoader(transportOptions);
98
99
 
99
- const manifestLoaderOptions = { customManifestLoader: options.manifestLoader };
100
+ const manifestLoaderOptions = { customManifestLoader: transportOptions.manifestLoader };
100
101
  const manifestLoader = generateManifestLoader(manifestLoaderOptions,
101
102
  "text");
102
103
 
@@ -151,9 +152,9 @@ export default function(options : ITransportOptions) : ITransportPipelines {
151
152
  manifestReceivedTime);
152
153
 
153
154
  const manifest = new Manifest(parserResult, {
154
- representationFilter: options.representationFilter,
155
- supplementaryImageTracks: options.supplementaryImageTracks,
156
- supplementaryTextTracks: options.supplementaryTextTracks,
155
+ representationFilter: transportOptions.representationFilter,
156
+ supplementaryImageTracks: transportOptions.supplementaryImageTracks,
157
+ supplementaryTextTracks: transportOptions.supplementaryTextTracks,
157
158
  });
158
159
  return { manifest, url };
159
160
  },
@@ -168,6 +169,7 @@ export default function(options : ITransportOptions) : ITransportPipelines {
168
169
  * Load a Smooth audio/video segment.
169
170
  * @param {string|null} url
170
171
  * @param {Object} content
172
+ * @param {Object} loaderOptions
171
173
  * @param {Object} cancelSignal
172
174
  * @param {Object} callbacks
173
175
  * @returns {Promise}
@@ -175,12 +177,13 @@ export default function(options : ITransportOptions) : ITransportPipelines {
175
177
  loadSegment(
176
178
  url : string | null,
177
179
  content : ISegmentContext,
180
+ loaderOptions : ISegmentLoaderOptions,
178
181
  cancelSignal : CancellationSignal,
179
182
  callbacks : ISegmentLoaderCallbacks<ILoadedAudioVideoSegmentFormat>
180
183
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedAudioVideoSegmentFormat> |
181
184
  ISegmentLoaderResultSegmentCreated<ILoadedAudioVideoSegmentFormat>>
182
185
  {
183
- return segmentLoader(url, content, cancelSignal, callbacks);
186
+ return segmentLoader(url, content, loaderOptions, cancelSignal, callbacks);
184
187
  },
185
188
 
186
189
  parseSegment(
@@ -256,6 +259,7 @@ export default function(options : ITransportOptions) : ITransportPipelines {
256
259
  loadSegment(
257
260
  url : string | null,
258
261
  content : ISegmentContext,
262
+ loaderOptions : ISegmentLoaderOptions,
259
263
  cancelSignal : CancellationSignal,
260
264
  callbacks : ISegmentLoaderCallbacks<ILoadedTextSegmentFormat>
261
265
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedTextSegmentFormat> |
@@ -270,6 +274,7 @@ export default function(options : ITransportOptions) : ITransportPipelines {
270
274
  if (!isMP4) {
271
275
  return request({ url,
272
276
  responseType: "text",
277
+ timeout: loaderOptions.timeout,
273
278
  cancelSignal,
274
279
  onProgress: callbacks.onProgress })
275
280
  .then((data) => ({ resultType: "segment-loaded" as const,
@@ -277,10 +282,11 @@ export default function(options : ITransportOptions) : ITransportPipelines {
277
282
  } else {
278
283
  return request({ url,
279
284
  responseType: "arraybuffer",
285
+ timeout: loaderOptions.timeout,
280
286
  cancelSignal,
281
287
  onProgress: callbacks.onProgress })
282
288
  .then((data) => {
283
- if (options.checkMediaSegmentIntegrity !== true) {
289
+ if (transportOptions.checkMediaSegmentIntegrity !== true) {
284
290
  return { resultType: "segment-loaded" as const,
285
291
  resultData: data };
286
292
  }
@@ -443,6 +449,7 @@ export default function(options : ITransportOptions) : ITransportPipelines {
443
449
  async loadSegment(
444
450
  url : string | null,
445
451
  content : ISegmentContext,
452
+ loaderOptions : ISegmentLoaderOptions,
446
453
  cancelSignal : CancellationSignal,
447
454
  callbacks : ISegmentLoaderCallbacks<ILoadedImageSegmentFormat>
448
455
  ) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedImageSegmentFormat> |
@@ -455,6 +462,7 @@ export default function(options : ITransportOptions) : ITransportPipelines {
455
462
 
456
463
  const data = await request({ url,
457
464
  responseType: "arraybuffer",
465
+ timeout: loaderOptions.timeout,
458
466
  onProgress: callbacks.onProgress,
459
467
  cancelSignal });
460
468
  return { resultType: "segment-loaded" as const,
@@ -25,6 +25,7 @@ import {
25
25
  import {
26
26
  ISegmentContext,
27
27
  ISegmentLoaderCallbacks,
28
+ ISegmentLoaderOptions,
28
29
  ISegmentLoaderResultSegmentCreated,
29
30
  ISegmentLoaderResultSegmentLoaded,
30
31
  } from "../types";
@@ -40,6 +41,7 @@ import { isMP4EmbeddedTrack } from "./utils";
40
41
  * Segment loader triggered if there was no custom-defined one in the API.
41
42
  * @param {string} url
42
43
  * @param {Object} content
44
+ * @param {Object} loaderOptions
43
45
  * @param {Object} callbacks
44
46
  * @param {Object} cancelSignal
45
47
  * @param {boolean} checkMediaSegmentIntegrity
@@ -49,6 +51,7 @@ function regularSegmentLoader(
49
51
  url : string,
50
52
  content : ISegmentContext,
51
53
  callbacks : ISegmentLoaderCallbacks<Uint8Array | ArrayBuffer | null>,
54
+ loaderOptions : ISegmentLoaderOptions,
52
55
  cancelSignal : CancellationSignal,
53
56
  checkMediaSegmentIntegrity? : boolean | undefined
54
57
  ) : Promise<ISegmentLoaderResultSegmentLoaded<Uint8Array | ArrayBuffer | null>> {
@@ -61,6 +64,7 @@ function regularSegmentLoader(
61
64
  return request({ url,
62
65
  responseType: "arraybuffer",
63
66
  headers,
67
+ timeout: loaderOptions.timeout,
64
68
  cancelSignal,
65
69
  onProgress: callbacks.onProgress })
66
70
  .then((data) => {
@@ -89,6 +93,7 @@ const generateSegmentLoader = ({
89
93
  }) => (
90
94
  url : string | null,
91
95
  content : ISegmentContext,
96
+ loaderOptions : ISegmentLoaderOptions,
92
97
  cancelSignal : CancellationSignal,
93
98
  callbacks : ISegmentLoaderCallbacks<Uint8Array | ArrayBuffer | null>
94
99
  ) : Promise<ISegmentLoaderResultSegmentLoaded<Uint8Array | ArrayBuffer | null> |
@@ -154,12 +159,14 @@ const generateSegmentLoader = ({
154
159
  representation,
155
160
  segment,
156
161
  transport: "smooth",
162
+ timeout: loaderOptions.timeout,
157
163
  url };
158
164
 
159
165
  if (typeof customSegmentLoader !== "function") {
160
166
  return regularSegmentLoader(url,
161
167
  content,
162
168
  callbacks,
169
+ loaderOptions,
163
170
  cancelSignal,
164
171
  checkMediaSegmentIntegrity);
165
172
  }
@@ -249,6 +256,7 @@ const generateSegmentLoader = ({
249
256
  regularSegmentLoader(url,
250
257
  content,
251
258
  callbacks,
259
+ loaderOptions,
252
260
  cancelSignal,
253
261
  checkMediaSegmentIntegrity)
254
262
  .then(res, rej);
@@ -92,6 +92,7 @@ export interface ITransportManifestPipeline {
92
92
  */
93
93
  loadManifest : (
94
94
  url : string | undefined,
95
+ options : IManifestLoaderOptions,
95
96
  cancelSignal : CancellationSignal,
96
97
  ) => Promise<IRequestedData<ILoadedManifestFormat>>;
97
98
 
@@ -195,6 +196,20 @@ export interface ITransportManifestPipeline {
195
196
  ) => Promise<string | undefined>;
196
197
  }
197
198
 
199
+ /**
200
+ * Options given to the `loadManifest` method of an
201
+ * `ITransportManifestPipeline` to configure its behavior.
202
+ */
203
+ export interface IManifestLoaderOptions {
204
+ /**
205
+ * Timeout, in milliseconds, after which a manifest request should be aborted
206
+ * with the corresponding error.
207
+ *
208
+ * `undefined` means that no timeout will be enforced.
209
+ */
210
+ timeout? : number | undefined;
211
+ }
212
+
198
213
  /** Functions allowing to load and parse segments of any type. */
199
214
  export interface ISegmentPipeline<
200
215
  TLoadedFormat,
@@ -224,12 +239,24 @@ export interface ISegmentPipeline<
224
239
  export type ISegmentLoader<TLoadedFormat> = (
225
240
  url : string | null,
226
241
  content : ISegmentContext,
242
+ options : ISegmentLoaderOptions,
227
243
  cancelSignal : CancellationSignal,
228
244
  callbacks : ISegmentLoaderCallbacks<TLoadedFormat>
229
245
  ) => Promise<ISegmentLoaderResultSegmentCreated<TLoadedFormat> |
230
246
  ISegmentLoaderResultSegmentLoaded<TLoadedFormat> |
231
247
  ISegmentLoaderResultChunkedComplete>;
232
248
 
249
+ /** Options given to an `ISegmentLoader` to configure its behavior. */
250
+ export interface ISegmentLoaderOptions {
251
+ /**
252
+ * Timeout, in milliseconds, after which a segment request should be aborted
253
+ * with the corresponding error.
254
+ *
255
+ * `undefined` means that no timeout will be enforced.
256
+ */
257
+ timeout? : number | undefined;
258
+ }
259
+
233
260
  /**
234
261
  * Segment parser function, allowing to parse a chunk (which may be a sub-part
235
262
  * of a segment) of any type.
@@ -24,6 +24,7 @@ import {
24
24
  CancellationSignal,
25
25
  } from "../../utils/task_canceller";
26
26
  import {
27
+ IManifestLoaderOptions,
27
28
  IRequestedData,
28
29
  } from "../types";
29
30
 
@@ -31,15 +32,18 @@ export default function callCustomManifestLoader(
31
32
  customManifestLoader : IManifestLoader,
32
33
  fallbackManifestLoader : (
33
34
  url : string | undefined,
35
+ loaderOptions : IManifestLoaderOptions,
34
36
  cancelSignal : CancellationSignal
35
37
  ) => Promise< IRequestedData<ILoadedManifestFormat> >
36
38
  ) : (
37
39
  url : string | undefined,
40
+ loaderOptions : IManifestLoaderOptions,
38
41
  cancelSignal : CancellationSignal
39
42
  ) => Promise< IRequestedData<ILoadedManifestFormat> >
40
43
  {
41
44
  return (
42
45
  url : string | undefined,
46
+ loaderOptions : IManifestLoaderOptions,
43
47
  cancelSignal : CancellationSignal
44
48
  ) : Promise< IRequestedData<ILoadedManifestFormat> > => {
45
49
  return new Promise((res, rej) => {
@@ -114,11 +118,13 @@ export default function callCustomManifestLoader(
114
118
  }
115
119
  hasFinished = true;
116
120
  cancelSignal.deregister(abortCustomLoader);
117
- fallbackManifestLoader(url, cancelSignal).then(res, rej);
121
+ fallbackManifestLoader(url, loaderOptions, cancelSignal).then(res, rej);
118
122
  };
119
123
 
120
124
  const callbacks = { reject, resolve, fallback };
121
- const abort = customManifestLoader(url, callbacks);
125
+ const abort = customManifestLoader(url,
126
+ callbacks,
127
+ { timeout: loaderOptions.timeout });
122
128
 
123
129
  cancelSignal.register(abortCustomLoader);
124
130
 
@@ -22,24 +22,27 @@ import assertUnreachable from "../../utils/assert_unreachable";
22
22
  import request from "../../utils/request";
23
23
  import { CancellationSignal } from "../../utils/task_canceller";
24
24
  import {
25
+ IManifestLoaderOptions,
25
26
  IRequestedData,
26
27
  } from "../types";
27
28
  import callCustomManifestLoader from "./call_custom_manifest_loader";
28
29
 
29
30
  /**
30
31
  * Manifest loader triggered if there was no custom-defined one in the API.
31
- * @param {string} url
32
- * @returns {Observable}
32
+ * @param {string} preferredType
33
+ * @returns {Function}
33
34
  */
34
35
  function generateRegularManifestLoader(
35
36
  preferredType: "arraybuffer" | "text" | "document"
36
37
  ) : (
37
38
  url : string | undefined,
39
+ loaderOptions : IManifestLoaderOptions,
38
40
  cancelSignal : CancellationSignal
39
41
  ) => Promise < IRequestedData<ILoadedManifestFormat> >
40
42
  {
41
43
  return function regularManifestLoader(
42
44
  url : string | undefined,
45
+ loaderOptions : IManifestLoaderOptions,
43
46
  cancelSignal : CancellationSignal
44
47
  ) : Promise< IRequestedData<ILoadedManifestFormat> > {
45
48
  if (url === undefined) {
@@ -51,11 +54,20 @@ function generateRegularManifestLoader(
51
54
  // So I wrote that instead, temporarily of course ;)
52
55
  switch (preferredType) {
53
56
  case "arraybuffer":
54
- return request({ url, responseType: "arraybuffer", cancelSignal });
57
+ return request({ url,
58
+ responseType: "arraybuffer",
59
+ timeout: loaderOptions.timeout,
60
+ cancelSignal });
55
61
  case "text":
56
- return request({ url, responseType: "text", cancelSignal });
62
+ return request({ url,
63
+ responseType: "text",
64
+ timeout: loaderOptions.timeout,
65
+ cancelSignal });
57
66
  case "document":
58
- return request({ url, responseType: "document", cancelSignal });
67
+ return request({ url,
68
+ responseType: "document",
69
+ timeout: loaderOptions.timeout,
70
+ cancelSignal });
59
71
  default:
60
72
  assertUnreachable(preferredType);
61
73
  }
@@ -72,6 +84,7 @@ export default function generateManifestLoader(
72
84
  preferredType: "arraybuffer" | "text" | "document"
73
85
  ) : (
74
86
  url : string | undefined,
87
+ loaderOptions : IManifestLoaderOptions,
75
88
  cancelSignal : CancellationSignal
76
89
  ) => Promise<IRequestedData<ILoadedManifestFormat>>
77
90
  {
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import config from "../../config";
18
17
  import {
19
18
  NetworkErrorTypes,
20
19
  RequestError,
@@ -145,13 +144,13 @@ export default function fetchRequest(
145
144
  abortController.abort();
146
145
  }
147
146
 
148
- const requestTimeout = isNullOrUndefined(options.timeout) ?
149
- config.getCurrent().DEFAULT_REQUEST_TIMEOUT :
150
- options.timeout;
151
- const timeout = window.setTimeout(() => {
152
- timeouted = true;
153
- abortFetch();
154
- }, requestTimeout);
147
+ let timeout : number | undefined;
148
+ if (options.timeout !== undefined) {
149
+ timeout = window.setTimeout(() => {
150
+ timeouted = true;
151
+ abortFetch();
152
+ }, options.timeout);
153
+ }
155
154
 
156
155
  const deregisterCancelLstnr = options.cancelSignal
157
156
  .register(function abortRequest(err : CancellationError) {
@@ -14,7 +14,6 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import config from "../../config";
18
17
  import { RequestError } from "../../errors";
19
18
  import isNonEmptyString from "../is_non_empty_string";
20
19
  import isNullOrUndefined from "../is_null_or_undefined";
@@ -129,14 +128,12 @@ export default function request<T>(
129
128
  options : IRequestOptions< XMLHttpRequestResponseType | null | undefined >
130
129
  ) : Promise<IRequestResponse< T, XMLHttpRequestResponseType >> {
131
130
 
132
- const { DEFAULT_REQUEST_TIMEOUT } = config.getCurrent();
133
131
  const requestOptions = {
134
132
  url: options.url,
135
133
  headers: options.headers,
136
134
  responseType: isNullOrUndefined(options.responseType) ? DEFAULT_RESPONSE_TYPE :
137
135
  options.responseType,
138
- timeout: isNullOrUndefined(options.timeout) ? DEFAULT_REQUEST_TIMEOUT :
139
- options.timeout,
136
+ timeout: options.timeout,
140
137
  };
141
138
 
142
139
  return new Promise((resolve, reject) => {
@@ -148,8 +145,20 @@ export default function request<T>(
148
145
  const xhr = new XMLHttpRequest();
149
146
  xhr.open("GET", url, true);
150
147
 
151
- if (timeout >= 0) {
148
+ let timeoutId : undefined | number;
149
+ if (timeout !== undefined) {
152
150
  xhr.timeout = timeout;
151
+
152
+ // We've seen on some browser (mainly on some LG TVs), that `xhr.timeout`
153
+ // was either not supported or did not function properly despite the
154
+ // browser being recent enough to support it.
155
+ // That's why we also start a manual timeout. We do this a little later
156
+ // than the "native one" performed on the xhr assuming that the latter
157
+ // is more precise, it might also be more efficient.
158
+ timeoutId = window.setTimeout(() => {
159
+ clearCancellingProcess();
160
+ reject(new RequestError(url, xhr.status, "TIMEOUT", xhr));
161
+ }, timeout + 3000);
153
162
  }
154
163
 
155
164
  xhr.responseType = responseType;
@@ -174,6 +183,7 @@ export default function request<T>(
174
183
  if (cancelSignal !== undefined) {
175
184
  deregisterCancellationListener = cancelSignal
176
185
  .register(function abortRequest(err : CancellationError) {
186
+ clearCancellingProcess();
177
187
  if (!isNullOrUndefined(xhr) && xhr.readyState !== 4) {
178
188
  xhr.abort();
179
189
  }
@@ -186,16 +196,12 @@ export default function request<T>(
186
196
  }
187
197
 
188
198
  xhr.onerror = function onXHRError() {
189
- if (deregisterCancellationListener !== null) {
190
- deregisterCancellationListener();
191
- }
199
+ clearCancellingProcess();
192
200
  reject(new RequestError(url, xhr.status, "ERROR_EVENT", xhr));
193
201
  };
194
202
 
195
203
  xhr.ontimeout = function onXHRTimeout() {
196
- if (deregisterCancellationListener !== null) {
197
- deregisterCancellationListener();
198
- }
204
+ clearCancellingProcess();
199
205
  reject(new RequestError(url, xhr.status, "TIMEOUT", xhr));
200
206
  };
201
207
 
@@ -213,9 +219,7 @@ export default function request<T>(
213
219
 
214
220
  xhr.onload = function onXHRLoad(event : ProgressEvent) {
215
221
  if (xhr.readyState === 4) {
216
- if (deregisterCancellationListener !== null) {
217
- deregisterCancellationListener();
218
- }
222
+ clearCancellingProcess();
219
223
  if (xhr.status >= 200 && xhr.status < 300) {
220
224
  const receivedTime = performance.now();
221
225
  const totalSize = xhr.response instanceof
@@ -259,6 +263,18 @@ export default function request<T>(
259
263
  };
260
264
 
261
265
  xhr.send();
266
+
267
+ /**
268
+ * Clear resources and timers created to handle cancellation and timeouts.
269
+ */
270
+ function clearCancellingProcess() {
271
+ if (timeoutId !== undefined) {
272
+ clearTimeout(timeoutId);
273
+ }
274
+ if (deregisterCancellationListener !== null) {
275
+ deregisterCancellationListener();
276
+ }
277
+ }
262
278
  });
263
279
  }
264
280
 
@@ -286,7 +302,7 @@ export interface IRequestOptions<ResponseType> {
286
302
  responseType? : ResponseType | undefined;
287
303
  /**
288
304
  * Optional timeout, in milliseconds, after which we will cancel a request.
289
- * Set to DEFAULT_REQUEST_TIMEOUT by default.
305
+ * To not set or to set to `undefined` for disable.
290
306
  */
291
307
  timeout? : number | undefined;
292
308
  /**
@@ -299,8 +299,7 @@ export class CancellationSignal {
299
299
  export type ICancellationListener = (error : CancellationError) => void;
300
300
 
301
301
  /**
302
- * Error created when a task is cancelled through the TaskCanceller.
303
- *
302
+ * Error created when a task is cancelled.
304
303
  * @class CancellationError
305
304
  * @extends Error
306
305
  */