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
@@ -20,6 +20,8 @@ import log from "../../../log";
20
20
  import objectAssign from "../../../utils/object_assign";
21
21
  import { getLeftSizeOfRange } from "../../../utils/ranges";
22
22
  import createSharedReference from "../../../utils/reference";
23
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
24
+ import TaskCanceller from "../../../utils/task_canceller";
23
25
  import SegmentBuffersStore from "../../segment_buffers";
24
26
  import AdaptationStream from "../adaptation";
25
27
  import EVENTS from "../events_generators";
@@ -57,25 +59,28 @@ export default function PeriodStream(_a) {
57
59
  DELTA_POSITION_AFTER_RELOAD.trackSwitch.other;
58
60
  if (adaptation === null) { // Current type is disabled for that Period
59
61
  log.info("Stream: Set no ".concat(bufferType, " Adaptation. P:"), period.start);
60
- var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
62
+ var segmentBufferStatus_1 = segmentBuffersStore.getStatus(bufferType);
61
63
  var cleanBuffer$ = void 0;
62
- if (segmentBufferStatus.type === "initialized") {
64
+ if (segmentBufferStatus_1.type === "initialized") {
63
65
  log.info("Stream: Clearing previous ".concat(bufferType, " SegmentBuffer"));
64
66
  if (SegmentBuffersStore.isNative(bufferType)) {
65
67
  return reloadAfterSwitch(period, bufferType, playbackObserver, 0);
66
68
  }
67
- if (period.end === undefined) {
68
- cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, Infinity);
69
- }
70
- else if (period.end <= period.start) {
71
- cleanBuffer$ = observableOf(null);
72
- }
73
- else {
74
- cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, period.end);
75
- }
69
+ var canceller_1 = new TaskCanceller();
70
+ cleanBuffer$ = fromCancellablePromise(canceller_1, function () {
71
+ if (period.end === undefined) {
72
+ return segmentBufferStatus_1.value.removeBuffer(period.start, Infinity, canceller_1.signal);
73
+ }
74
+ else if (period.end <= period.start) {
75
+ return Promise.resolve();
76
+ }
77
+ else {
78
+ return segmentBufferStatus_1.value.removeBuffer(period.start, period.end, canceller_1.signal);
79
+ }
80
+ });
76
81
  }
77
82
  else {
78
- if (segmentBufferStatus.type === "uninitialized") {
83
+ if (segmentBufferStatus_1.type === "uninitialized") {
79
84
  segmentBuffersStore.disableSegmentBuffer(bufferType);
80
85
  }
81
86
  cleanBuffer$ = observableOf(null);
@@ -101,7 +106,10 @@ export default function PeriodStream(_a) {
101
106
  var cleanBuffer$ = strategy.type === "clean-buffer" || strategy.type === "flush-buffer" ?
102
107
  observableConcat.apply(void 0, strategy.value.map(function (_a) {
103
108
  var start = _a.start, end = _a.end;
104
- return segmentBuffer.removeBuffer(start, end);
109
+ var canceller = new TaskCanceller();
110
+ return fromCancellablePromise(canceller, function () {
111
+ return segmentBuffer.removeBuffer(start, end, canceller.signal);
112
+ });
105
113
  })
106
114
  // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
107
115
  // first type parameter as `any` instead of the perfectly fine `unknown`,
@@ -111,7 +119,10 @@ export default function PeriodStream(_a) {
111
119
  ).pipe(ignoreElements()) : EMPTY;
112
120
  var bufferGarbageCollector$ = garbageCollectors.get(segmentBuffer);
113
121
  var adaptationStream$ = createAdaptationStream(adaptation, segmentBuffer);
114
- return segmentBuffersStore.waitForUsableBuffers().pipe(mergeMap(function () {
122
+ var cancelWait = new TaskCanceller();
123
+ return fromCancellablePromise(cancelWait, function () {
124
+ return segmentBuffersStore.waitForUsableBuffers(cancelWait.signal);
125
+ }).pipe(mergeMap(function () {
115
126
  return observableConcat(cleanBuffer$, needsBufferFlush$, observableMerge(adaptationStream$, bufferGarbageCollector$));
116
127
  }));
117
128
  });
@@ -13,10 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- /**
17
- * This file allows any Stream to push data to a SegmentBuffer.
18
- */
19
- import { Observable } from "rxjs";
16
+ import { CancellationSignal } from "../../../utils/task_canceller";
20
17
  import { IReadOnlyPlaybackObserver } from "../../api";
21
18
  import { IPushChunkInfos, SegmentBuffer } from "../../segment_buffers";
22
19
  import { IRepresentationStreamPlaybackObservation } from "./representation_stream";
@@ -24,10 +21,10 @@ import { IRepresentationStreamPlaybackObservation } from "./representation_strea
24
21
  * Append a segment to the given segmentBuffer.
25
22
  * If it leads to a QuotaExceededError, try to run our custom range
26
23
  * _garbage collector_ then retry.
27
- *
28
24
  * @param {Observable} playbackObserver
29
25
  * @param {Object} segmentBuffer
30
26
  * @param {Object} dataInfos
31
- * @returns {Observable}
27
+ * @param {Object} cancellationSignal
28
+ * @returns {Promise}
32
29
  */
33
- export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T>): Observable<unknown>;
30
+ export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T>, cancellationSignal: CancellationSignal): Promise<void>;
@@ -13,40 +13,97 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __generator = (this && this.__generator) || function (thisArg, body) {
26
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
+ function verb(n) { return function (v) { return step([n, v]); }; }
29
+ function step(op) {
30
+ if (f) throw new TypeError("Generator is already executing.");
31
+ while (_) try {
32
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
+ if (y = 0, t) op = [op[0] & 2, t.value];
34
+ switch (op[0]) {
35
+ case 0: case 1: t = op; break;
36
+ case 4: _.label++; return { value: op[1], done: false };
37
+ case 5: _.label++; y = op[1]; op = [0]; continue;
38
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
+ default:
40
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
+ if (t[2]) _.ops.pop();
45
+ _.trys.pop(); continue;
46
+ }
47
+ op = body.call(thisArg, _);
48
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
+ }
51
+ };
16
52
  /**
17
53
  * This file allows any Stream to push data to a SegmentBuffer.
18
54
  */
19
- import { catchError, concat as observableConcat, mergeMap, ignoreElements, take, } from "rxjs";
20
55
  import { MediaError } from "../../../errors";
21
56
  import forceGarbageCollection from "./force_garbage_collection";
22
57
  /**
23
58
  * Append a segment to the given segmentBuffer.
24
59
  * If it leads to a QuotaExceededError, try to run our custom range
25
60
  * _garbage collector_ then retry.
26
- *
27
61
  * @param {Observable} playbackObserver
28
62
  * @param {Object} segmentBuffer
29
63
  * @param {Object} dataInfos
30
- * @returns {Observable}
64
+ * @param {Object} cancellationSignal
65
+ * @returns {Promise}
31
66
  */
32
- export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, dataInfos) {
33
- var append$ = segmentBuffer.pushChunk(dataInfos);
34
- return append$.pipe(catchError(function (appendError) {
35
- if (!(appendError instanceof Error) || appendError.name !== "QuotaExceededError") {
36
- var reason = appendError instanceof Error ?
37
- appendError.toString() :
38
- "An unknown error happened when pushing content";
39
- throw new MediaError("BUFFER_APPEND_ERROR", reason);
40
- }
41
- return playbackObserver.getReference().asObservable().pipe(take(1), mergeMap(function (observation) {
42
- var _a;
43
- var currentPos = (_a = observation.position.pending) !== null && _a !== void 0 ? _a : observation.position.last;
44
- return observableConcat(forceGarbageCollection(currentPos, segmentBuffer).pipe(ignoreElements()), append$).pipe(catchError(function (forcedGCError) {
45
- var reason = forcedGCError instanceof Error ?
46
- forcedGCError.toString() :
47
- "Could not clean the buffer";
48
- throw new MediaError("BUFFER_FULL_ERROR", reason);
49
- }));
50
- }));
51
- }));
67
+ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, dataInfos, cancellationSignal) {
68
+ var _a;
69
+ return __awaiter(this, void 0, void 0, function () {
70
+ var appendError_1, reason, position, currentPos, err2_1, reason;
71
+ return __generator(this, function (_b) {
72
+ switch (_b.label) {
73
+ case 0:
74
+ _b.trys.push([0, 2, , 8]);
75
+ return [4 /*yield*/, segmentBuffer.pushChunk(dataInfos, cancellationSignal)];
76
+ case 1:
77
+ _b.sent();
78
+ return [3 /*break*/, 8];
79
+ case 2:
80
+ appendError_1 = _b.sent();
81
+ if (!(appendError_1 instanceof Error) || appendError_1.name !== "QuotaExceededError") {
82
+ reason = appendError_1 instanceof Error ?
83
+ appendError_1.toString() :
84
+ "An unknown error happened when pushing content";
85
+ throw new MediaError("BUFFER_APPEND_ERROR", reason);
86
+ }
87
+ position = playbackObserver.getReference().getValue().position;
88
+ currentPos = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
89
+ _b.label = 3;
90
+ case 3:
91
+ _b.trys.push([3, 6, , 7]);
92
+ return [4 /*yield*/, forceGarbageCollection(currentPos, segmentBuffer, cancellationSignal)];
93
+ case 4:
94
+ _b.sent();
95
+ return [4 /*yield*/, segmentBuffer.pushChunk(dataInfos, cancellationSignal)];
96
+ case 5:
97
+ _b.sent();
98
+ return [3 /*break*/, 7];
99
+ case 6:
100
+ err2_1 = _b.sent();
101
+ reason = err2_1 instanceof Error ? err2_1.toString() :
102
+ "Could not clean the buffer";
103
+ throw new MediaError("BUFFER_FULL_ERROR", reason);
104
+ case 7: return [3 /*break*/, 8];
105
+ case 8: return [2 /*return*/];
106
+ }
107
+ });
108
+ });
52
109
  }
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Observable } from "rxjs";
16
+ import { CancellationSignal } from "../../../utils/task_canceller";
17
17
  import { SegmentBuffer } from "../../segment_buffers";
18
18
  /**
19
19
  * Run the garbage collector.
@@ -21,8 +21,9 @@ import { SegmentBuffer } from "../../segment_buffers";
21
21
  * Try to clean up buffered ranges from a low gcGap at first.
22
22
  * If it does not succeed to clean up space, use a higher gcCap.
23
23
  *
24
- * @param {Observable} timings$
24
+ * @param {number} currentPosition
25
25
  * @param {Object} bufferingQueue
26
- * @returns {Observable}
26
+ * @param {Object} cancellationSignal
27
+ * @returns {Promise}
27
28
  */
28
- export default function forceGarbageCollection(currentPosition: number, bufferingQueue: SegmentBuffer): Observable<unknown>;
29
+ export default function forceGarbageCollection(currentPosition: number, bufferingQueue: SegmentBuffer, cancellationSignal: CancellationSignal): Promise<void>;
@@ -13,7 +13,42 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { concatAll, defer as observableDefer, from as observableFrom, of as observableOf, } from "rxjs";
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __generator = (this && this.__generator) || function (thisArg, body) {
26
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
+ function verb(n) { return function (v) { return step([n, v]); }; }
29
+ function step(op) {
30
+ if (f) throw new TypeError("Generator is already executing.");
31
+ while (_) try {
32
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
+ if (y = 0, t) op = [op[0] & 2, t.value];
34
+ switch (op[0]) {
35
+ case 0: case 1: t = op; break;
36
+ case 4: _.label++; return { value: op[1], done: false };
37
+ case 5: _.label++; y = op[1]; op = [0]; continue;
38
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
+ default:
40
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
+ if (t[2]) _.ops.pop();
45
+ _.trys.pop(); continue;
46
+ }
47
+ op = body.call(thisArg, _);
48
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
+ }
51
+ };
17
52
  import config from "../../../config";
18
53
  import log from "../../../log";
19
54
  import { getInnerAndOuterTimeRanges } from "../../../utils/ranges";
@@ -23,33 +58,50 @@ import { getInnerAndOuterTimeRanges } from "../../../utils/ranges";
23
58
  * Try to clean up buffered ranges from a low gcGap at first.
24
59
  * If it does not succeed to clean up space, use a higher gcCap.
25
60
  *
26
- * @param {Observable} timings$
61
+ * @param {number} currentPosition
27
62
  * @param {Object} bufferingQueue
28
- * @returns {Observable}
63
+ * @param {Object} cancellationSignal
64
+ * @returns {Promise}
29
65
  */
30
- export default function forceGarbageCollection(currentPosition, bufferingQueue) {
31
- return observableDefer(function () {
32
- var GC_GAP_CALM = config.getCurrent().BUFFER_GC_GAPS.CALM;
33
- var GC_GAP_BEEFY = config.getCurrent().BUFFER_GC_GAPS.BEEFY;
34
- log.warn("Stream: Running garbage collector");
35
- var buffered = bufferingQueue.getBufferedRanges();
36
- var cleanedupRanges = selectGCedRanges(currentPosition, buffered, GC_GAP_CALM);
37
- // more aggressive GC if we could not find any range to clean
38
- if (cleanedupRanges.length === 0) {
39
- cleanedupRanges = selectGCedRanges(currentPosition, buffered, GC_GAP_BEEFY);
40
- }
41
- if (log.hasLevel("DEBUG")) {
42
- log.debug("Stream: GC cleaning", cleanedupRanges.map(function (_a) {
43
- var start = _a.start, end = _a.end;
44
- return "start: ".concat(start, " - end ").concat(end);
45
- })
46
- .join(", "));
47
- }
48
- return observableFrom(cleanedupRanges.map(function (_a) {
49
- var start = _a.start, end = _a.end;
50
- return start >= end ? observableOf(null) :
51
- bufferingQueue.removeBuffer(start, end);
52
- })).pipe(concatAll());
66
+ export default function forceGarbageCollection(currentPosition, bufferingQueue, cancellationSignal) {
67
+ return __awaiter(this, void 0, void 0, function () {
68
+ var GC_GAP_CALM, GC_GAP_BEEFY, buffered, cleanedupRanges, _i, cleanedupRanges_1, range, start, end;
69
+ return __generator(this, function (_a) {
70
+ switch (_a.label) {
71
+ case 0:
72
+ GC_GAP_CALM = config.getCurrent().BUFFER_GC_GAPS.CALM;
73
+ GC_GAP_BEEFY = config.getCurrent().BUFFER_GC_GAPS.BEEFY;
74
+ log.warn("Stream: Running garbage collector");
75
+ buffered = bufferingQueue.getBufferedRanges();
76
+ cleanedupRanges = selectGCedRanges(currentPosition, buffered, GC_GAP_CALM);
77
+ // more aggressive GC if we could not find any range to clean
78
+ if (cleanedupRanges.length === 0) {
79
+ cleanedupRanges = selectGCedRanges(currentPosition, buffered, GC_GAP_BEEFY);
80
+ }
81
+ if (log.hasLevel("DEBUG")) {
82
+ log.debug("Stream: GC cleaning", cleanedupRanges.map(function (_a) {
83
+ var start = _a.start, end = _a.end;
84
+ return "start: ".concat(start, " - end ").concat(end);
85
+ })
86
+ .join(", "));
87
+ }
88
+ _i = 0, cleanedupRanges_1 = cleanedupRanges;
89
+ _a.label = 1;
90
+ case 1:
91
+ if (!(_i < cleanedupRanges_1.length)) return [3 /*break*/, 4];
92
+ range = cleanedupRanges_1[_i];
93
+ start = range.start, end = range.end;
94
+ if (!(start < end)) return [3 /*break*/, 3];
95
+ return [4 /*yield*/, bufferingQueue.removeBuffer(start, end, cancellationSignal)];
96
+ case 2:
97
+ _a.sent();
98
+ _a.label = 3;
99
+ case 3:
100
+ _i++;
101
+ return [3 /*break*/, 1];
102
+ case 4: return [2 /*return*/];
103
+ }
104
+ });
53
105
  });
54
106
  }
55
107
  /**
@@ -38,7 +38,11 @@ import getSegmentPriority from "./get_segment_priority";
38
38
  export default function getBufferStatus(content, initialWantedTime, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer) {
39
39
  segmentBuffer.synchronizeInventory();
40
40
  var representation = content.representation;
41
- var neededRange = getRangeOfNeededSegments(content, initialWantedTime, bufferGoal);
41
+ var askedStart = playbackObserver.getIsPaused() ||
42
+ playbackObserver.getPlaybackRate() <= 0 ?
43
+ initialWantedTime - 0.1 :
44
+ initialWantedTime;
45
+ var neededRange = getRangeOfNeededSegments(content, askedStart, bufferGoal);
42
46
  var shouldRefreshManifest = representation.index.shouldRefresh(neededRange.start, neededRange.end);
43
47
  /**
44
48
  * Every segment awaiting an "EndOfSegment" operation, which indicates that a
@@ -57,7 +61,7 @@ export default function getBufferStatus(content, initialWantedTime, playbackObse
57
61
  /** List of segments we will need to download. */
58
62
  var _a = getNeededSegments({ content: content, bufferedSegments: bufferedSegments, currentPlaybackTime: currentPlaybackTime, fastSwitchThreshold: fastSwitchThreshold, getBufferedHistory: getBufferedHistory, neededRange: neededRange, segmentsBeingPushed: segmentsBeingPushed, maxBufferSize: maxBufferSize }), segmentsToLoad = _a.segmentsToLoad, segmentsOnHold = _a.segmentsOnHold, isBufferFull = _a.isBufferFull;
59
63
  var prioritizedNeededSegments = segmentsToLoad.map(function (segment) { return ({
60
- priority: getSegmentPriority(segment.time, initialWantedTime),
64
+ priority: getSegmentPriority(segment.time, askedStart),
61
65
  segment: segment,
62
66
  }); });
63
67
  /**
@@ -119,7 +123,7 @@ function getRangeOfNeededSegments(content, initialWantedTime, bufferGoal) {
119
123
  wantedStartPosition = lastIndexPosition - 1;
120
124
  }
121
125
  else {
122
- wantedStartPosition = initialWantedTime;
126
+ wantedStartPosition = initialWantedTime - 0.1;
123
127
  }
124
128
  var wantedEndPosition = wantedStartPosition + bufferGoal;
125
129
  var hasReachedPeriodEnd;
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { defer as observableDefer, EMPTY, map, } from "rxjs";
17
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
18
+ import TaskCanceller from "../../../utils/task_canceller";
17
19
  import EVENTS from "../events_generators";
18
20
  import appendSegmentToBuffer from "./append_segment_to_buffer";
19
21
  /**
@@ -35,7 +37,11 @@ export default function pushInitSegment(_a) {
35
37
  chunk: null,
36
38
  timestampOffset: 0,
37
39
  appendWindow: [undefined, undefined], codec: codec };
38
- return appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: null }).pipe(map(function () {
40
+ var canceller = new TaskCanceller();
41
+ return fromCancellablePromise(canceller, function () {
42
+ return appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: null }, canceller.signal);
43
+ })
44
+ .pipe(map(function () {
39
45
  var buffered = segmentBuffer.getBufferedRanges();
40
46
  return EVENTS.addedSegment(content, segment, buffered, segmentData);
41
47
  }));
@@ -16,6 +16,8 @@
16
16
  import { defer as observableDefer, EMPTY, map, } from "rxjs";
17
17
  import config from "../../../config";
18
18
  import objectAssign from "../../../utils/object_assign";
19
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
20
+ import TaskCanceller from "../../../utils/task_canceller";
19
21
  import EVENTS from "../events_generators";
20
22
  import appendSegmentToBuffer from "./append_segment_to_buffer";
21
23
  /**
@@ -62,7 +64,11 @@ export default function pushMediaSegment(_a) {
62
64
  }
63
65
  var inventoryInfos = objectAssign({ segment: segment, chunkSize: chunkSize, start: estimatedStart,
64
66
  end: estimatedEnd }, content);
65
- return appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: inventoryInfos }).pipe(map(function () {
67
+ var canceller = new TaskCanceller();
68
+ return fromCancellablePromise(canceller, function () {
69
+ return appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: inventoryInfos }, canceller.signal);
70
+ })
71
+ .pipe(map(function () {
66
72
  var buffered = segmentBuffer.getBufferedRanges();
67
73
  return EVENTS.addedSegment(content, segment, buffered, chunkData);
68
74
  }));
@@ -28,6 +28,8 @@ import log from "../../../log";
28
28
  import assertUnreachable from "../../../utils/assert_unreachable";
29
29
  import objectAssign from "../../../utils/object_assign";
30
30
  import { createSharedReference } from "../../../utils/reference";
31
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
32
+ import TaskCanceller from "../../../utils/task_canceller";
31
33
  import EVENTS from "../events_generators";
32
34
  import DownloadingQueue from "./downloading_queue";
33
35
  import getBufferStatus from "./get_buffer_status";
@@ -171,12 +173,14 @@ export default function RepresentationStream(_a) {
171
173
  var bufferRemoval = EMPTY;
172
174
  var UPTO_CURRENT_POSITION_CLEANUP = config.getCurrent().UPTO_CURRENT_POSITION_CLEANUP;
173
175
  if (status.isBufferFull) {
174
- var gcedPosition = Math.max(0, initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
175
- if (gcedPosition > 0) {
176
- bufferRemoval = segmentBuffer
177
- .removeBuffer(0, gcedPosition)
178
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
179
- .pipe(ignoreElements());
176
+ var gcedPosition_1 = Math.max(0, initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
177
+ if (gcedPosition_1 > 0) {
178
+ var removalCanceller_1 = new TaskCanceller();
179
+ bufferRemoval = fromCancellablePromise(removalCanceller_1, function () {
180
+ return segmentBuffer.removeBuffer(0, gcedPosition_1, removalCanceller_1.signal);
181
+ }
182
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
183
+ ).pipe(ignoreElements());
180
184
  }
181
185
  }
182
186
  return status.shouldRefreshManifest ?
@@ -207,8 +211,11 @@ export default function RepresentationStream(_a) {
207
211
  case "parsed-media":
208
212
  return onParsedChunk(evt);
209
213
  case "end-of-segment": {
210
- var segment = evt.value.segment;
211
- return segmentBuffer.endOfSegment(objectAssign({ segment: segment }, content))
214
+ var segment_1 = evt.value.segment;
215
+ var endOfSegmentCanceller_1 = new TaskCanceller();
216
+ return fromCancellablePromise(endOfSegmentCanceller_1, function () {
217
+ return segmentBuffer.endOfSegment(objectAssign({ segment: segment_1 }, content), endOfSegmentCanceller_1.signal);
218
+ })
212
219
  // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
213
220
  // first type parameter as `any` instead of the perfectly fine `unknown`,
214
221
  // leading to linter issues, as it forbids the usage of `any`.
@@ -312,7 +312,7 @@ var DEFAULT_CONFIG = {
312
312
  * small enough so this (arguably rare) situation won't lead to too much
313
313
  * waiting time.
314
314
  */
315
- FORCE_DISCONTINUITY_SEEK_DELAY: 2000,
315
+ FORCE_DISCONTINUITY_SEEK_DELAY: 3000,
316
316
  /**
317
317
  * Ratio used to know if an already loaded segment should be re-buffered.
318
318
  * We re-load the given segment if the current one times that ratio is
@@ -29,9 +29,10 @@ export default class CustomLoaderError extends Error {
29
29
  readonly isOfflineError: boolean;
30
30
  readonly xhr: XMLHttpRequest | undefined;
31
31
  /**
32
+ * @param {string} message
33
+ * @param {boolean} canRetry
34
+ * @param {boolean} isOfflineError
32
35
  * @param {XMLHttpRequest} xhr
33
- * @param {string} url
34
- * @param {string} type
35
36
  */
36
37
  constructor(message: string, canRetry: boolean, isOfflineError: boolean, xhr: XMLHttpRequest | undefined);
37
38
  }
@@ -40,9 +40,10 @@ var __extends = (this && this.__extends) || (function () {
40
40
  var CustomLoaderError = /** @class */ (function (_super) {
41
41
  __extends(CustomLoaderError, _super);
42
42
  /**
43
+ * @param {string} message
44
+ * @param {boolean} canRetry
45
+ * @param {boolean} isOfflineError
43
46
  * @param {XMLHttpRequest} xhr
44
- * @param {string} url
45
- * @param {string} type
46
47
  */
47
48
  function CustomLoaderError(message, canRetry, isOfflineError, xhr) {
48
49
  var _this = _super.call(this) || this;
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { EMPTY, map, merge as observableMerge, mergeMap, of as observableOf, ReplaySubject, Subject, tap, } from "rxjs";
17
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
18
+ import TaskCanceller from "../../../utils/task_canceller";
17
19
  import prepareSourceBuffer from "./prepare_source_buffer";
18
20
  var mediaSourceSubscription;
19
21
  var sourceBufferContent;
@@ -63,14 +65,15 @@ function loadAndPushInitData(contentInfos, initSegment, sourceBuffer, segmentFet
63
65
  var initSegmentData = initializationData instanceof ArrayBuffer ?
64
66
  new Uint8Array(initializationData) :
65
67
  initializationData;
66
- return sourceBuffer
68
+ var pushCanceller = new TaskCanceller();
69
+ return fromCancellablePromise(pushCanceller, function () { return sourceBuffer
67
70
  .pushChunk({ data: { initSegment: initSegmentData,
68
71
  chunk: null,
69
72
  appendWindow: [undefined, undefined],
70
73
  timestampOffset: 0,
71
74
  codec: contentInfos
72
75
  .representation.getMimeTypeString() },
73
- inventoryInfos: null });
76
+ inventoryInfos: null }, pushCanceller.signal); });
74
77
  }));
75
78
  }
76
79
  /**
@@ -1,3 +1,5 @@
1
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
2
+ import TaskCanceller from "../../../utils/task_canceller";
1
3
  /**
2
4
  * Push data to the video source buffer.
3
5
  * @param {Object} inventoryInfos
@@ -10,9 +12,10 @@ export default function pushData(inventoryInfos, parsed, videoSourceBuffer) {
10
12
  var chunkData = parsed.chunkData, appendWindow = parsed.appendWindow;
11
13
  var segmentData = chunkData instanceof ArrayBuffer ?
12
14
  new Uint8Array(chunkData) : chunkData;
13
- return videoSourceBuffer
15
+ var pushCanceller = new TaskCanceller();
16
+ return fromCancellablePromise(pushCanceller, function () { return videoSourceBuffer
14
17
  .pushChunk({ data: { chunk: segmentData,
15
18
  timestampOffset: 0, appendWindow: appendWindow, initSegment: null,
16
19
  codec: inventoryInfos
17
- .representation.getMimeTypeString() }, inventoryInfos: inventoryInfos });
20
+ .representation.getMimeTypeString() }, inventoryInfos: inventoryInfos }, pushCanceller.signal); });
18
21
  }
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { combineLatest as observableCombineLatest, of as observableOf, } from "rxjs";
17
+ import fromCancellablePromise from "../../../utils/rx-from_cancellable_promise";
18
+ import TaskCanceller from "../../../utils/task_canceller";
17
19
  /**
18
20
  * Remove buffer around wanted time, considering a margin around
19
21
  * it that defines what must be kept :
@@ -31,11 +33,16 @@ export default function removeBufferAroundTime$(videoElement, sourceBuffer, time
31
33
  return observableOf(null);
32
34
  }
33
35
  var bufferRemovals$ = [];
36
+ var removalCanceller = new TaskCanceller();
34
37
  if ((time - margin) > 0) {
35
- bufferRemovals$.push(sourceBuffer.removeBuffer(0, time - margin));
38
+ bufferRemovals$.push(fromCancellablePromise(removalCanceller, function () {
39
+ return sourceBuffer.removeBuffer(0, time - margin, removalCanceller.signal);
40
+ }));
36
41
  }
37
42
  if ((time + margin) < videoElement.duration) {
38
- bufferRemovals$.push(sourceBuffer.removeBuffer(time + margin, videoElement.duration));
43
+ bufferRemovals$.push(fromCancellablePromise(removalCanceller, function () {
44
+ return sourceBuffer.removeBuffer(time + margin, videoElement.duration, removalCanceller.signal);
45
+ }));
39
46
  }
40
47
  return observableCombineLatest(bufferRemovals$);
41
48
  }
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { catchError, combineLatest, finalize, ignoreElements, lastValueFrom, map, merge as observableMerge, mergeMap, race as observableRace, Subject, take, tap, } from "rxjs";
17
+ import config from "../../../config";
17
18
  import createSegmentFetcher from "../../../core/fetchers/segment/segment_fetcher";
18
19
  import log from "../../../log";
19
20
  import objectAssign from "../../../utils/object_assign";
@@ -146,7 +147,8 @@ var VideoThumbnailLoader = /** @class */ (function () {
146
147
  {}, { baseDelay: 0,
147
148
  maxDelay: 0,
148
149
  maxRetryOffline: 0,
149
- maxRetryRegular: 0 });
150
+ maxRetryRegular: 0,
151
+ requestTimeout: config.getCurrent().DEFAULT_REQUEST_TIMEOUT });
150
152
  var taskPromise = lastValueFrom(observableRace(abortError$, getInitializedSourceBuffer$(contentInfos, this._videoElement, segmentFetcher).pipe(mergeMap(function (videoSourceBuffer) {
151
153
  var bufferCleaning$ = removeBufferAroundTime$(_this._videoElement, videoSourceBuffer, time);
152
154
  log.debug("VTL: Removing buffer around time.", time);