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.
- package/CHANGELOG.md +11 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/event_listeners.d.ts +18 -2
- package/dist/_esm5.processed/compat/event_listeners.js +64 -2
- package/dist/_esm5.processed/compat/on_height_width_change.d.ts +5 -4
- package/dist/_esm5.processed/compat/on_height_width_change.js +43 -34
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +12 -2
- package/dist/_esm5.processed/core/api/playback_observer.js +27 -12
- package/dist/_esm5.processed/core/api/public_api.js +14 -14
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.d.ts +7 -0
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +10 -2
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +8 -1
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +10 -4
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +7 -0
- package/dist/_esm5.processed/core/init/initialize_directfile.js +1 -1
- package/dist/_esm5.processed/core/init/load_on_media_source.js +1 -1
- package/dist/_esm5.processed/core/init/stall_avoider.d.ts +4 -2
- package/dist/_esm5.processed/core/init/stall_avoider.js +32 -26
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.d.ts +12 -6
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +142 -78
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -16
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +53 -41
- package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.d.ts +6 -5
- package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +37 -39
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +23 -22
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +84 -72
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +6 -12
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +33 -43
- package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +12 -9
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.d.ts +7 -6
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +17 -10
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +20 -9
- package/dist/_esm5.processed/core/stream/period/period_stream.js +25 -14
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.d.ts +4 -7
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +80 -23
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.d.ts +5 -4
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +78 -26
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +7 -3
- package/dist/_esm5.processed/core/stream/representation/push_init_segment.js +7 -1
- package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +7 -1
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -8
- package/dist/_esm5.processed/default_config.js +1 -1
- package/dist/_esm5.processed/errors/custom_loader_error.d.ts +3 -2
- package/dist/_esm5.processed/errors/custom_loader_error.js +3 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +5 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.js +5 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.js +9 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +3 -1
- package/dist/_esm5.processed/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +4 -3
- package/dist/_esm5.processed/public_types.d.ts +22 -3
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +2 -2
- package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/image_pipelines.js +3 -1
- package/dist/_esm5.processed/transports/dash/init_segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/init_segment_loader.js +12 -6
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +3 -2
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +6 -2
- package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/segment_loader.js +12 -9
- package/dist/_esm5.processed/transports/dash/text_loader.js +6 -3
- package/dist/_esm5.processed/transports/local/pipelines.d.ts +2 -2
- package/dist/_esm5.processed/transports/local/pipelines.js +6 -6
- package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/local/segment_loader.js +4 -3
- package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.js +5 -2
- package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +15 -10
- package/dist/_esm5.processed/transports/smooth/pipelines.d.ts +1 -1
- package/dist/_esm5.processed/transports/smooth/pipelines.js +18 -14
- package/dist/_esm5.processed/transports/smooth/segment_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +8 -6
- package/dist/_esm5.processed/transports/types.d.ts +25 -2
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
- package/dist/_esm5.processed/transports/utils/generate_manifest_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/utils/generate_manifest_loader.js +9 -6
- package/dist/_esm5.processed/utils/request/fetch.js +7 -8
- package/dist/_esm5.processed/utils/request/xhr.d.ts +1 -1
- package/dist/_esm5.processed/utils/request/xhr.js +28 -14
- package/dist/_esm5.processed/utils/task_canceller.d.ts +1 -2
- package/dist/_esm5.processed/utils/task_canceller.js +1 -2
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.js +1116 -695
- package/dist/rx-player.min.js +1 -1
- package/package.json +7 -7
- package/sonar-project.properties +1 -1
- package/src/compat/event_listeners.ts +86 -1
- package/src/compat/on_height_width_change.ts +48 -49
- package/src/core/api/playback_observer.ts +34 -14
- package/src/core/api/public_api.ts +23 -18
- package/src/core/fetchers/manifest/manifest_fetcher.ts +20 -2
- package/src/core/fetchers/segment/segment_fetcher.ts +23 -3
- package/src/core/fetchers/segment/segment_fetcher_creator.ts +7 -0
- package/src/core/init/initialize_directfile.ts +1 -1
- package/src/core/init/load_on_media_source.ts +1 -0
- package/src/core/init/stall_avoider.ts +40 -26
- package/src/core/segment_buffers/garbage_collector.ts +55 -47
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +92 -70
- package/src/core/segment_buffers/implementations/image/image_segment_buffer.ts +37 -42
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +103 -105
- package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +35 -46
- package/src/core/segment_buffers/implementations/types.ts +22 -9
- package/src/core/segment_buffers/segment_buffers_store.ts +23 -14
- package/src/core/stream/orchestrator/stream_orchestrator.ts +31 -12
- package/src/core/stream/period/period_stream.ts +31 -18
- package/src/core/stream/representation/append_segment_to_buffer.ts +27 -42
- package/src/core/stream/representation/force_garbage_collection.ts +28 -32
- package/src/core/stream/representation/get_buffer_status.ts +7 -3
- package/src/core/stream/representation/push_init_segment.ts +12 -6
- package/src/core/stream/representation/push_media_segment.ts +12 -6
- package/src/core/stream/representation/representation_stream.ts +11 -5
- package/src/default_config.ts +17 -17
- package/src/errors/custom_loader_error.ts +3 -2
- package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +7 -2
- package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +6 -2
- package/src/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.ts +10 -2
- package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +3 -1
- package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +4 -3
- package/src/public_types.ts +28 -4
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +2 -2
- package/src/transports/dash/image_pipelines.ts +4 -0
- package/src/transports/dash/init_segment_loader.ts +8 -0
- package/src/transports/dash/low_latency_segment_loader.ts +4 -0
- package/src/transports/dash/manifest_parser.ts +4 -0
- package/src/transports/dash/segment_loader.ts +21 -5
- package/src/transports/dash/text_loader.ts +7 -2
- package/src/transports/local/pipelines.ts +7 -5
- package/src/transports/local/segment_loader.ts +4 -2
- package/src/transports/metaplaylist/manifest_loader.ts +9 -2
- package/src/transports/metaplaylist/pipelines.ts +16 -6
- package/src/transports/smooth/pipelines.ts +17 -9
- package/src/transports/smooth/segment_loader.ts +8 -0
- package/src/transports/types.ts +27 -0
- package/src/transports/utils/call_custom_manifest_loader.ts +8 -2
- package/src/transports/utils/generate_manifest_loader.ts +18 -5
- package/src/utils/request/fetch.ts +7 -8
- package/src/utils/request/xhr.ts +31 -15
- 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
|
-
|
|
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(
|
|
96
|
-
const smoothManifestParser = createSmoothManifestParser(
|
|
97
|
-
const segmentLoader = generateSegmentLoader(
|
|
96
|
+
export default function(transportOptions : ITransportOptions) : ITransportPipelines {
|
|
97
|
+
const smoothManifestParser = createSmoothManifestParser(transportOptions);
|
|
98
|
+
const segmentLoader = generateSegmentLoader(transportOptions);
|
|
98
99
|
|
|
99
|
-
const manifestLoaderOptions = { customManifestLoader:
|
|
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:
|
|
155
|
-
supplementaryImageTracks:
|
|
156
|
-
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 (
|
|
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);
|
package/src/transports/types.ts
CHANGED
|
@@ -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,
|
|
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}
|
|
32
|
-
* @returns {
|
|
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,
|
|
57
|
+
return request({ url,
|
|
58
|
+
responseType: "arraybuffer",
|
|
59
|
+
timeout: loaderOptions.timeout,
|
|
60
|
+
cancelSignal });
|
|
55
61
|
case "text":
|
|
56
|
-
return request({ url,
|
|
62
|
+
return request({ url,
|
|
63
|
+
responseType: "text",
|
|
64
|
+
timeout: loaderOptions.timeout,
|
|
65
|
+
cancelSignal });
|
|
57
66
|
case "document":
|
|
58
|
-
return request({ url,
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
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) {
|
package/src/utils/request/xhr.ts
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
303
|
-
*
|
|
302
|
+
* Error created when a task is cancelled.
|
|
304
303
|
* @class CancellationError
|
|
305
304
|
* @extends Error
|
|
306
305
|
*/
|