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
|
@@ -31,12 +31,13 @@ var EPSILON = 1 / 60;
|
|
|
31
31
|
* encountered and exited.
|
|
32
32
|
* @param {object} playbackObserver - emit the current playback conditions.
|
|
33
33
|
* @param {Object} manifest - The Manifest of the currently-played content.
|
|
34
|
+
* @param {Object} speed - The last speed set by the user
|
|
35
|
+
* @param {Observable} lockedStream$
|
|
34
36
|
* @param {Observable} discontinuityUpdate$ - Observable emitting encountered
|
|
35
37
|
* discontinuities for loaded Period and buffer types.
|
|
36
|
-
* @param {Function} setCurrentTime
|
|
37
38
|
* @returns {Observable}
|
|
38
39
|
*/
|
|
39
|
-
export default function StallAvoider(playbackObserver, manifest, lockedStream$, discontinuityUpdate$) {
|
|
40
|
+
export default function StallAvoider(playbackObserver, manifest, speed, lockedStream$, discontinuityUpdate$) {
|
|
40
41
|
var initialDiscontinuitiesStore = [];
|
|
41
42
|
/**
|
|
42
43
|
* Emit every known audio and video buffer discontinuities in chronological
|
|
@@ -79,10 +80,9 @@ export default function StallAvoider(playbackObserver, manifest, lockedStream$,
|
|
|
79
80
|
var unlock$ = lockedStream$.pipe(withLatestFrom(playbackObserver.getReference().asObservable()), tap(function (_a) {
|
|
80
81
|
var _b;
|
|
81
82
|
var lockedStreamEvt = _a[0], observation = _a[1];
|
|
82
|
-
// TODO(PaulB) also skip when the user's wanted speed is set to `0`, as we
|
|
83
|
-
// might not want to seek in that case?
|
|
84
83
|
if (!observation.rebuffering ||
|
|
85
|
-
observation.paused ||
|
|
84
|
+
observation.paused ||
|
|
85
|
+
speed.getValue() <= 0 || (lockedStreamEvt.bufferType !== "audio" &&
|
|
86
86
|
lockedStreamEvt.bufferType !== "video")) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
@@ -103,9 +103,22 @@ export default function StallAvoider(playbackObserver, manifest, lockedStream$,
|
|
|
103
103
|
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
|
|
104
104
|
ignoreElements());
|
|
105
105
|
var stall$ = playbackObserver.getReference().asObservable().pipe(withLatestFrom(discontinuitiesStore$), map(function (_a) {
|
|
106
|
+
var _b;
|
|
106
107
|
var observation = _a[0], discontinuitiesStore = _a[1];
|
|
107
108
|
var buffered = observation.buffered, position = observation.position, readyState = observation.readyState, rebuffering = observation.rebuffering, freezing = observation.freezing;
|
|
108
|
-
var
|
|
109
|
+
var _c = config.getCurrent(), BUFFER_DISCONTINUITY_THRESHOLD = _c.BUFFER_DISCONTINUITY_THRESHOLD, FORCE_DISCONTINUITY_SEEK_DELAY = _c.FORCE_DISCONTINUITY_SEEK_DELAY, FREEZING_STALLED_DELAY = _c.FREEZING_STALLED_DELAY, UNFREEZING_SEEK_DELAY = _c.UNFREEZING_SEEK_DELAY, UNFREEZING_DELTA_POSITION = _c.UNFREEZING_DELTA_POSITION;
|
|
110
|
+
if (!observation.seeking &&
|
|
111
|
+
isSeekingApproximate &&
|
|
112
|
+
ignoredStallTimeStamp === null &&
|
|
113
|
+
lastSeekingPosition !== null &&
|
|
114
|
+
observation.position < lastSeekingPosition) {
|
|
115
|
+
log.debug("Init: the device appeared to have seeked back by itself.");
|
|
116
|
+
var now = performance.now();
|
|
117
|
+
ignoredStallTimeStamp = now;
|
|
118
|
+
}
|
|
119
|
+
lastSeekingPosition = observation.seeking ?
|
|
120
|
+
Math.max((_b = observation.pendingInternalSeek) !== null && _b !== void 0 ? _b : 0, observation.position) :
|
|
121
|
+
null;
|
|
109
122
|
if (freezing !== null) {
|
|
110
123
|
var now = performance.now();
|
|
111
124
|
var referenceTimestamp = prevFreezingState === null ?
|
|
@@ -130,7 +143,7 @@ export default function StallAvoider(playbackObserver, manifest, lockedStream$,
|
|
|
130
143
|
// Return that we're stalled
|
|
131
144
|
var reason = void 0;
|
|
132
145
|
if (observation.seeking) {
|
|
133
|
-
reason = observation.
|
|
146
|
+
reason = observation.pendingInternalSeek !== null ? "internal-seek" :
|
|
134
147
|
"seeking";
|
|
135
148
|
}
|
|
136
149
|
else {
|
|
@@ -145,27 +158,19 @@ export default function StallAvoider(playbackObserver, manifest, lockedStream$,
|
|
|
145
158
|
// We want to separate a stall situation when a seek is due to a seek done
|
|
146
159
|
// internally by the player to when its due to a regular user seek.
|
|
147
160
|
var stalledReason = rebuffering.reason === "seeking" &&
|
|
148
|
-
observation.
|
|
161
|
+
observation.pendingInternalSeek !== null ?
|
|
162
|
+
"internal-seek" :
|
|
149
163
|
rebuffering.reason;
|
|
150
|
-
if (
|
|
151
|
-
lastSeekingPosition = observation.position;
|
|
152
|
-
}
|
|
153
|
-
else if (lastSeekingPosition !== null) {
|
|
164
|
+
if (ignoredStallTimeStamp !== null) {
|
|
154
165
|
var now = performance.now();
|
|
155
|
-
if (ignoredStallTimeStamp
|
|
156
|
-
|
|
166
|
+
if (now - ignoredStallTimeStamp < FORCE_DISCONTINUITY_SEEK_DELAY) {
|
|
167
|
+
log.debug("Init: letting the device get out of a stall by itself");
|
|
168
|
+
return { type: "stalled",
|
|
169
|
+
value: stalledReason };
|
|
157
170
|
}
|
|
158
|
-
|
|
159
|
-
log.
|
|
160
|
-
if (now - ignoredStallTimeStamp < FORCE_DISCONTINUITY_SEEK_DELAY) {
|
|
161
|
-
return { type: "stalled",
|
|
162
|
-
value: stalledReason };
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
log.warn("Init: ignored stall for too long, checking discontinuity", now - ignoredStallTimeStamp);
|
|
166
|
-
}
|
|
171
|
+
else {
|
|
172
|
+
log.warn("Init: ignored stall for too long, checking discontinuity", now - ignoredStallTimeStamp);
|
|
167
173
|
}
|
|
168
|
-
lastSeekingPosition = null;
|
|
169
174
|
}
|
|
170
175
|
ignoredStallTimeStamp = null;
|
|
171
176
|
if (manifest === null) {
|
|
@@ -174,7 +179,7 @@ export default function StallAvoider(playbackObserver, manifest, lockedStream$,
|
|
|
174
179
|
}
|
|
175
180
|
/** Position at which data is awaited. */
|
|
176
181
|
var stalledPosition = rebuffering.position;
|
|
177
|
-
if (stalledPosition !== null) {
|
|
182
|
+
if (stalledPosition !== null && speed.getValue() > 0) {
|
|
178
183
|
var skippableDiscontinuity = findSeekableDiscontinuity(discontinuitiesStore, manifest, stalledPosition);
|
|
179
184
|
if (skippableDiscontinuity !== null) {
|
|
180
185
|
var realSeekTime = skippableDiscontinuity + 0.001;
|
|
@@ -197,7 +202,8 @@ export default function StallAvoider(playbackObserver, manifest, lockedStream$,
|
|
|
197
202
|
// implementation that might drop an injected segment, or in
|
|
198
203
|
// case of small discontinuity in the content.
|
|
199
204
|
var nextBufferRangeGap = getNextRangeGap(buffered, freezePosition);
|
|
200
|
-
if (
|
|
205
|
+
if (speed.getValue() > 0 &&
|
|
206
|
+
nextBufferRangeGap < BUFFER_DISCONTINUITY_THRESHOLD) {
|
|
201
207
|
var seekTo = (freezePosition + nextBufferRangeGap + EPSILON);
|
|
202
208
|
if (playbackObserver.getCurrentTime() < seekTo) {
|
|
203
209
|
log.warn("Init: discontinuity encountered inferior to the threshold", freezePosition, seekTo, BUFFER_DISCONTINUITY_THRESHOLD);
|
|
@@ -13,24 +13,30 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import { IReadOnlySharedReference } from "../../utils/reference";
|
|
17
|
+
import { CancellationSignal } from "../../utils/task_canceller";
|
|
18
|
+
import { IReadOnlyPlaybackObserver } from "../api";
|
|
19
|
+
import { IStreamOrchestratorPlaybackObservation } from "../stream";
|
|
17
20
|
import { SegmentBuffer } from "./implementations";
|
|
18
21
|
export interface IGarbageCollectorArgument {
|
|
19
22
|
/** SegmentBuffer implementation */
|
|
20
23
|
segmentBuffer: SegmentBuffer;
|
|
21
24
|
/** Emit current position in seconds regularly */
|
|
22
|
-
|
|
25
|
+
playbackObserver: IReadOnlyPlaybackObserver<Pick<IStreamOrchestratorPlaybackObservation, "position">>;
|
|
23
26
|
/** Maximum time to keep behind current time position, in seconds */
|
|
24
|
-
maxBufferBehind
|
|
27
|
+
maxBufferBehind: IReadOnlySharedReference<number>;
|
|
25
28
|
/** Minimum time to keep behind current time position, in seconds */
|
|
26
|
-
maxBufferAhead
|
|
29
|
+
maxBufferAhead: IReadOnlySharedReference<number>;
|
|
27
30
|
}
|
|
28
31
|
/**
|
|
29
32
|
* Perform cleaning of the buffer according to the values set by the user
|
|
30
|
-
* each time `
|
|
33
|
+
* each time `playbackObserver` emits and each times the
|
|
31
34
|
* maxBufferBehind/maxBufferAhead values change.
|
|
32
35
|
*
|
|
36
|
+
* Abort this operation when the `cancellationSignal` emits.
|
|
37
|
+
*
|
|
33
38
|
* @param {Object} opt
|
|
39
|
+
* @param {Object} cancellationSignal
|
|
34
40
|
* @returns {Observable}
|
|
35
41
|
*/
|
|
36
|
-
export default function BufferGarbageCollector({ segmentBuffer,
|
|
42
|
+
export default function BufferGarbageCollector({ segmentBuffer, playbackObserver, maxBufferBehind, maxBufferAhead }: IGarbageCollectorArgument, cancellationSignal: CancellationSignal): void;
|
|
@@ -13,23 +13,75 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
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 log from "../../log";
|
|
18
53
|
import { getInnerAndOuterTimeRanges } from "../../utils/ranges";
|
|
19
54
|
/**
|
|
20
55
|
* Perform cleaning of the buffer according to the values set by the user
|
|
21
|
-
* each time `
|
|
56
|
+
* each time `playbackObserver` emits and each times the
|
|
22
57
|
* maxBufferBehind/maxBufferAhead values change.
|
|
23
58
|
*
|
|
59
|
+
* Abort this operation when the `cancellationSignal` emits.
|
|
60
|
+
*
|
|
24
61
|
* @param {Object} opt
|
|
62
|
+
* @param {Object} cancellationSignal
|
|
25
63
|
* @returns {Observable}
|
|
26
64
|
*/
|
|
27
|
-
export default function BufferGarbageCollector(_a) {
|
|
28
|
-
var segmentBuffer = _a.segmentBuffer,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
65
|
+
export default function BufferGarbageCollector(_a, cancellationSignal) {
|
|
66
|
+
var segmentBuffer = _a.segmentBuffer, playbackObserver = _a.playbackObserver, maxBufferBehind = _a.maxBufferBehind, maxBufferAhead = _a.maxBufferAhead;
|
|
67
|
+
var lastPosition;
|
|
68
|
+
playbackObserver.listen(function (o) {
|
|
69
|
+
var _a;
|
|
70
|
+
lastPosition = (_a = o.position.pending) !== null && _a !== void 0 ? _a : o.position.last;
|
|
71
|
+
clean();
|
|
72
|
+
}, { includeLastObservation: true, clearSignal: cancellationSignal });
|
|
73
|
+
function clean() {
|
|
74
|
+
clearBuffer(segmentBuffer, lastPosition, maxBufferBehind.getValue(), maxBufferAhead.getValue(), cancellationSignal)
|
|
75
|
+
.catch(function (e) {
|
|
76
|
+
var errMsg = e instanceof Error ?
|
|
77
|
+
e.message :
|
|
78
|
+
"Unknown error";
|
|
79
|
+
log.error("Could not run BufferGarbageCollector:", errMsg);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
maxBufferBehind.onUpdate(clean, { clearSignal: cancellationSignal });
|
|
83
|
+
maxBufferAhead.onUpdate(clean, { clearSignal: cancellationSignal });
|
|
84
|
+
clean();
|
|
33
85
|
}
|
|
34
86
|
/**
|
|
35
87
|
* Remove buffer from the browser's memory based on the user's
|
|
@@ -45,76 +97,88 @@ export default function BufferGarbageCollector(_a) {
|
|
|
45
97
|
* @param {Number} position - The current position
|
|
46
98
|
* @param {Number} maxBufferBehind
|
|
47
99
|
* @param {Number} maxBufferAhead
|
|
48
|
-
* @returns {
|
|
100
|
+
* @returns {Promise}
|
|
49
101
|
*/
|
|
50
|
-
function clearBuffer(segmentBuffer, position, maxBufferBehind, maxBufferAhead) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
function clearBuffer(segmentBuffer, position, maxBufferBehind, maxBufferAhead, cancellationSignal) {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
104
|
+
var cleanedupRanges, _a, innerRange, outerRanges, collectBufferBehind, collectBufferAhead, _i, cleanedupRanges_1, range;
|
|
105
|
+
return __generator(this, function (_b) {
|
|
106
|
+
switch (_b.label) {
|
|
107
|
+
case 0:
|
|
108
|
+
if (!isFinite(maxBufferBehind) && !isFinite(maxBufferAhead)) {
|
|
109
|
+
return [2 /*return*/, Promise.resolve()];
|
|
110
|
+
}
|
|
111
|
+
cleanedupRanges = [];
|
|
112
|
+
_a = getInnerAndOuterTimeRanges(segmentBuffer.getBufferedRanges(), position), innerRange = _a.innerRange, outerRanges = _a.outerRanges;
|
|
113
|
+
collectBufferBehind = function () {
|
|
114
|
+
if (!isFinite(maxBufferBehind)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// begin from the oldest
|
|
118
|
+
for (var i = 0; i < outerRanges.length; i++) {
|
|
119
|
+
var outerRange = outerRanges[i];
|
|
120
|
+
if (position - maxBufferBehind >= outerRange.end) {
|
|
121
|
+
cleanedupRanges.push(outerRange);
|
|
122
|
+
}
|
|
123
|
+
else if (position >= outerRange.end &&
|
|
124
|
+
position - maxBufferBehind > outerRange.start &&
|
|
125
|
+
position - maxBufferBehind < outerRange.end) {
|
|
126
|
+
cleanedupRanges.push({ start: outerRange.start,
|
|
127
|
+
end: position - maxBufferBehind });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (innerRange != null) {
|
|
131
|
+
if (position - maxBufferBehind > innerRange.start) {
|
|
132
|
+
cleanedupRanges.push({ start: innerRange.start,
|
|
133
|
+
end: position - maxBufferBehind });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
collectBufferAhead = function () {
|
|
138
|
+
if (!isFinite(maxBufferAhead)) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// begin from the oldest
|
|
142
|
+
for (var i = 0; i < outerRanges.length; i++) {
|
|
143
|
+
var outerRange = outerRanges[i];
|
|
144
|
+
if (position + maxBufferAhead <= outerRange.start) {
|
|
145
|
+
cleanedupRanges.push(outerRange);
|
|
146
|
+
}
|
|
147
|
+
else if (position <= outerRange.start &&
|
|
148
|
+
position + maxBufferAhead < outerRange.end &&
|
|
149
|
+
position + maxBufferAhead > outerRange.start) {
|
|
150
|
+
cleanedupRanges.push({ start: position + maxBufferAhead,
|
|
151
|
+
end: outerRange.end });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (innerRange != null) {
|
|
155
|
+
if (position + maxBufferAhead < innerRange.end) {
|
|
156
|
+
cleanedupRanges.push({ start: position + maxBufferAhead,
|
|
157
|
+
end: innerRange.end });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
collectBufferBehind();
|
|
162
|
+
collectBufferAhead();
|
|
163
|
+
_i = 0, cleanedupRanges_1 = cleanedupRanges;
|
|
164
|
+
_b.label = 1;
|
|
165
|
+
case 1:
|
|
166
|
+
if (!(_i < cleanedupRanges_1.length)) return [3 /*break*/, 4];
|
|
167
|
+
range = cleanedupRanges_1[_i];
|
|
168
|
+
if (!(range.start < range.end)) return [3 /*break*/, 3];
|
|
169
|
+
log.debug("GC: cleaning range from SegmentBuffer", range.start, range.end);
|
|
170
|
+
if (cancellationSignal.cancellationError !== null) {
|
|
171
|
+
throw cancellationSignal.cancellationError;
|
|
172
|
+
}
|
|
173
|
+
return [4 /*yield*/, segmentBuffer.removeBuffer(range.start, range.end, cancellationSignal)];
|
|
174
|
+
case 2:
|
|
175
|
+
_b.sent();
|
|
176
|
+
_b.label = 3;
|
|
177
|
+
case 3:
|
|
178
|
+
_i++;
|
|
179
|
+
return [3 /*break*/, 1];
|
|
180
|
+
case 4: return [2 /*return*/];
|
|
101
181
|
}
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
collectBufferBehind();
|
|
105
|
-
collectBufferAhead();
|
|
106
|
-
var clean$ = observableFrom(cleanedupRanges.map(function (range) {
|
|
107
|
-
log.debug("GC: cleaning range from SegmentBuffer", range.start, range.end);
|
|
108
|
-
if (range.start >= range.end) {
|
|
109
|
-
return observableOf(null);
|
|
110
|
-
}
|
|
111
|
-
return segmentBuffer.removeBuffer(range.start, range.end);
|
|
112
|
-
})).pipe(concatAll(),
|
|
113
|
-
// NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
|
|
114
|
-
// first type parameter as `any` instead of the perfectly fine `unknown`,
|
|
115
|
-
// leading to linter issues, as it forbids the usage of `any`.
|
|
116
|
-
// This is why we're disabling the eslint rule.
|
|
117
|
-
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
|
|
118
|
-
ignoreElements());
|
|
119
|
-
return clean$;
|
|
182
|
+
});
|
|
183
|
+
});
|
|
120
184
|
}
|
|
@@ -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 {
|
|
16
|
+
import { CancellationSignal } from "../../../../utils/task_canceller";
|
|
17
17
|
import { IEndOfSegmentInfos, IPushChunkInfos, ISBOperation, SegmentBuffer } from "../types";
|
|
18
18
|
/**
|
|
19
19
|
* Allows to push and remove new segments to a SourceBuffer in a FIFO queue (not
|
|
@@ -31,10 +31,9 @@ export default class AudioVideoSegmentBuffer extends SegmentBuffer {
|
|
|
31
31
|
/** SourceBuffer implementation. */
|
|
32
32
|
private readonly _sourceBuffer;
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
* Helps to clean-up Observables created at its creation.
|
|
34
|
+
* Helps to clean-up resource taken at the AudioVideoSegmentBuffer creation.
|
|
36
35
|
*/
|
|
37
|
-
private
|
|
36
|
+
private _canceller;
|
|
38
37
|
/**
|
|
39
38
|
* Queue of awaited buffer "operations".
|
|
40
39
|
* The first element in this array will be the first performed.
|
|
@@ -64,7 +63,7 @@ export default class AudioVideoSegmentBuffer extends SegmentBuffer {
|
|
|
64
63
|
* @constructor
|
|
65
64
|
* @param {string} bufferType
|
|
66
65
|
* @param {string} codec
|
|
67
|
-
* @param {
|
|
66
|
+
* @param {MediaSource} mediaSource
|
|
68
67
|
*/
|
|
69
68
|
constructor(bufferType: "audio" | "video", codec: string, mediaSource: MediaSource);
|
|
70
69
|
/**
|
|
@@ -91,26 +90,28 @@ export default class AudioVideoSegmentBuffer extends SegmentBuffer {
|
|
|
91
90
|
* `data.chunk` argument to null.
|
|
92
91
|
*
|
|
93
92
|
* @param {Object} infos
|
|
94
|
-
* @
|
|
93
|
+
* @param {Object} cancellationSignal
|
|
94
|
+
* @returns {Promise}
|
|
95
95
|
*/
|
|
96
|
-
pushChunk(infos: IPushChunkInfos<unknown
|
|
96
|
+
pushChunk(infos: IPushChunkInfos<unknown>, cancellationSignal: CancellationSignal): Promise<void>;
|
|
97
97
|
/**
|
|
98
98
|
* Remove buffered data (added to the same FIFO queue than `pushChunk`).
|
|
99
99
|
* @param {number} start - start position, in seconds
|
|
100
100
|
* @param {number} end - end position, in seconds
|
|
101
|
-
* @
|
|
101
|
+
* @param {Object} cancellationSignal
|
|
102
|
+
* @returns {Promise}
|
|
102
103
|
*/
|
|
103
|
-
removeBuffer(start: number, end: number):
|
|
104
|
+
removeBuffer(start: number, end: number, cancellationSignal: CancellationSignal): Promise<void>;
|
|
104
105
|
/**
|
|
105
106
|
* Indicate that every chunks from a Segment has been given to pushChunk so
|
|
106
107
|
* far.
|
|
107
108
|
* This will update our internal Segment inventory accordingly.
|
|
108
|
-
* The returned
|
|
109
|
-
*
|
|
109
|
+
* The returned Promise will resolve once the whole segment has been pushed
|
|
110
|
+
* and this indication is acknowledged.
|
|
110
111
|
* @param {Object} infos
|
|
111
|
-
* @returns {
|
|
112
|
+
* @returns {Promise}
|
|
112
113
|
*/
|
|
113
|
-
endOfSegment(infos: IEndOfSegmentInfos):
|
|
114
|
+
endOfSegment(infos: IEndOfSegmentInfos, cancellationSignal: CancellationSignal): Promise<void>;
|
|
114
115
|
/**
|
|
115
116
|
* Returns the currently buffered data, in a TimeRanges object.
|
|
116
117
|
* @returns {TimeRanges}
|
|
@@ -133,7 +134,7 @@ export default class AudioVideoSegmentBuffer extends SegmentBuffer {
|
|
|
133
134
|
dispose(): void;
|
|
134
135
|
/**
|
|
135
136
|
* Called when an error arised that made the current task fail.
|
|
136
|
-
* @param {Event}
|
|
137
|
+
* @param {Event} err
|
|
137
138
|
*/
|
|
138
139
|
private _onPendingTaskError;
|
|
139
140
|
/**
|
|
@@ -144,7 +145,8 @@ export default class AudioVideoSegmentBuffer extends SegmentBuffer {
|
|
|
144
145
|
* Cancel queued operation on unsubscription.
|
|
145
146
|
* @private
|
|
146
147
|
* @param {Object} operation
|
|
147
|
-
* @
|
|
148
|
+
* @param {Object} cancellationSignal
|
|
149
|
+
* @returns {Promise}
|
|
148
150
|
*/
|
|
149
151
|
private _addToQueue;
|
|
150
152
|
/**
|
|
@@ -160,7 +162,7 @@ export default class AudioVideoSegmentBuffer extends SegmentBuffer {
|
|
|
160
162
|
*
|
|
161
163
|
* This method allows to "prepare" that push operation so that all is left is
|
|
162
164
|
* to push the returned segment data one after the other (from first to last).
|
|
163
|
-
* @param {Object}
|
|
165
|
+
* @param {Object} data
|
|
164
166
|
* @returns {Object}
|
|
165
167
|
*/
|
|
166
168
|
private _preparePushOperation;
|