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
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
of as observableOf,
|
|
21
21
|
} from "rxjs";
|
|
22
22
|
import { AudioVideoSegmentBuffer } from "../../../core/segment_buffers/implementations";
|
|
23
|
+
import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
|
|
24
|
+
import TaskCanceller from "../../../utils/task_canceller";
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* Remove buffer around wanted time, considering a margin around
|
|
@@ -42,11 +44,17 @@ export default function removeBufferAroundTime$(
|
|
|
42
44
|
return observableOf(null);
|
|
43
45
|
}
|
|
44
46
|
const bufferRemovals$ = [];
|
|
47
|
+
const removalCanceller = new TaskCanceller();
|
|
45
48
|
if ((time - margin) > 0) {
|
|
46
|
-
bufferRemovals$.push(
|
|
49
|
+
bufferRemovals$.push(
|
|
50
|
+
fromCancellablePromise(removalCanceller, () =>
|
|
51
|
+
sourceBuffer.removeBuffer(0, time - margin, removalCanceller.signal)));
|
|
47
52
|
}
|
|
48
53
|
if ((time + margin) < videoElement.duration) {
|
|
49
|
-
bufferRemovals$.push(
|
|
54
|
+
bufferRemovals$.push(fromCancellablePromise(removalCanceller, () =>
|
|
55
|
+
sourceBuffer.removeBuffer(time + margin,
|
|
56
|
+
videoElement.duration,
|
|
57
|
+
removalCanceller.signal)));
|
|
50
58
|
}
|
|
51
59
|
return observableCombineLatest(bufferRemovals$);
|
|
52
60
|
}
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
take,
|
|
29
29
|
tap,
|
|
30
30
|
} from "rxjs";
|
|
31
|
+
import config from "../../../config";
|
|
31
32
|
import Player from "../../../core/api";
|
|
32
33
|
import createSegmentFetcher, {
|
|
33
34
|
ISegmentFetcher,
|
|
@@ -214,7 +215,8 @@ export default class VideoThumbnailLoader {
|
|
|
214
215
|
{ baseDelay: 0,
|
|
215
216
|
maxDelay: 0,
|
|
216
217
|
maxRetryOffline: 0,
|
|
217
|
-
maxRetryRegular: 0
|
|
218
|
+
maxRetryRegular: 0,
|
|
219
|
+
requestTimeout: config.getCurrent().DEFAULT_REQUEST_TIMEOUT }
|
|
218
220
|
) as ISegmentFetcher<ArrayBuffer | Uint8Array>;
|
|
219
221
|
|
|
220
222
|
const taskPromise: Promise<number> = lastValueFrom(observableRace(
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
Observable,
|
|
20
20
|
throwError,
|
|
21
21
|
} from "rxjs";
|
|
22
|
+
import config from "../../../config";
|
|
22
23
|
import { IMetaPlaylist } from "../../../parsers/manifest/metaplaylist";
|
|
23
24
|
import isNonEmptyString from "../../../utils/is_non_empty_string";
|
|
24
25
|
import request from "../../../utils/request/xhr";
|
|
@@ -37,9 +38,7 @@ const iso8601Duration =
|
|
|
37
38
|
* 2. the second value is a possible error encountered while parsing this
|
|
38
39
|
* value - set to `null` if no error was encountered.
|
|
39
40
|
* @param {string} val - The value to parse
|
|
40
|
-
* @
|
|
41
|
-
* formatting.
|
|
42
|
-
* @returns {Array.<number | Error | null>}
|
|
41
|
+
* @returns {number | null}
|
|
43
42
|
*/
|
|
44
43
|
function parseDuration(val : string) : number | null {
|
|
45
44
|
|
|
@@ -90,6 +89,7 @@ function getDurationFromManifest(url: string,
|
|
|
90
89
|
canceller,
|
|
91
90
|
() => request({ url,
|
|
92
91
|
responseType: "document",
|
|
92
|
+
timeout: config.getCurrent().DEFAULT_REQUEST_TIMEOUT,
|
|
93
93
|
cancelSignal: canceller.signal })
|
|
94
94
|
).pipe(map((response) => {
|
|
95
95
|
const { responseData } = response;
|
|
@@ -129,6 +129,7 @@ function getDurationFromManifest(url: string,
|
|
|
129
129
|
canceller,
|
|
130
130
|
() => request({ url,
|
|
131
131
|
responseType: "text",
|
|
132
|
+
timeout: config.getCurrent().DEFAULT_REQUEST_TIMEOUT,
|
|
132
133
|
cancelSignal: canceller.signal })
|
|
133
134
|
).pipe(map((response) => {
|
|
134
135
|
const { responseData } = response;
|
package/src/public_types.ts
CHANGED
|
@@ -364,24 +364,44 @@ export interface INetworkConfigOption {
|
|
|
364
364
|
* request before failing on Error.
|
|
365
365
|
* Set to `Infinity` for an infinite number of requests.
|
|
366
366
|
*/
|
|
367
|
-
manifestRetry? : number;
|
|
367
|
+
manifestRetry? : number | undefined;
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Amount of time, in milliseconds, after which a manifest request should be
|
|
371
|
+
* aborted and optionally retried, depending on the current configuration.
|
|
372
|
+
*
|
|
373
|
+
* Setting it to `-1` allows to disable any timeout.
|
|
374
|
+
* `undefined` means that a default, large, timeout will be used instead.
|
|
375
|
+
*/
|
|
376
|
+
manifestRequestTimeout? : number | undefined;
|
|
377
|
+
|
|
368
378
|
/**
|
|
369
379
|
* The amount of time maximum we should retry a request in general when the
|
|
370
380
|
* user is offline.
|
|
371
381
|
* Set to `Infinity` for an infinite number of requests.
|
|
372
382
|
*/
|
|
373
|
-
offlineRetry? : number;
|
|
383
|
+
offlineRetry? : number | undefined;
|
|
374
384
|
/**
|
|
375
385
|
* The amount of time maximum we should retry a segment or segment-related
|
|
376
386
|
* request before failing on Error.
|
|
377
387
|
* Set to `Infinity` for an infinite number of requests.
|
|
378
388
|
*/
|
|
379
|
-
segmentRetry? : number;
|
|
389
|
+
segmentRetry? : number | undefined;
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Amount of time, in milliseconds, after which a segment request should be
|
|
393
|
+
* aborted and optionally retried, depending on the current configuration.
|
|
394
|
+
*
|
|
395
|
+
* Setting it to `-1` allows to disable any timeout.
|
|
396
|
+
* `undefined` means that a default, large, timeout will be used instead.
|
|
397
|
+
*/
|
|
398
|
+
segmentRequestTimeout? : number | undefined;
|
|
380
399
|
}
|
|
381
400
|
|
|
382
401
|
export type ISegmentLoader = (
|
|
383
402
|
// first argument: infos on the segment
|
|
384
403
|
infos : { url : string;
|
|
404
|
+
timeout : number | undefined;
|
|
385
405
|
manifest : IManifest;
|
|
386
406
|
period : IPeriod;
|
|
387
407
|
adaptation : IAdaptation;
|
|
@@ -423,7 +443,11 @@ export type IManifestLoader = (
|
|
|
423
443
|
=> void;
|
|
424
444
|
|
|
425
445
|
reject : (err? : Error) => void;
|
|
426
|
-
fallback : () => void; }
|
|
446
|
+
fallback : () => void; },
|
|
447
|
+
|
|
448
|
+
options : {
|
|
449
|
+
timeout : number | undefined;
|
|
450
|
+
}
|
|
427
451
|
) =>
|
|
428
452
|
// returns either the aborting callback or nothing
|
|
429
453
|
(() => void)|void;
|
|
@@ -29,7 +29,7 @@ import inferSegmentContainer from "../utils/infer_segment_container";
|
|
|
29
29
|
export default function addSegmentIntegrityChecks<T>(
|
|
30
30
|
segmentLoader : ISegmentLoader<T>
|
|
31
31
|
) : ISegmentLoader<T> {
|
|
32
|
-
return (url, content, initialCancelSignal, callbacks) => {
|
|
32
|
+
return (url, content, loaderOptions, initialCancelSignal, callbacks) => {
|
|
33
33
|
return new Promise((resolve, reject) => {
|
|
34
34
|
const requestCanceller = new TaskCanceller({ cancelOn: initialCancelSignal });
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ export default function addSegmentIntegrityChecks<T>(
|
|
|
37
37
|
// `stopRejectingOnCancel` here is a function allowing to stop this mechanism
|
|
38
38
|
const stopRejectingOnCancel = requestCanceller.signal.register(reject);
|
|
39
39
|
|
|
40
|
-
segmentLoader(url, content, requestCanceller.signal, {
|
|
40
|
+
segmentLoader(url, content, loaderOptions, requestCanceller.signal, {
|
|
41
41
|
...callbacks,
|
|
42
42
|
onNewChunk(data) {
|
|
43
43
|
try {
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
ILoadedImageSegmentFormat,
|
|
24
24
|
ISegmentContext,
|
|
25
25
|
ISegmentLoaderCallbacks,
|
|
26
|
+
ISegmentLoaderOptions,
|
|
26
27
|
ISegmentLoaderResultSegmentCreated,
|
|
27
28
|
ISegmentLoaderResultSegmentLoaded,
|
|
28
29
|
ISegmentParserParsedInitChunk,
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
* Loads an image segment.
|
|
34
35
|
* @param {string|null} url
|
|
35
36
|
* @param {Object} content
|
|
37
|
+
* @param {Object} options
|
|
36
38
|
* @param {Object} cancelSignal
|
|
37
39
|
* @param {Object} callbacks
|
|
38
40
|
* @returns {Promise}
|
|
@@ -40,6 +42,7 @@ import {
|
|
|
40
42
|
export async function imageLoader(
|
|
41
43
|
url : string | null,
|
|
42
44
|
content : ISegmentContext,
|
|
45
|
+
options : ISegmentLoaderOptions,
|
|
43
46
|
cancelSignal : CancellationSignal,
|
|
44
47
|
callbacks : ISegmentLoaderCallbacks<ILoadedImageSegmentFormat>
|
|
45
48
|
) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedImageSegmentFormat> |
|
|
@@ -52,6 +55,7 @@ export async function imageLoader(
|
|
|
52
55
|
}
|
|
53
56
|
const data = await request({ url,
|
|
54
57
|
responseType: "arraybuffer",
|
|
58
|
+
timeout: options.timeout,
|
|
55
59
|
onProgress: callbacks.onProgress,
|
|
56
60
|
cancelSignal });
|
|
57
61
|
return { resultType: "segment-loaded",
|
|
@@ -20,6 +20,7 @@ import request from "../../utils/request";
|
|
|
20
20
|
import { CancellationSignal } from "../../utils/task_canceller";
|
|
21
21
|
import {
|
|
22
22
|
ISegmentLoaderCallbacks,
|
|
23
|
+
ISegmentLoaderOptions,
|
|
23
24
|
ISegmentLoaderResultChunkedComplete,
|
|
24
25
|
ISegmentLoaderResultSegmentCreated,
|
|
25
26
|
ISegmentLoaderResultSegmentLoaded,
|
|
@@ -30,6 +31,7 @@ import byteRange from "../utils/byte_range";
|
|
|
30
31
|
* Perform a request for an initialization segment, agnostic to the container.
|
|
31
32
|
* @param {string} url
|
|
32
33
|
* @param {Object} segment
|
|
34
|
+
* @param {Object} options
|
|
33
35
|
* @param {CancellationSignal} cancelSignal
|
|
34
36
|
* @param {Object} callbacks
|
|
35
37
|
* @returns {Promise}
|
|
@@ -37,6 +39,7 @@ import byteRange from "../utils/byte_range";
|
|
|
37
39
|
export default function initSegmentLoader(
|
|
38
40
|
url : string,
|
|
39
41
|
segment : ISegment,
|
|
42
|
+
options : ISegmentLoaderOptions,
|
|
40
43
|
cancelSignal : CancellationSignal,
|
|
41
44
|
callbacks : ISegmentLoaderCallbacks<ArrayBuffer | Uint8Array>
|
|
42
45
|
) : Promise<ISegmentLoaderResultSegmentLoaded<ArrayBuffer | Uint8Array> |
|
|
@@ -46,6 +49,7 @@ export default function initSegmentLoader(
|
|
|
46
49
|
if (segment.range === undefined) {
|
|
47
50
|
return request({ url,
|
|
48
51
|
responseType: "arraybuffer",
|
|
52
|
+
timeout: options.timeout,
|
|
49
53
|
cancelSignal,
|
|
50
54
|
onProgress: callbacks.onProgress })
|
|
51
55
|
.then(data => ({ resultType: "segment-loaded",
|
|
@@ -56,6 +60,7 @@ export default function initSegmentLoader(
|
|
|
56
60
|
return request({ url,
|
|
57
61
|
headers: { Range: byteRange(segment.range) },
|
|
58
62
|
responseType: "arraybuffer",
|
|
63
|
+
timeout: options.timeout,
|
|
59
64
|
cancelSignal,
|
|
60
65
|
onProgress: callbacks.onProgress })
|
|
61
66
|
.then(data => ({ resultType: "segment-loaded",
|
|
@@ -68,6 +73,7 @@ export default function initSegmentLoader(
|
|
|
68
73
|
headers: { Range: byteRange([segment.range[0],
|
|
69
74
|
segment.indexRange[1] ]) },
|
|
70
75
|
responseType: "arraybuffer",
|
|
76
|
+
timeout: options.timeout,
|
|
71
77
|
cancelSignal,
|
|
72
78
|
onProgress: callbacks.onProgress })
|
|
73
79
|
.then(data => ({ resultType: "segment-loaded",
|
|
@@ -77,11 +83,13 @@ export default function initSegmentLoader(
|
|
|
77
83
|
const rangeRequest$ = request({ url,
|
|
78
84
|
headers: { Range: byteRange(segment.range) },
|
|
79
85
|
responseType: "arraybuffer",
|
|
86
|
+
timeout: options.timeout,
|
|
80
87
|
cancelSignal,
|
|
81
88
|
onProgress: callbacks.onProgress });
|
|
82
89
|
const indexRequest$ = request({ url,
|
|
83
90
|
headers: { Range: byteRange(segment.indexRange) },
|
|
84
91
|
responseType: "arraybuffer",
|
|
92
|
+
timeout: options.timeout,
|
|
85
93
|
cancelSignal,
|
|
86
94
|
onProgress: callbacks.onProgress });
|
|
87
95
|
|
|
@@ -22,6 +22,7 @@ import { CancellationSignal } from "../../utils/task_canceller";
|
|
|
22
22
|
import {
|
|
23
23
|
ISegmentContext,
|
|
24
24
|
ISegmentLoaderCallbacks,
|
|
25
|
+
ISegmentLoaderOptions,
|
|
25
26
|
ISegmentLoaderResultChunkedComplete,
|
|
26
27
|
} from "../types";
|
|
27
28
|
import byteRange from "../utils/byte_range";
|
|
@@ -34,6 +35,7 @@ import extractCompleteChunks from "./extract_complete_chunks";
|
|
|
34
35
|
*
|
|
35
36
|
* @param {string} url - URL of the segment to download.
|
|
36
37
|
* @param {Object} content - Context of the segment needed.
|
|
38
|
+
* @param {Object} options
|
|
37
39
|
* @param {Object} callbacks
|
|
38
40
|
* @param {CancellationSignal} cancelSignal
|
|
39
41
|
* @returns {Promise}
|
|
@@ -41,6 +43,7 @@ import extractCompleteChunks from "./extract_complete_chunks";
|
|
|
41
43
|
export default function lowLatencySegmentLoader(
|
|
42
44
|
url : string,
|
|
43
45
|
content : ISegmentContext,
|
|
46
|
+
options : ISegmentLoaderOptions,
|
|
44
47
|
callbacks : ISegmentLoaderCallbacks<Uint8Array>,
|
|
45
48
|
cancelSignal : CancellationSignal
|
|
46
49
|
) : Promise<ISegmentLoaderResultChunkedComplete> {
|
|
@@ -77,6 +80,7 @@ export default function lowLatencySegmentLoader(
|
|
|
77
80
|
return fetchRequest({ url,
|
|
78
81
|
headers,
|
|
79
82
|
onData,
|
|
83
|
+
timeout: options.timeout,
|
|
80
84
|
cancelSignal })
|
|
81
85
|
.then((res) => ({ resultType: "chunk-complete" as const,
|
|
82
86
|
resultData: res }));
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import config from "../../config";
|
|
17
18
|
import { formatError } from "../../errors";
|
|
18
19
|
import features from "../../features";
|
|
19
20
|
import log from "../../log";
|
|
@@ -149,12 +150,15 @@ export default function generateManifestParser(
|
|
|
149
150
|
|
|
150
151
|
const externalResources = value.urls.map(resourceUrl => {
|
|
151
152
|
return scheduleRequest(() => {
|
|
153
|
+
const defaultTimeout = config.getCurrent().DEFAULT_REQUEST_TIMEOUT;
|
|
152
154
|
return value.format === "string" ? request({ url: resourceUrl,
|
|
153
155
|
responseType: "text",
|
|
156
|
+
timeout: defaultTimeout,
|
|
154
157
|
cancelSignal }) :
|
|
155
158
|
|
|
156
159
|
request({ url: resourceUrl,
|
|
157
160
|
responseType: "arraybuffer",
|
|
161
|
+
timeout: defaultTimeout,
|
|
158
162
|
cancelSignal });
|
|
159
163
|
}).then((res) => {
|
|
160
164
|
if (value.format === "string") {
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
ISegmentContext,
|
|
30
30
|
ISegmentLoader,
|
|
31
31
|
ISegmentLoaderCallbacks,
|
|
32
|
+
ISegmentLoaderOptions,
|
|
32
33
|
ISegmentLoaderResultChunkedComplete,
|
|
33
34
|
ISegmentLoaderResultSegmentCreated,
|
|
34
35
|
ISegmentLoaderResultSegmentLoaded,
|
|
@@ -44,6 +45,7 @@ import lowLatencySegmentLoader from "./low_latency_segment_loader";
|
|
|
44
45
|
* @param {string} url
|
|
45
46
|
* @param {Object} content
|
|
46
47
|
* @param {boolean} lowLatencyMode
|
|
48
|
+
* @param {Object} options
|
|
47
49
|
* @param {Object} callbacks
|
|
48
50
|
* @param {Object} cancelSignal
|
|
49
51
|
* @returns {Promise}
|
|
@@ -52,6 +54,7 @@ export function regularSegmentLoader(
|
|
|
52
54
|
url : string,
|
|
53
55
|
content : ISegmentContext,
|
|
54
56
|
lowLatencyMode : boolean,
|
|
57
|
+
options : ISegmentLoaderOptions,
|
|
55
58
|
callbacks : ISegmentLoaderCallbacks<ILoadedAudioVideoSegmentFormat>,
|
|
56
59
|
cancelSignal : CancellationSignal
|
|
57
60
|
) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedAudioVideoSegmentFormat> |
|
|
@@ -59,14 +62,14 @@ export function regularSegmentLoader(
|
|
|
59
62
|
ISegmentLoaderResultChunkedComplete>
|
|
60
63
|
{
|
|
61
64
|
if (content.segment.isInit) {
|
|
62
|
-
return initSegmentLoader(url, content.segment, cancelSignal, callbacks);
|
|
65
|
+
return initSegmentLoader(url, content.segment, options, cancelSignal, callbacks);
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
const containerType = inferSegmentContainer(content.adaptation.type,
|
|
66
69
|
content.representation);
|
|
67
70
|
if (lowLatencyMode && (containerType === "mp4" || containerType === undefined)) {
|
|
68
71
|
if (fetchIsSupported()) {
|
|
69
|
-
return lowLatencySegmentLoader(url, content, callbacks, cancelSignal);
|
|
72
|
+
return lowLatencySegmentLoader(url, content, options, callbacks, cancelSignal);
|
|
70
73
|
} else {
|
|
71
74
|
warnOnce("DASH: Your browser does not have the fetch API. You will have " +
|
|
72
75
|
"a higher chance of rebuffering when playing close to the live edge");
|
|
@@ -79,6 +82,7 @@ export function regularSegmentLoader(
|
|
|
79
82
|
headers: segment.range !== undefined ?
|
|
80
83
|
{ Range: byteRange(segment.range) } :
|
|
81
84
|
undefined,
|
|
85
|
+
timeout: options.timeout,
|
|
82
86
|
cancelSignal,
|
|
83
87
|
onProgress: callbacks.onProgress })
|
|
84
88
|
.then((data) => ({ resultType: "segment-loaded",
|
|
@@ -106,6 +110,7 @@ export default function generateSegmentLoader(
|
|
|
106
110
|
function segmentLoader(
|
|
107
111
|
url : string | null,
|
|
108
112
|
content : ISegmentContext,
|
|
113
|
+
options : ISegmentLoaderOptions,
|
|
109
114
|
cancelSignal : CancellationSignal,
|
|
110
115
|
callbacks : ISegmentLoaderCallbacks<Uint8Array | ArrayBuffer | null>
|
|
111
116
|
) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedAudioVideoSegmentFormat> |
|
|
@@ -118,7 +123,12 @@ export default function generateSegmentLoader(
|
|
|
118
123
|
}
|
|
119
124
|
|
|
120
125
|
if (lowLatencyMode || customSegmentLoader === undefined) {
|
|
121
|
-
return regularSegmentLoader(url,
|
|
126
|
+
return regularSegmentLoader(url,
|
|
127
|
+
content,
|
|
128
|
+
lowLatencyMode,
|
|
129
|
+
options,
|
|
130
|
+
callbacks,
|
|
131
|
+
cancelSignal);
|
|
122
132
|
}
|
|
123
133
|
|
|
124
134
|
const args = { adaptation: content.adaptation,
|
|
@@ -127,6 +137,7 @@ export default function generateSegmentLoader(
|
|
|
127
137
|
representation: content.representation,
|
|
128
138
|
segment: content.segment,
|
|
129
139
|
transport: "dash",
|
|
140
|
+
timeout: options.timeout,
|
|
130
141
|
url };
|
|
131
142
|
|
|
132
143
|
return new Promise((res, rej) => {
|
|
@@ -135,7 +146,7 @@ export default function generateSegmentLoader(
|
|
|
135
146
|
|
|
136
147
|
/**
|
|
137
148
|
* Callback triggered when the custom segment loader has a response.
|
|
138
|
-
* @param {Object}
|
|
149
|
+
* @param {Object} _args
|
|
139
150
|
*/
|
|
140
151
|
const resolve = (
|
|
141
152
|
_args : { data : ArrayBuffer|Uint8Array;
|
|
@@ -202,7 +213,12 @@ export default function generateSegmentLoader(
|
|
|
202
213
|
}
|
|
203
214
|
hasFinished = true;
|
|
204
215
|
cancelSignal.deregister(abortCustomLoader);
|
|
205
|
-
regularSegmentLoader(url,
|
|
216
|
+
regularSegmentLoader(url,
|
|
217
|
+
content,
|
|
218
|
+
lowLatencyMode,
|
|
219
|
+
options,
|
|
220
|
+
callbacks,
|
|
221
|
+
cancelSignal)
|
|
206
222
|
.then(res, rej);
|
|
207
223
|
};
|
|
208
224
|
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
ISegmentContext,
|
|
25
25
|
ISegmentLoader,
|
|
26
26
|
ISegmentLoaderCallbacks,
|
|
27
|
+
ISegmentLoaderOptions,
|
|
27
28
|
ISegmentLoaderResultChunkedComplete,
|
|
28
29
|
ISegmentLoaderResultSegmentCreated,
|
|
29
30
|
ISegmentLoaderResultSegmentLoaded,
|
|
@@ -50,6 +51,7 @@ export default function generateTextTrackLoader(
|
|
|
50
51
|
/**
|
|
51
52
|
* @param {string|null} url
|
|
52
53
|
* @param {Object} content
|
|
54
|
+
* @param {Object} options
|
|
53
55
|
* @param {Object} cancelSignal
|
|
54
56
|
* @param {Object} callbacks
|
|
55
57
|
* @returns {Promise}
|
|
@@ -57,6 +59,7 @@ export default function generateTextTrackLoader(
|
|
|
57
59
|
function textTrackLoader(
|
|
58
60
|
url : string | null,
|
|
59
61
|
content : ISegmentContext,
|
|
62
|
+
options : ISegmentLoaderOptions,
|
|
60
63
|
cancelSignal : CancellationSignal,
|
|
61
64
|
callbacks : ISegmentLoaderCallbacks<ILoadedTextSegmentFormat>
|
|
62
65
|
) : Promise<ISegmentLoaderResultSegmentLoaded<ILoadedTextSegmentFormat> |
|
|
@@ -72,14 +75,14 @@ export default function generateTextTrackLoader(
|
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
if (segment.isInit) {
|
|
75
|
-
return initSegmentLoader(url, segment, cancelSignal, callbacks);
|
|
78
|
+
return initSegmentLoader(url, segment, options, cancelSignal, callbacks);
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
const containerType = inferSegmentContainer(adaptation.type, representation);
|
|
79
82
|
const seemsToBeMP4 = containerType === "mp4" || containerType === undefined;
|
|
80
83
|
if (lowLatencyMode && seemsToBeMP4) {
|
|
81
84
|
if (fetchIsSupported()) {
|
|
82
|
-
return lowLatencySegmentLoader(url, content, callbacks, cancelSignal);
|
|
85
|
+
return lowLatencySegmentLoader(url, content, options, callbacks, cancelSignal);
|
|
83
86
|
} else {
|
|
84
87
|
warnOnce("DASH: Your browser does not have the fetch API. You will have " +
|
|
85
88
|
"a higher chance of rebuffering when playing close to the live edge");
|
|
@@ -92,6 +95,7 @@ export default function generateTextTrackLoader(
|
|
|
92
95
|
headers: Array.isArray(range) ?
|
|
93
96
|
{ Range: byteRange(range) } :
|
|
94
97
|
null,
|
|
98
|
+
timeout: options.timeout,
|
|
95
99
|
onProgress: callbacks.onProgress,
|
|
96
100
|
cancelSignal })
|
|
97
101
|
.then((data) => ({ resultType: "segment-loaded",
|
|
@@ -103,6 +107,7 @@ export default function generateTextTrackLoader(
|
|
|
103
107
|
headers: Array.isArray(range) ?
|
|
104
108
|
{ Range: byteRange(range) } :
|
|
105
109
|
null,
|
|
110
|
+
timeout: options.timeout,
|
|
106
111
|
onProgress: callbacks.onProgress,
|
|
107
112
|
cancelSignal })
|
|
108
113
|
.then((data) => ({ resultType: "segment-loaded",
|
|
@@ -27,6 +27,7 @@ import { ILoadedManifestFormat } from "../../public_types";
|
|
|
27
27
|
import isNullOrUndefined from "../../utils/is_null_or_undefined";
|
|
28
28
|
import { CancellationSignal } from "../../utils/task_canceller";
|
|
29
29
|
import {
|
|
30
|
+
IManifestLoaderOptions,
|
|
30
31
|
IManifestParserResult,
|
|
31
32
|
IRequestedData,
|
|
32
33
|
ITransportOptions,
|
|
@@ -39,17 +40,18 @@ import textTrackParser from "./text_parser";
|
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Returns pipelines used for local Manifest streaming.
|
|
42
|
-
* @param {Object}
|
|
43
|
+
* @param {Object} transportOptions
|
|
43
44
|
* @returns {Object}
|
|
44
45
|
*/
|
|
45
46
|
export default function getLocalManifestPipelines(
|
|
46
|
-
|
|
47
|
+
transportOptions : ITransportOptions
|
|
47
48
|
) : ITransportPipelines {
|
|
48
49
|
|
|
49
|
-
const customManifestLoader =
|
|
50
|
+
const customManifestLoader = transportOptions.manifestLoader;
|
|
50
51
|
const manifestPipeline = {
|
|
51
52
|
loadManifest(
|
|
52
53
|
url : string | undefined,
|
|
54
|
+
loaderOptions : IManifestLoaderOptions,
|
|
53
55
|
cancelSignal : CancellationSignal
|
|
54
56
|
) : Promise<IRequestedData<ILoadedManifestFormat>> {
|
|
55
57
|
if (isNullOrUndefined(customManifestLoader)) {
|
|
@@ -62,7 +64,7 @@ export default function getLocalManifestPipelines(
|
|
|
62
64
|
() : never => {
|
|
63
65
|
throw new Error("Cannot fallback from the `manifestLoader` of a " +
|
|
64
66
|
"`local` transport");
|
|
65
|
-
})(url, cancelSignal);
|
|
67
|
+
})(url, loaderOptions, cancelSignal);
|
|
66
68
|
},
|
|
67
69
|
|
|
68
70
|
parseManifest(manifestData : IRequestedData<unknown>) : IManifestParserResult {
|
|
@@ -71,7 +73,7 @@ export default function getLocalManifestPipelines(
|
|
|
71
73
|
throw new Error("Wrong format for the manifest data");
|
|
72
74
|
}
|
|
73
75
|
const parsed = parseLocalManifest(loadedManifest as ILocalManifest);
|
|
74
|
-
const manifest = new Manifest(parsed,
|
|
76
|
+
const manifest = new Manifest(parsed, transportOptions);
|
|
75
77
|
return { manifest, url: undefined };
|
|
76
78
|
},
|
|
77
79
|
};
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
ISegmentContext,
|
|
29
29
|
ISegmentLoaderCallbacks,
|
|
30
|
+
ISegmentLoaderOptions,
|
|
30
31
|
ISegmentLoaderResultSegmentLoaded,
|
|
31
32
|
} from "../types";
|
|
32
33
|
|
|
@@ -45,7 +46,7 @@ function loadInitSegment(
|
|
|
45
46
|
|
|
46
47
|
/**
|
|
47
48
|
* Callback triggered when the custom segment loader has a response.
|
|
48
|
-
* @param {Object}
|
|
49
|
+
* @param {Object} _args
|
|
49
50
|
*/
|
|
50
51
|
const resolve = (_args : {
|
|
51
52
|
data : ArrayBuffer | null;
|
|
@@ -113,7 +114,7 @@ function loadSegment(
|
|
|
113
114
|
|
|
114
115
|
/**
|
|
115
116
|
* Callback triggered when the custom segment loader has a response.
|
|
116
|
-
* @param {Object}
|
|
117
|
+
* @param {Object} _args
|
|
117
118
|
*/
|
|
118
119
|
const resolve = (_args : {
|
|
119
120
|
data : ArrayBuffer | null;
|
|
@@ -188,6 +189,7 @@ function loadSegment(
|
|
|
188
189
|
export default function segmentLoader(
|
|
189
190
|
_url : string | null,
|
|
190
191
|
content : ISegmentContext,
|
|
192
|
+
_loaderOptions : ISegmentLoaderOptions, // TODO use timeout?
|
|
191
193
|
cancelSignal : CancellationSignal,
|
|
192
194
|
_callbacks : ISegmentLoaderCallbacks<ArrayBuffer | null>
|
|
193
195
|
) : Promise<ISegmentLoaderResultSegmentLoaded<ArrayBuffer | null>> {
|
|
@@ -20,21 +20,27 @@ import {
|
|
|
20
20
|
} from "../../public_types";
|
|
21
21
|
import request from "../../utils/request";
|
|
22
22
|
import { CancellationSignal } from "../../utils/task_canceller";
|
|
23
|
-
import { IRequestedData } from "../types";
|
|
23
|
+
import { IManifestLoaderOptions, IRequestedData } from "../types";
|
|
24
24
|
import callCustomManifestLoader from "../utils/call_custom_manifest_loader";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Manifest loader triggered if there was no custom-defined one in the API.
|
|
28
28
|
* @param {string} url
|
|
29
|
+
* @param {Object} loaderOptions
|
|
30
|
+
* @param {Object} cancelSignal
|
|
29
31
|
*/
|
|
30
32
|
function regularManifestLoader(
|
|
31
33
|
url : string | undefined,
|
|
34
|
+
loaderOptions : IManifestLoaderOptions,
|
|
32
35
|
cancelSignal : CancellationSignal
|
|
33
36
|
) : Promise< IRequestedData<ILoadedManifestFormat> > {
|
|
34
37
|
if (url === undefined) {
|
|
35
38
|
throw new Error("Cannot perform HTTP(s) request. URL not known");
|
|
36
39
|
}
|
|
37
|
-
return request({ url,
|
|
40
|
+
return request({ url,
|
|
41
|
+
responseType: "text",
|
|
42
|
+
timeout: loaderOptions.timeout,
|
|
43
|
+
cancelSignal });
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
/**
|
|
@@ -46,6 +52,7 @@ export default function generateManifestLoader(
|
|
|
46
52
|
{ customManifestLoader } : { customManifestLoader?: IManifestLoader | undefined }
|
|
47
53
|
) : (
|
|
48
54
|
url : string | undefined,
|
|
55
|
+
loaderOptions : IManifestLoaderOptions,
|
|
49
56
|
cancelSignal : CancellationSignal
|
|
50
57
|
) => Promise<IRequestedData<ILoadedManifestFormat>>
|
|
51
58
|
{
|