rx-player 3.28.1-dev.2022083000 → 3.29.0-dev.2022090500
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/event_listeners.d.ts +18 -2
- package/dist/_esm5.processed/compat/event_listeners.js +64 -2
- package/dist/_esm5.processed/compat/on_height_width_change.d.ts +5 -4
- package/dist/_esm5.processed/compat/on_height_width_change.js +43 -34
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +12 -2
- package/dist/_esm5.processed/core/api/playback_observer.js +27 -12
- package/dist/_esm5.processed/core/api/public_api.js +14 -14
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.d.ts +7 -0
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +10 -2
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +8 -1
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +10 -4
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +7 -0
- package/dist/_esm5.processed/core/init/initialize_directfile.js +1 -1
- package/dist/_esm5.processed/core/init/load_on_media_source.js +1 -1
- package/dist/_esm5.processed/core/init/stall_avoider.d.ts +4 -2
- package/dist/_esm5.processed/core/init/stall_avoider.js +32 -26
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.d.ts +12 -6
- package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +142 -78
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.d.ts +18 -16
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +53 -41
- package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.d.ts +6 -5
- package/dist/_esm5.processed/core/segment_buffers/implementations/image/image_segment_buffer.js +37 -39
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.d.ts +23 -22
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +84 -72
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.d.ts +6 -12
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/native/native_text_segment_buffer.js +33 -43
- package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +12 -9
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.d.ts +7 -6
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +17 -10
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +20 -9
- package/dist/_esm5.processed/core/stream/period/period_stream.js +25 -14
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.d.ts +4 -7
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +80 -23
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.d.ts +5 -4
- package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +78 -26
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +7 -3
- package/dist/_esm5.processed/core/stream/representation/push_init_segment.js +7 -1
- package/dist/_esm5.processed/core/stream/representation/push_media_segment.js +7 -1
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -8
- package/dist/_esm5.processed/default_config.js +1 -1
- package/dist/_esm5.processed/errors/custom_loader_error.d.ts +3 -2
- package/dist/_esm5.processed/errors/custom_loader_error.js +3 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +5 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.js +5 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.js +9 -2
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +3 -1
- package/dist/_esm5.processed/experimental/tools/createMetaplaylist/get_duration_from_manifest.js +4 -3
- package/dist/_esm5.processed/public_types.d.ts +22 -3
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +2 -2
- package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/image_pipelines.js +3 -1
- package/dist/_esm5.processed/transports/dash/init_segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/init_segment_loader.js +12 -6
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +3 -2
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +6 -2
- package/dist/_esm5.processed/transports/dash/segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/segment_loader.js +12 -9
- package/dist/_esm5.processed/transports/dash/text_loader.js +6 -3
- package/dist/_esm5.processed/transports/local/pipelines.d.ts +2 -2
- package/dist/_esm5.processed/transports/local/pipelines.js +6 -6
- package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/local/segment_loader.js +4 -3
- package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/metaplaylist/manifest_loader.js +5 -2
- package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +15 -10
- package/dist/_esm5.processed/transports/smooth/pipelines.d.ts +1 -1
- package/dist/_esm5.processed/transports/smooth/pipelines.js +18 -14
- package/dist/_esm5.processed/transports/smooth/segment_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +8 -6
- package/dist/_esm5.processed/transports/types.d.ts +25 -2
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
- package/dist/_esm5.processed/transports/utils/generate_manifest_loader.d.ts +2 -2
- package/dist/_esm5.processed/transports/utils/generate_manifest_loader.js +9 -6
- package/dist/_esm5.processed/utils/request/fetch.js +7 -8
- package/dist/_esm5.processed/utils/request/xhr.d.ts +1 -1
- package/dist/_esm5.processed/utils/request/xhr.js +28 -14
- package/dist/_esm5.processed/utils/task_canceller.d.ts +1 -2
- package/dist/_esm5.processed/utils/task_canceller.js +1 -2
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.js +1116 -695
- package/dist/rx-player.min.js +1 -1
- package/package.json +7 -7
- package/sonar-project.properties +1 -1
- package/src/compat/event_listeners.ts +86 -1
- package/src/compat/on_height_width_change.ts +48 -49
- package/src/core/api/playback_observer.ts +34 -14
- package/src/core/api/public_api.ts +23 -18
- package/src/core/fetchers/manifest/manifest_fetcher.ts +20 -2
- package/src/core/fetchers/segment/segment_fetcher.ts +23 -3
- package/src/core/fetchers/segment/segment_fetcher_creator.ts +7 -0
- package/src/core/init/initialize_directfile.ts +1 -1
- package/src/core/init/load_on_media_source.ts +1 -0
- package/src/core/init/stall_avoider.ts +40 -26
- package/src/core/segment_buffers/garbage_collector.ts +55 -47
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +92 -70
- package/src/core/segment_buffers/implementations/image/image_segment_buffer.ts +37 -42
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +103 -105
- package/src/core/segment_buffers/implementations/text/native/native_text_segment_buffer.ts +35 -46
- package/src/core/segment_buffers/implementations/types.ts +22 -9
- package/src/core/segment_buffers/segment_buffers_store.ts +23 -14
- package/src/core/stream/orchestrator/stream_orchestrator.ts +31 -12
- package/src/core/stream/period/period_stream.ts +31 -18
- package/src/core/stream/representation/append_segment_to_buffer.ts +27 -42
- package/src/core/stream/representation/force_garbage_collection.ts +28 -32
- package/src/core/stream/representation/get_buffer_status.ts +7 -3
- package/src/core/stream/representation/push_init_segment.ts +12 -6
- package/src/core/stream/representation/push_media_segment.ts +12 -6
- package/src/core/stream/representation/representation_stream.ts +11 -5
- package/src/default_config.ts +17 -17
- package/src/errors/custom_loader_error.ts +3 -2
- package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +7 -2
- package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +6 -2
- package/src/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.ts +10 -2
- package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +3 -1
- package/src/experimental/tools/createMetaplaylist/get_duration_from_manifest.ts +4 -3
- package/src/public_types.ts +28 -4
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +2 -2
- package/src/transports/dash/image_pipelines.ts +4 -0
- package/src/transports/dash/init_segment_loader.ts +8 -0
- package/src/transports/dash/low_latency_segment_loader.ts +4 -0
- package/src/transports/dash/manifest_parser.ts +4 -0
- package/src/transports/dash/segment_loader.ts +21 -5
- package/src/transports/dash/text_loader.ts +7 -2
- package/src/transports/local/pipelines.ts +7 -5
- package/src/transports/local/segment_loader.ts +4 -2
- package/src/transports/metaplaylist/manifest_loader.ts +9 -2
- package/src/transports/metaplaylist/pipelines.ts +16 -6
- package/src/transports/smooth/pipelines.ts +17 -9
- package/src/transports/smooth/segment_loader.ts +8 -0
- package/src/transports/types.ts +27 -0
- package/src/transports/utils/call_custom_manifest_loader.ts +8 -2
- package/src/transports/utils/generate_manifest_loader.ts +18 -5
- package/src/utils/request/fetch.ts +7 -8
- package/src/utils/request/xhr.ts +31 -15
- package/src/utils/task_canceller.ts +1 -2
|
@@ -14,11 +14,6 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
defer as observableDefer,
|
|
19
|
-
Observable,
|
|
20
|
-
of as observableOf,
|
|
21
|
-
} from "rxjs";
|
|
22
17
|
import log from "../../../../log";
|
|
23
18
|
import { IBifThumbnail } from "../../../../parsers/images/bif";
|
|
24
19
|
import {
|
|
@@ -45,55 +40,57 @@ export default class ImageSegmentBuffer extends SegmentBuffer {
|
|
|
45
40
|
|
|
46
41
|
/**
|
|
47
42
|
* @param {Object} data
|
|
43
|
+
* @returns {Promise}
|
|
48
44
|
*/
|
|
49
45
|
public pushChunk(
|
|
50
46
|
infos : IPushChunkInfos<unknown>
|
|
51
|
-
) :
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
chunk } = infos.data;
|
|
47
|
+
) : Promise<void> {
|
|
48
|
+
log.debug("ISB: appending new data.");
|
|
49
|
+
if (infos.data.chunk === null) {
|
|
50
|
+
return Promise.resolve();
|
|
51
|
+
}
|
|
52
|
+
const { appendWindow,
|
|
53
|
+
chunk } = infos.data;
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
// The following check is ugly. I don't care, the image buffer is there
|
|
56
|
+
// due to an ugly deprecated API that will soon disappear
|
|
57
|
+
const { start, end, timescale } = chunk as IImageTrackSegmentData;
|
|
58
|
+
const appendWindowStart = appendWindow[0] ?? 0;
|
|
59
|
+
const appendWindowEnd = appendWindow[1] ?? Infinity;
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const timescaledStart = start / timescale;
|
|
62
|
+
const timescaledEnd = end / timescale;
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
const startTime = Math.max(appendWindowStart, timescaledStart);
|
|
65
|
+
const endTime = Math.min(appendWindowEnd, timescaledEnd);
|
|
71
66
|
|
|
67
|
+
try {
|
|
72
68
|
this._buffered.insert(startTime, endTime);
|
|
73
69
|
if (infos.inventoryInfos !== null) {
|
|
74
70
|
this._segmentInventory.insertChunk(infos.inventoryInfos);
|
|
75
71
|
}
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
} catch (err) {
|
|
73
|
+
return Promise.reject(err);
|
|
74
|
+
}
|
|
75
|
+
return Promise.resolve();
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
/**
|
|
81
79
|
* @param {Number} from
|
|
82
80
|
* @param {Number} to
|
|
81
|
+
* @returns {Promise}
|
|
83
82
|
*/
|
|
84
|
-
public removeBuffer(start : number, end : number) :
|
|
85
|
-
|
|
86
|
-
log.info("ISB: ignored image data remove order", start, end);
|
|
83
|
+
public removeBuffer(start : number, end : number) : Promise<void> {
|
|
84
|
+
log.info("ISB: ignored image data remove order", start, end);
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
86
|
+
// Logic removed as it caused more problems than it resolved:
|
|
87
|
+
// Image thumbnails are always downloaded as a single BIF file, meaning that
|
|
88
|
+
// any removing might necessitate to re-load the whole file in the future
|
|
89
|
+
// which seems pointless.
|
|
90
|
+
// In any case, image handling through the regular RxPlayer APIs has been
|
|
91
|
+
// completely deprecated now for several reasons, and should disappear in
|
|
92
|
+
// the next major version.
|
|
93
|
+
return Promise.resolve();
|
|
97
94
|
}
|
|
98
95
|
|
|
99
96
|
/**
|
|
@@ -103,13 +100,11 @@ export default class ImageSegmentBuffer extends SegmentBuffer {
|
|
|
103
100
|
* The returned Observable will emit and complete successively once the whole
|
|
104
101
|
* segment has been pushed and this indication is acknowledged.
|
|
105
102
|
* @param {Object} infos
|
|
106
|
-
* @returns {
|
|
103
|
+
* @returns {Promise}
|
|
107
104
|
*/
|
|
108
|
-
public endOfSegment(_infos : IEndOfSegmentInfos) :
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return observableOf(undefined);
|
|
112
|
-
});
|
|
105
|
+
public endOfSegment(_infos : IEndOfSegmentInfos) : Promise<void> {
|
|
106
|
+
this._segmentInventory.completeSegment(_infos, this._buffered);
|
|
107
|
+
return Promise.resolve();
|
|
113
108
|
}
|
|
114
109
|
|
|
115
110
|
/**
|
|
@@ -14,19 +14,6 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
concat as observableConcat,
|
|
19
|
-
defer as observableDefer,
|
|
20
|
-
interval as observableInterval,
|
|
21
|
-
map,
|
|
22
|
-
merge as observableMerge,
|
|
23
|
-
Observable,
|
|
24
|
-
of as observableOf,
|
|
25
|
-
startWith,
|
|
26
|
-
Subject,
|
|
27
|
-
switchMap,
|
|
28
|
-
takeUntil,
|
|
29
|
-
} from "rxjs";
|
|
30
17
|
import {
|
|
31
18
|
events,
|
|
32
19
|
onHeightWidthChange,
|
|
@@ -34,6 +21,9 @@ import {
|
|
|
34
21
|
import config from "../../../../../config";
|
|
35
22
|
import log from "../../../../../log";
|
|
36
23
|
import { ITextTrackSegmentData } from "../../../../../transports";
|
|
24
|
+
import TaskCanceller, {
|
|
25
|
+
CancellationSignal,
|
|
26
|
+
} from "../../../../../utils/task_canceller";
|
|
37
27
|
import {
|
|
38
28
|
IEndOfSegmentInfos,
|
|
39
29
|
IPushChunkInfos,
|
|
@@ -44,31 +34,7 @@ import parseTextTrackToElements from "./parsers";
|
|
|
44
34
|
import TextTrackCuesStore from "./text_track_cues_store";
|
|
45
35
|
import updateProportionalElements from "./update_proportional_elements";
|
|
46
36
|
|
|
47
|
-
const { onEnded
|
|
48
|
-
onSeeked$,
|
|
49
|
-
onSeeking$ } = events;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Generate the interval at which TextTrack HTML Cues should be refreshed.
|
|
54
|
-
* @param {HTMLMediaElement} videoElement
|
|
55
|
-
* @returns {Observable}
|
|
56
|
-
*/
|
|
57
|
-
function generateRefreshInterval(videoElement : HTMLMediaElement) : Observable<boolean> {
|
|
58
|
-
const seeking$ = onSeeking$(videoElement);
|
|
59
|
-
const seeked$ = onSeeked$(videoElement);
|
|
60
|
-
const ended$ = onEnded$(videoElement);
|
|
61
|
-
const { MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL } = config.getCurrent();
|
|
62
|
-
const manualRefresh$ = observableMerge(seeked$, ended$);
|
|
63
|
-
const autoRefresh$ = observableInterval(MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL)
|
|
64
|
-
.pipe(startWith(null));
|
|
65
|
-
|
|
66
|
-
return manualRefresh$.pipe(
|
|
67
|
-
startWith(null),
|
|
68
|
-
switchMap(() => observableConcat(autoRefresh$.pipe(map(() => true),
|
|
69
|
-
takeUntil(seeking$)),
|
|
70
|
-
observableOf(false))));
|
|
71
|
-
}
|
|
37
|
+
const { onEnded, onSeeked, onSeeking } = events;
|
|
72
38
|
|
|
73
39
|
/**
|
|
74
40
|
* @param {Element} element
|
|
@@ -116,12 +82,8 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
116
82
|
*/
|
|
117
83
|
private readonly _videoElement : HTMLMediaElement;
|
|
118
84
|
|
|
119
|
-
/**
|
|
120
|
-
|
|
121
|
-
* unsubscribed.
|
|
122
|
-
* Used for clean-up
|
|
123
|
-
*/
|
|
124
|
-
private readonly _destroy$ : Subject<void>;
|
|
85
|
+
/** Used for clean-up. */
|
|
86
|
+
private readonly _canceller : TaskCanceller;
|
|
125
87
|
|
|
126
88
|
/** HTMLElement which will contain the cues */
|
|
127
89
|
private readonly _textTrackElement : HTMLElement;
|
|
@@ -131,10 +93,10 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
131
93
|
|
|
132
94
|
/**
|
|
133
95
|
* We could need us to automatically update styling depending on
|
|
134
|
-
* `_textTrackElement`'s size. This
|
|
96
|
+
* `_textTrackElement`'s size. This TaskCanceller allows to stop that
|
|
135
97
|
* regular check.
|
|
136
98
|
*/
|
|
137
|
-
private
|
|
99
|
+
private _sizeUpdateCanceller : TaskCanceller;
|
|
138
100
|
|
|
139
101
|
/** Information on cues currently displayed. */
|
|
140
102
|
private _currentCues : Array<{
|
|
@@ -167,72 +129,46 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
167
129
|
|
|
168
130
|
this._videoElement = videoElement;
|
|
169
131
|
this._textTrackElement = textTrackElement;
|
|
170
|
-
this.
|
|
171
|
-
this.
|
|
132
|
+
this._sizeUpdateCanceller = new TaskCanceller();
|
|
133
|
+
this._canceller = new TaskCanceller();
|
|
172
134
|
this._buffer = new TextTrackCuesStore();
|
|
173
135
|
this._currentCues = [];
|
|
174
136
|
|
|
175
|
-
|
|
176
|
-
generateRefreshInterval(this._videoElement)
|
|
177
|
-
.pipe(takeUntil(this._destroy$))
|
|
178
|
-
.subscribe((shouldDisplay) => {
|
|
179
|
-
if (!shouldDisplay) {
|
|
180
|
-
this._disableCurrentCues();
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
const { MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL } = config.getCurrent();
|
|
184
|
-
// to spread the time error, we divide the regular chosen interval.
|
|
185
|
-
const time = Math.max(this._videoElement.currentTime +
|
|
186
|
-
(MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL / 1000) / 2,
|
|
187
|
-
0);
|
|
188
|
-
const cues = this._buffer.get(time);
|
|
189
|
-
if (cues.length === 0) {
|
|
190
|
-
this._disableCurrentCues();
|
|
191
|
-
} else {
|
|
192
|
-
this._displayCues(cues);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
137
|
+
this.autoRefreshSubtitles(this._canceller.signal);
|
|
195
138
|
}
|
|
196
139
|
|
|
197
140
|
/**
|
|
198
141
|
* Push segment on Subscription.
|
|
199
142
|
* @param {Object} infos
|
|
200
|
-
* @returns {
|
|
143
|
+
* @returns {Promise}
|
|
201
144
|
*/
|
|
202
|
-
public pushChunk(infos : IPushChunkInfos<unknown>) :
|
|
203
|
-
|
|
145
|
+
public pushChunk(infos : IPushChunkInfos<unknown>) : Promise<void> {
|
|
146
|
+
try {
|
|
204
147
|
this.pushChunkSync(infos);
|
|
205
|
-
|
|
206
|
-
|
|
148
|
+
} catch (err) {
|
|
149
|
+
return Promise.reject(err);
|
|
150
|
+
}
|
|
151
|
+
return Promise.resolve();
|
|
207
152
|
}
|
|
208
153
|
|
|
209
154
|
/**
|
|
210
155
|
* Remove buffered data.
|
|
211
156
|
* @param {number} start - start position, in seconds
|
|
212
157
|
* @param {number} end - end position, in seconds
|
|
213
|
-
* @returns {
|
|
158
|
+
* @returns {Promise}
|
|
214
159
|
*/
|
|
215
|
-
public removeBuffer(start : number, end : number) :
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return observableOf(undefined);
|
|
219
|
-
});
|
|
160
|
+
public removeBuffer(start : number, end : number) : Promise<void> {
|
|
161
|
+
this.removeBufferSync(start, end);
|
|
162
|
+
return Promise.resolve();
|
|
220
163
|
}
|
|
221
164
|
|
|
222
165
|
/**
|
|
223
|
-
* Indicate that every chunks from a Segment has been given to pushChunk so
|
|
224
|
-
* far.
|
|
225
|
-
* This will update our internal Segment inventory accordingly.
|
|
226
|
-
* The returned Observable will emit and complete successively once the whole
|
|
227
|
-
* segment has been pushed and this indication is acknowledged.
|
|
228
166
|
* @param {Object} infos
|
|
229
|
-
* @returns {
|
|
167
|
+
* @returns {Promise}
|
|
230
168
|
*/
|
|
231
|
-
public endOfSegment(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
return observableOf(undefined);
|
|
235
|
-
});
|
|
169
|
+
public endOfSegment(infos : IEndOfSegmentInfos) : Promise<void> {
|
|
170
|
+
this._segmentInventory.completeSegment(infos, this._buffered);
|
|
171
|
+
return Promise.resolve();
|
|
236
172
|
}
|
|
237
173
|
|
|
238
174
|
/**
|
|
@@ -248,8 +184,7 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
248
184
|
this._disableCurrentCues();
|
|
249
185
|
this._buffer.remove(0, Infinity);
|
|
250
186
|
this._buffered.remove(0, Infinity);
|
|
251
|
-
this.
|
|
252
|
-
this._destroy$.complete();
|
|
187
|
+
this._canceller.cancel();
|
|
253
188
|
}
|
|
254
189
|
|
|
255
190
|
/**
|
|
@@ -264,7 +199,7 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
264
199
|
*
|
|
265
200
|
* /!\ This method won't add any data to the linked inventory.
|
|
266
201
|
* Please use the `pushChunk` method for most use-cases.
|
|
267
|
-
* @param {Object}
|
|
202
|
+
* @param {Object} infos
|
|
268
203
|
* @returns {boolean}
|
|
269
204
|
*/
|
|
270
205
|
public pushChunkSync(infos : IPushChunkInfos<unknown>) : void {
|
|
@@ -375,7 +310,7 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
375
310
|
* Remove the current cue from being displayed.
|
|
376
311
|
*/
|
|
377
312
|
private _disableCurrentCues() : void {
|
|
378
|
-
this.
|
|
313
|
+
this._sizeUpdateCanceller.cancel();
|
|
379
314
|
if (this._currentCues.length > 0) {
|
|
380
315
|
for (let i = 0; i < this._currentCues.length; i++) {
|
|
381
316
|
safelyRemoveChild(this._textTrackElement, this._currentCues[i].element);
|
|
@@ -386,7 +321,7 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
386
321
|
|
|
387
322
|
/**
|
|
388
323
|
* Display a new Cue. If one was already present, it will be replaced.
|
|
389
|
-
* @param {HTMLElement}
|
|
324
|
+
* @param {HTMLElement} elements
|
|
390
325
|
*/
|
|
391
326
|
private _displayCues(elements : HTMLElement[]) : void {
|
|
392
327
|
const nothingChanged = this._currentCues.length === elements.length &&
|
|
@@ -399,7 +334,7 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
399
334
|
// Remove and re-display everything
|
|
400
335
|
// TODO More intelligent handling
|
|
401
336
|
|
|
402
|
-
this.
|
|
337
|
+
this._sizeUpdateCanceller.cancel();
|
|
403
338
|
for (let i = 0; i < this._currentCues.length; i++) {
|
|
404
339
|
safelyRemoveChild(this._textTrackElement, this._currentCues[i].element);
|
|
405
340
|
}
|
|
@@ -418,17 +353,80 @@ export default class HTMLTextSegmentBuffer extends SegmentBuffer {
|
|
|
418
353
|
element : HTMLElement; } => cue.resolution !== null);
|
|
419
354
|
|
|
420
355
|
if (proportionalCues.length > 0) {
|
|
356
|
+
this._sizeUpdateCanceller = new TaskCanceller({ cancelOn: this._canceller.signal });
|
|
421
357
|
const { TEXT_TRACK_SIZE_CHECKS_INTERVAL } = config.getCurrent();
|
|
422
358
|
// update propertionally-sized elements periodically
|
|
423
|
-
onHeightWidthChange(this._textTrackElement,
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
359
|
+
const heightWidthRef = onHeightWidthChange(this._textTrackElement,
|
|
360
|
+
TEXT_TRACK_SIZE_CHECKS_INTERVAL,
|
|
361
|
+
this._sizeUpdateCanceller.signal);
|
|
362
|
+
heightWidthRef.onUpdate(({ height, width }) => {
|
|
363
|
+
for (let i = 0; i < proportionalCues.length; i++) {
|
|
364
|
+
const { resolution, element } = proportionalCues[i];
|
|
365
|
+
updateProportionalElements(height, width, resolution, element);
|
|
366
|
+
}
|
|
367
|
+
}, { clearSignal: this._sizeUpdateCanceller.signal,
|
|
368
|
+
emitCurrentValue: true });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Auto-refresh the display of subtitles according to the media element's
|
|
374
|
+
* position and events.
|
|
375
|
+
* @param {Object} cancellationSignal
|
|
376
|
+
*/
|
|
377
|
+
private autoRefreshSubtitles(
|
|
378
|
+
cancellationSignal : CancellationSignal
|
|
379
|
+
) : void {
|
|
380
|
+
let autoRefreshCanceller : TaskCanceller | null = null;
|
|
381
|
+
const { MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL } = config.getCurrent();
|
|
382
|
+
|
|
383
|
+
const startAutoRefresh = () => {
|
|
384
|
+
stopAutoRefresh();
|
|
385
|
+
autoRefreshCanceller = new TaskCanceller({ cancelOn: cancellationSignal });
|
|
386
|
+
const intervalId = setInterval(() => this.refreshSubtitles(),
|
|
387
|
+
MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL);
|
|
388
|
+
autoRefreshCanceller.signal.register(() => {
|
|
389
|
+
clearInterval(intervalId);
|
|
390
|
+
});
|
|
391
|
+
this.refreshSubtitles();
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
onSeeking(this._videoElement, () => {
|
|
395
|
+
stopAutoRefresh();
|
|
396
|
+
this._disableCurrentCues();
|
|
397
|
+
}, cancellationSignal);
|
|
398
|
+
onSeeked(this._videoElement, startAutoRefresh, cancellationSignal);
|
|
399
|
+
onEnded(this._videoElement, startAutoRefresh, cancellationSignal);
|
|
400
|
+
|
|
401
|
+
function stopAutoRefresh() {
|
|
402
|
+
if (autoRefreshCanceller !== null) {
|
|
403
|
+
autoRefreshCanceller.cancel();
|
|
404
|
+
autoRefreshCanceller = null;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Refresh current subtitles according to the current media element's
|
|
411
|
+
* position.
|
|
412
|
+
*/
|
|
413
|
+
private refreshSubtitles() : void {
|
|
414
|
+
const videoElt = this._videoElement;
|
|
415
|
+
const { MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL } = config.getCurrent();
|
|
416
|
+
let time;
|
|
417
|
+
if (videoElt.paused || videoElt.playbackRate <= 0) {
|
|
418
|
+
time = videoElt.currentTime;
|
|
419
|
+
} else {
|
|
420
|
+
// to spread the time error, we divide the regular chosen interval.
|
|
421
|
+
time = Math.max(this._videoElement.currentTime +
|
|
422
|
+
(MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL / 1000) / 2,
|
|
423
|
+
0);
|
|
424
|
+
}
|
|
425
|
+
const cues = this._buffer.get(time);
|
|
426
|
+
if (cues.length === 0) {
|
|
427
|
+
this._disableCurrentCues();
|
|
428
|
+
} else {
|
|
429
|
+
this._displayCues(cues);
|
|
432
430
|
}
|
|
433
431
|
}
|
|
434
432
|
}
|
|
@@ -14,11 +14,6 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
defer as observableDefer,
|
|
19
|
-
Observable,
|
|
20
|
-
of as observableOf,
|
|
21
|
-
} from "rxjs";
|
|
22
17
|
import {
|
|
23
18
|
addTextTrack,
|
|
24
19
|
ICompatTextTrack,
|
|
@@ -73,26 +68,26 @@ export default class NativeTextSegmentBuffer extends SegmentBuffer {
|
|
|
73
68
|
|
|
74
69
|
/**
|
|
75
70
|
* @param {Object} infos
|
|
76
|
-
* @returns {
|
|
71
|
+
* @returns {Promise}
|
|
77
72
|
*/
|
|
78
|
-
public pushChunk(infos : IPushChunkInfos<unknown>) :
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
73
|
+
public pushChunk(infos : IPushChunkInfos<unknown>) : Promise<void> {
|
|
74
|
+
log.debug("NTSB: Appending new native text tracks");
|
|
75
|
+
if (infos.data.chunk === null) {
|
|
76
|
+
return Promise.resolve();
|
|
77
|
+
}
|
|
78
|
+
const { timestampOffset,
|
|
79
|
+
appendWindow,
|
|
80
|
+
chunk } = infos.data;
|
|
81
|
+
assertChunkIsTextTrackSegmentData(chunk);
|
|
82
|
+
const { start: startTime,
|
|
83
|
+
end: endTime,
|
|
84
|
+
data: dataString,
|
|
85
|
+
type,
|
|
86
|
+
language } = chunk;
|
|
87
|
+
const appendWindowStart = appendWindow[0] ?? 0;
|
|
88
|
+
const appendWindowEnd = appendWindow[1] ?? Infinity;
|
|
89
|
+
|
|
90
|
+
try {
|
|
96
91
|
const cues = parseTextTrackToCues(type, dataString, timestampOffset, language);
|
|
97
92
|
|
|
98
93
|
if (appendWindowStart !== 0 && appendWindowEnd !== Infinity) {
|
|
@@ -130,7 +125,7 @@ export default class NativeTextSegmentBuffer extends SegmentBuffer {
|
|
|
130
125
|
} else {
|
|
131
126
|
if (cues.length <= 0) {
|
|
132
127
|
log.warn("NTSB: Current text tracks have no cues nor start time. Aborting");
|
|
133
|
-
return
|
|
128
|
+
return Promise.resolve();
|
|
134
129
|
}
|
|
135
130
|
log.warn("NTSB: No start time given. Guessing from cues.");
|
|
136
131
|
start = cues[0].startTime;
|
|
@@ -142,7 +137,7 @@ export default class NativeTextSegmentBuffer extends SegmentBuffer {
|
|
|
142
137
|
} else {
|
|
143
138
|
if (cues.length <= 0) {
|
|
144
139
|
log.warn("NTSB: Current text tracks have no cues nor end time. Aborting");
|
|
145
|
-
return
|
|
140
|
+
return Promise.resolve();
|
|
146
141
|
}
|
|
147
142
|
log.warn("NTSB: No end time given. Guessing from cues.");
|
|
148
143
|
end = cues[cues.length - 1].endTime;
|
|
@@ -151,7 +146,7 @@ export default class NativeTextSegmentBuffer extends SegmentBuffer {
|
|
|
151
146
|
if (end <= start) {
|
|
152
147
|
log.warn("NTSB: Invalid text track appended: ",
|
|
153
148
|
"the start time is inferior or equal to the end time.");
|
|
154
|
-
return
|
|
149
|
+
return Promise.resolve();
|
|
155
150
|
}
|
|
156
151
|
|
|
157
152
|
if (cues.length > 0) {
|
|
@@ -178,37 +173,31 @@ export default class NativeTextSegmentBuffer extends SegmentBuffer {
|
|
|
178
173
|
if (infos.inventoryInfos !== null) {
|
|
179
174
|
this._segmentInventory.insertChunk(infos.inventoryInfos);
|
|
180
175
|
}
|
|
181
|
-
|
|
182
|
-
|
|
176
|
+
} catch (err) {
|
|
177
|
+
return Promise.reject(err);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return Promise.resolve();
|
|
183
181
|
}
|
|
184
182
|
|
|
185
183
|
/**
|
|
186
184
|
* Remove buffered data.
|
|
187
185
|
* @param {number} start - start position, in seconds
|
|
188
186
|
* @param {number} end - end position, in seconds
|
|
189
|
-
* @returns {
|
|
187
|
+
* @returns {Promise}
|
|
190
188
|
*/
|
|
191
|
-
public removeBuffer(start : number, end : number) :
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return observableOf(undefined);
|
|
195
|
-
});
|
|
189
|
+
public removeBuffer(start : number, end : number) : Promise<void> {
|
|
190
|
+
this._removeData(start, end);
|
|
191
|
+
return Promise.resolve();
|
|
196
192
|
}
|
|
197
193
|
|
|
198
194
|
/**
|
|
199
|
-
* Indicate that every chunks from a Segment has been given to pushChunk so
|
|
200
|
-
* far.
|
|
201
|
-
* This will update our internal Segment inventory accordingly.
|
|
202
|
-
* The returned Observable will emit and complete successively once the whole
|
|
203
|
-
* segment has been pushed and this indication is acknowledged.
|
|
204
195
|
* @param {Object} infos
|
|
205
|
-
* @returns {
|
|
196
|
+
* @returns {Promise}
|
|
206
197
|
*/
|
|
207
|
-
public endOfSegment(_infos : IEndOfSegmentInfos) :
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return observableOf(undefined);
|
|
211
|
-
});
|
|
198
|
+
public endOfSegment(_infos : IEndOfSegmentInfos) : Promise<void> {
|
|
199
|
+
this._segmentInventory.completeSegment(_infos, this._buffered);
|
|
200
|
+
return Promise.resolve();
|
|
212
201
|
}
|
|
213
202
|
|
|
214
203
|
/**
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { Observable } from "rxjs";
|
|
18
17
|
import {
|
|
19
18
|
Adaptation,
|
|
20
19
|
ISegment,
|
|
21
20
|
Period,
|
|
22
21
|
Representation,
|
|
23
22
|
} from "../../../manifest";
|
|
23
|
+
import { CancellationSignal } from "../../../utils/task_canceller";
|
|
24
24
|
import SegmentInventory, {
|
|
25
25
|
IBufferedChunk,
|
|
26
26
|
IBufferedHistoryEntry,
|
|
@@ -112,28 +112,41 @@ export abstract class SegmentBuffer {
|
|
|
112
112
|
* `data.chunk` argument to null.
|
|
113
113
|
*
|
|
114
114
|
* @param {Object} infos
|
|
115
|
-
* @
|
|
115
|
+
* @param {Object} cancellationSignal
|
|
116
|
+
* @returns {Promise}
|
|
116
117
|
*/
|
|
117
|
-
public abstract pushChunk(
|
|
118
|
+
public abstract pushChunk(
|
|
119
|
+
infos : IPushChunkInfos<unknown>,
|
|
120
|
+
cancellationSignal : CancellationSignal
|
|
121
|
+
) : Promise<void>;
|
|
118
122
|
|
|
119
123
|
/**
|
|
120
124
|
* Remove buffered data (added to the same FIFO queue than `pushChunk`).
|
|
121
125
|
* @param {number} start - start position, in seconds
|
|
122
126
|
* @param {number} end - end position, in seconds
|
|
123
|
-
* @
|
|
127
|
+
* @param {Object} cancellationSignal
|
|
128
|
+
* @returns {Promise}
|
|
124
129
|
*/
|
|
125
|
-
public abstract removeBuffer(
|
|
130
|
+
public abstract removeBuffer(
|
|
131
|
+
start : number,
|
|
132
|
+
end : number,
|
|
133
|
+
cancellationSignal : CancellationSignal
|
|
134
|
+
) : Promise<void>;
|
|
126
135
|
|
|
127
136
|
/**
|
|
128
137
|
* Indicate that every chunks from a Segment has been given to pushChunk so
|
|
129
138
|
* far.
|
|
130
139
|
* This will update our internal Segment inventory accordingly.
|
|
131
|
-
* The returned
|
|
132
|
-
*
|
|
140
|
+
* The returned Promise will resolve once the whole segment has been pushed
|
|
141
|
+
* and this indication is acknowledged.
|
|
133
142
|
* @param {Object} infos
|
|
134
|
-
* @
|
|
143
|
+
* @param {Object} cancellationSignal
|
|
144
|
+
* @returns {Promise}
|
|
135
145
|
*/
|
|
136
|
-
public abstract endOfSegment(
|
|
146
|
+
public abstract endOfSegment(
|
|
147
|
+
infos : IEndOfSegmentInfos,
|
|
148
|
+
cancellationSignal : CancellationSignal
|
|
149
|
+
) : Promise<void>;
|
|
137
150
|
|
|
138
151
|
/**
|
|
139
152
|
* Returns the currently buffered data, in a TimeRanges object.
|