rx-player 3.28.0-dev.2022062000 → 3.28.0-dev.2022063000
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 +2 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/event_listeners.js +1 -1
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +1 -6
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +47 -35
- package/dist/_esm5.processed/core/api/playback_observer.js +120 -117
- package/dist/_esm5.processed/core/api/public_api.d.ts +4 -6
- package/dist/_esm5.processed/core/api/public_api.js +18 -18
- package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +1 -1
- package/dist/_esm5.processed/core/init/create_stream_playback_observer.d.ts +1 -1
- package/dist/_esm5.processed/core/init/create_stream_playback_observer.js +23 -6
- package/dist/_esm5.processed/core/init/initial_seek_and_play.js +3 -3
- 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.js +12 -8
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +5 -4
- package/dist/_esm5.processed/core/stream/period/create_empty_adaptation_stream.js +1 -1
- package/dist/_esm5.processed/core/stream/period/period_stream.js +21 -5
- package/dist/_esm5.processed/core/stream/reload_after_switch.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +1 -1
- package/dist/_esm5.processed/utils/reference.d.ts +2 -2
- package/dist/_esm5.processed/utils/reference.js +5 -4
- package/dist/rx-player.js +250 -198
- package/dist/rx-player.min.js +1 -1
- package/package.json +2 -2
- package/sonar-project.properties +1 -1
- package/src/README.md +84 -68
- package/src/compat/event_listeners.ts +1 -1
- package/src/core/adaptive/adaptive_representation_selector.ts +1 -7
- package/src/core/api/playback_observer.ts +185 -173
- package/src/core/api/public_api.ts +23 -21
- package/src/core/init/content_time_boundaries_observer.ts +1 -1
- package/src/core/init/create_stream_playback_observer.ts +69 -47
- package/src/core/init/initial_seek_and_play.ts +3 -3
- package/src/core/init/initialize_directfile.ts +1 -1
- package/src/core/init/load_on_media_source.ts +1 -1
- package/src/core/init/stall_avoider.ts +12 -9
- package/src/core/stream/orchestrator/stream_orchestrator.ts +5 -4
- package/src/core/stream/period/create_empty_adaptation_stream.ts +1 -1
- package/src/core/stream/period/period_stream.ts +33 -14
- package/src/core/stream/reload_after_switch.ts +1 -1
- package/src/core/stream/representation/append_segment_to_buffer.ts +1 -1
- package/src/core/stream/representation/representation_stream.ts +1 -1
- package/src/utils/reference.ts +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## v3.28.0
|
|
3
|
+
## /v3.28.0-dev.2022063000
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
- After a `RELOADING` state, stay in `PAUSED` if the media element was paused synchronously before the side-effect which triggered the reloading (usually coming from the API) was perform [#1132]
|
|
17
17
|
- Fix issue with `maxVideoBufferSize` setting which could lead to too much data being buffered [#1125]
|
|
18
18
|
- Prevent possibility of requests loops and infinite rebuffering when a pushed segment is always completely and immediately garbage collected by the browser [#1123]
|
|
19
|
+
- DASH: Fix potential rare memory leak when stopping the content after it has reloaded at least once [#1135]
|
|
19
20
|
- DASH: Fix issues that could arise if a segment is calculated to start at a negative position [#1122]
|
|
20
21
|
- DASH: Fix possibility of wrong segments being requested when a SegmentTimeline in a given Period (whose Period@end is set) had an S@r set to `-1` at its end [#1098]
|
|
21
22
|
- DASH: If the first `<S>` has its S@t attribute not set, make as if it is set to `0` [#1118]
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.28.0-dev.
|
|
1
|
+
3.28.0-dev.2022063000
|
|
@@ -132,7 +132,7 @@ function getDocumentVisibilityRef(stopListening) {
|
|
|
132
132
|
var visibilityChangeEvent = isNonEmptyString(prefix) ? prefix + "visibilitychange" :
|
|
133
133
|
"visibilitychange";
|
|
134
134
|
var isHidden = document[hidden];
|
|
135
|
-
var ref = createSharedReference(isHidden);
|
|
135
|
+
var ref = createSharedReference(!isHidden);
|
|
136
136
|
addEventListener(document, visibilityChangeEvent, function () {
|
|
137
137
|
var isVisible = !(document[hidden]);
|
|
138
138
|
ref.setValueIfChanged(isVisible);
|
|
@@ -170,13 +170,8 @@ function getEstimateReference(_a, stopAllEstimates) {
|
|
|
170
170
|
* Only used in very specific scenarios.
|
|
171
171
|
*/
|
|
172
172
|
var guessBasedChooser = new GuessBasedChooser(scoreCalculator, prevEstimate);
|
|
173
|
-
var lastPlaybackObservation;
|
|
174
173
|
// get initial observation for initial estimate
|
|
175
|
-
var
|
|
176
|
-
lastPlaybackObservation = obs;
|
|
177
|
-
}, { includeLastObservation: true });
|
|
178
|
-
unregisterInitial(); // The initial is emitted synchronously, we can now remove it
|
|
179
|
-
// TODO cleaner playbackObserver.getLast() or something?
|
|
174
|
+
var lastPlaybackObservation = playbackObserver.getReference().getValue();
|
|
180
175
|
/** Reference through which estimates are emitted. */
|
|
181
176
|
var innerEstimateRef = createSharedReference(getCurrentEstimate());
|
|
182
177
|
// subscribe to subsequent playback observations
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import
|
|
16
|
+
import noop from "../../utils/noop";
|
|
17
|
+
import { IReadOnlySharedReference } from "../../utils/reference";
|
|
17
18
|
import { CancellationSignal } from "../../utils/task_canceller";
|
|
18
19
|
/**
|
|
19
20
|
* Class allowing to "observe" current playback conditions so the RxPlayer is
|
|
@@ -55,21 +56,36 @@ export default class PlaybackObserver {
|
|
|
55
56
|
*/
|
|
56
57
|
private _internalSeekingEventsIncomingCounter;
|
|
57
58
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* `null` if no observation has been made yet.
|
|
59
|
+
* Stores the last playback observation produced by the `PlaybackObserver`.:
|
|
61
60
|
*/
|
|
62
|
-
private
|
|
61
|
+
private _observationRef;
|
|
63
62
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* `TaskCanceller` allowing to free all resources and stop producing playback
|
|
64
|
+
* observations.
|
|
66
65
|
*/
|
|
67
|
-
private
|
|
66
|
+
private _canceller;
|
|
68
67
|
/**
|
|
68
|
+
* Create a new `PlaybackObserver`, which allows to produce new "playback
|
|
69
|
+
* observations" on various media events and intervals.
|
|
70
|
+
*
|
|
71
|
+
* Note that creating a `PlaybackObserver` lead to the usage of resources,
|
|
72
|
+
* such as event listeners which will only be freed once the `stop` method is
|
|
73
|
+
* called.
|
|
69
74
|
* @param {HTMLMediaElement} mediaElement
|
|
70
75
|
* @param {Object} options
|
|
71
76
|
*/
|
|
72
77
|
constructor(mediaElement: HTMLMediaElement, options: IPlaybackObserverOptions);
|
|
78
|
+
/**
|
|
79
|
+
* Stop the `PlaybackObserver` from emitting playback observations and free all
|
|
80
|
+
* resources reserved to emitting them such as event listeners, intervals and
|
|
81
|
+
* subscribing callbacks.
|
|
82
|
+
*
|
|
83
|
+
* Once `stop` is called, no new playback observation will ever be emitted.
|
|
84
|
+
*
|
|
85
|
+
* Note that it is important to call stop once the `PlaybackObserver` is no
|
|
86
|
+
* more needed to avoid unnecessarily leaking resources.
|
|
87
|
+
*/
|
|
88
|
+
stop(): void;
|
|
73
89
|
/**
|
|
74
90
|
* Returns the current position advertised by the `HTMLMediaElement`, in
|
|
75
91
|
* seconds.
|
|
@@ -101,18 +117,16 @@ export default class PlaybackObserver {
|
|
|
101
117
|
*/
|
|
102
118
|
getReadyState(): number;
|
|
103
119
|
/**
|
|
104
|
-
* Returns an
|
|
105
|
-
*
|
|
120
|
+
* Returns an `IReadOnlySharedReference` storing the last playback observation
|
|
121
|
+
* produced by the `PlaybackObserver` and updated each time a new one is
|
|
122
|
+
* produced.
|
|
106
123
|
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* `subscribe` will receive the same events at the same time.
|
|
110
|
-
* This was done for performance and simplicity reasons.
|
|
124
|
+
* This value can then be for example subscribed to to be notified of future
|
|
125
|
+
* playback observations.
|
|
111
126
|
*
|
|
112
|
-
* @
|
|
113
|
-
* @returns {Observable}
|
|
127
|
+
* @returns {Object}
|
|
114
128
|
*/
|
|
115
|
-
|
|
129
|
+
getReference(): IReadOnlySharedReference<IPlaybackObservation>;
|
|
116
130
|
/**
|
|
117
131
|
* Register a callback so it regularly receives playback observations.
|
|
118
132
|
* @param {Function} cb
|
|
@@ -121,12 +135,11 @@ export default class PlaybackObserver {
|
|
|
121
135
|
* be first emitted synchronously.
|
|
122
136
|
* - `clearSignal`: If set, the callback will be unregistered when this
|
|
123
137
|
* CancellationSignal emits.
|
|
124
|
-
* @returns {Function} - Allows to easily unregister the callback
|
|
125
138
|
*/
|
|
126
139
|
listen(cb: (observation: IPlaybackObservation) => void, options?: {
|
|
127
140
|
includeLastObservation?: boolean | undefined;
|
|
128
141
|
clearSignal?: CancellationSignal | undefined;
|
|
129
|
-
}):
|
|
142
|
+
}): typeof noop | undefined;
|
|
130
143
|
/**
|
|
131
144
|
* Generate a new playback observer which can listen to other
|
|
132
145
|
* properties and which can only be accessed to read observations (e.g.
|
|
@@ -138,15 +151,16 @@ export default class PlaybackObserver {
|
|
|
138
151
|
*
|
|
139
152
|
* As argument, this method takes a function which will allow to produce
|
|
140
153
|
* the new set of properties to be present on each observation.
|
|
141
|
-
* @param {Function}
|
|
154
|
+
* @param {Function} transform
|
|
142
155
|
* @returns {Object}
|
|
143
156
|
*/
|
|
144
|
-
deriveReadOnlyObserver<TDest>(
|
|
157
|
+
deriveReadOnlyObserver<TDest>(transform: (observationRef: IReadOnlySharedReference<IPlaybackObservation>, cancellationSignal: CancellationSignal) => IReadOnlySharedReference<TDest>): IReadOnlyPlaybackObserver<TDest>;
|
|
145
158
|
/**
|
|
146
|
-
* Creates the
|
|
159
|
+
* Creates the `IReadOnlySharedReference` that will generate playback
|
|
160
|
+
* observations.
|
|
147
161
|
* @returns {Observable}
|
|
148
162
|
*/
|
|
149
|
-
private
|
|
163
|
+
private _createSharedReference;
|
|
150
164
|
private _generateInitialObservation;
|
|
151
165
|
}
|
|
152
166
|
/** "Event" that triggered the playback observation. */
|
|
@@ -286,18 +300,16 @@ export interface IReadOnlyPlaybackObserver<TObservationType> {
|
|
|
286
300
|
*/
|
|
287
301
|
getIsPaused(): boolean;
|
|
288
302
|
/**
|
|
289
|
-
* Returns an
|
|
290
|
-
*
|
|
303
|
+
* Returns an `IReadOnlySharedReference` storing the last playback observation
|
|
304
|
+
* produced by the `IReadOnlyPlaybackObserver` and updated each time a new one
|
|
305
|
+
* is produced.
|
|
291
306
|
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
* `subscribe` will receive the same events at the same time.
|
|
295
|
-
* This was done for performance and simplicity reasons.
|
|
307
|
+
* This value can then be for example subscribed to to be notified of future
|
|
308
|
+
* playback observations.
|
|
296
309
|
*
|
|
297
|
-
* @
|
|
298
|
-
* @returns {Observable}
|
|
310
|
+
* @returns {Object}
|
|
299
311
|
*/
|
|
300
|
-
|
|
312
|
+
getReference(): IReadOnlySharedReference<TObservationType>;
|
|
301
313
|
/**
|
|
302
314
|
* Register a callback so it regularly receives playback observations.
|
|
303
315
|
* @param {Function} cb
|
|
@@ -311,16 +323,16 @@ export interface IReadOnlyPlaybackObserver<TObservationType> {
|
|
|
311
323
|
listen(cb: (observation: TObservationType) => void, options?: {
|
|
312
324
|
includeLastObservation?: boolean | undefined;
|
|
313
325
|
clearSignal?: CancellationSignal | undefined;
|
|
314
|
-
}):
|
|
326
|
+
}): void;
|
|
315
327
|
/**
|
|
316
328
|
* Generate a new `IReadOnlyPlaybackObserver` from this one.
|
|
317
329
|
*
|
|
318
330
|
* As argument, this method takes a function which will allow to produce
|
|
319
331
|
* the new set of properties to be present on each observation.
|
|
320
|
-
* @param {Function}
|
|
332
|
+
* @param {Function} transform
|
|
321
333
|
* @returns {Object}
|
|
322
334
|
*/
|
|
323
|
-
deriveReadOnlyObserver<TDest>(
|
|
335
|
+
deriveReadOnlyObserver<TDest>(transform: (observationRef: IReadOnlySharedReference<TObservationType>, cancellationSignal: CancellationSignal) => IReadOnlySharedReference<TDest>): IReadOnlyPlaybackObserver<TDest>;
|
|
324
336
|
}
|
|
325
337
|
export interface IPlaybackObserverOptions {
|
|
326
338
|
withMediaSource: boolean;
|
|
@@ -13,21 +13,13 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
17
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
18
|
-
if (ar || !(i in from)) {
|
|
19
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
20
|
-
ar[i] = from[i];
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
24
|
-
};
|
|
25
|
-
import { defer as observableDefer, fromEvent as observableFromEvent, interval as observableInterval, map, merge as observableMerge, share, shareReplay, skip, startWith, } from "rxjs";
|
|
26
16
|
import config from "../../config";
|
|
27
17
|
import log from "../../log";
|
|
28
18
|
import noop from "../../utils/noop";
|
|
29
19
|
import objectAssign from "../../utils/object_assign";
|
|
30
20
|
import { getRange } from "../../utils/ranges";
|
|
21
|
+
import createSharedReference from "../../utils/reference";
|
|
22
|
+
import TaskCanceller from "../../utils/task_canceller";
|
|
31
23
|
/**
|
|
32
24
|
* HTMLMediaElement Events for which playback observations are calculated and
|
|
33
25
|
* emitted.
|
|
@@ -56,6 +48,12 @@ var SCANNED_MEDIA_ELEMENTS_EVENTS = ["canplay",
|
|
|
56
48
|
*/
|
|
57
49
|
var PlaybackObserver = /** @class */ (function () {
|
|
58
50
|
/**
|
|
51
|
+
* Create a new `PlaybackObserver`, which allows to produce new "playback
|
|
52
|
+
* observations" on various media events and intervals.
|
|
53
|
+
*
|
|
54
|
+
* Note that creating a `PlaybackObserver` lead to the usage of resources,
|
|
55
|
+
* such as event listeners which will only be freed once the `stop` method is
|
|
56
|
+
* called.
|
|
59
57
|
* @param {HTMLMediaElement} mediaElement
|
|
60
58
|
* @param {Object} options
|
|
61
59
|
*/
|
|
@@ -64,9 +62,22 @@ var PlaybackObserver = /** @class */ (function () {
|
|
|
64
62
|
this._mediaElement = mediaElement;
|
|
65
63
|
this._withMediaSource = options.withMediaSource;
|
|
66
64
|
this._lowLatencyMode = options.lowLatencyMode;
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
65
|
+
this._canceller = new TaskCanceller();
|
|
66
|
+
this._observationRef = this._createSharedReference();
|
|
69
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Stop the `PlaybackObserver` from emitting playback observations and free all
|
|
70
|
+
* resources reserved to emitting them such as event listeners, intervals and
|
|
71
|
+
* subscribing callbacks.
|
|
72
|
+
*
|
|
73
|
+
* Once `stop` is called, no new playback observation will ever be emitted.
|
|
74
|
+
*
|
|
75
|
+
* Note that it is important to call stop once the `PlaybackObserver` is no
|
|
76
|
+
* more needed to avoid unnecessarily leaking resources.
|
|
77
|
+
*/
|
|
78
|
+
PlaybackObserver.prototype.stop = function () {
|
|
79
|
+
this._canceller.cancel();
|
|
80
|
+
};
|
|
70
81
|
/**
|
|
71
82
|
* Returns the current position advertised by the `HTMLMediaElement`, in
|
|
72
83
|
* seconds.
|
|
@@ -107,31 +118,17 @@ var PlaybackObserver = /** @class */ (function () {
|
|
|
107
118
|
return this._mediaElement.readyState;
|
|
108
119
|
};
|
|
109
120
|
/**
|
|
110
|
-
* Returns an
|
|
111
|
-
*
|
|
121
|
+
* Returns an `IReadOnlySharedReference` storing the last playback observation
|
|
122
|
+
* produced by the `PlaybackObserver` and updated each time a new one is
|
|
123
|
+
* produced.
|
|
112
124
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* `subscribe` will receive the same events at the same time.
|
|
116
|
-
* This was done for performance and simplicity reasons.
|
|
125
|
+
* This value can then be for example subscribed to to be notified of future
|
|
126
|
+
* playback observations.
|
|
117
127
|
*
|
|
118
|
-
* @
|
|
119
|
-
* @returns {Observable}
|
|
128
|
+
* @returns {Object}
|
|
120
129
|
*/
|
|
121
|
-
PlaybackObserver.prototype.
|
|
122
|
-
|
|
123
|
-
return observableDefer(function () {
|
|
124
|
-
if (_this._observation$ === null || _this._lastObservation === null) {
|
|
125
|
-
_this._lastObservation = _this._generateInitialObservation();
|
|
126
|
-
_this._observation$ = _this._createInnerObservable().pipe(share());
|
|
127
|
-
return _this.observe(includeLastObservation);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
return includeLastObservation ?
|
|
131
|
-
_this._observation$.pipe(startWith(_this._lastObservation)) :
|
|
132
|
-
_this._observation$;
|
|
133
|
-
}
|
|
134
|
-
});
|
|
130
|
+
PlaybackObserver.prototype.getReference = function () {
|
|
131
|
+
return this._observationRef;
|
|
135
132
|
};
|
|
136
133
|
/**
|
|
137
134
|
* Register a callback so it regularly receives playback observations.
|
|
@@ -141,22 +138,16 @@ var PlaybackObserver = /** @class */ (function () {
|
|
|
141
138
|
* be first emitted synchronously.
|
|
142
139
|
* - `clearSignal`: If set, the callback will be unregistered when this
|
|
143
140
|
* CancellationSignal emits.
|
|
144
|
-
* @returns {Function} - Allows to easily unregister the callback
|
|
145
141
|
*/
|
|
146
142
|
PlaybackObserver.prototype.listen = function (cb, options) {
|
|
147
|
-
var _a
|
|
148
|
-
if (((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled) === true) {
|
|
143
|
+
var _a;
|
|
144
|
+
if (this._canceller.isUsed || ((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled) === true) {
|
|
149
145
|
return noop;
|
|
150
146
|
}
|
|
151
|
-
|
|
152
|
-
.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
})) !== null && _d !== void 0 ? _d : noop;
|
|
156
|
-
return function () {
|
|
157
|
-
unregister();
|
|
158
|
-
sub.unsubscribe();
|
|
159
|
-
};
|
|
147
|
+
this._observationRef.onUpdate(cb, {
|
|
148
|
+
clearSignal: options === null || options === void 0 ? void 0 : options.clearSignal,
|
|
149
|
+
emitCurrentValue: options === null || options === void 0 ? void 0 : options.includeLastObservation,
|
|
150
|
+
});
|
|
160
151
|
};
|
|
161
152
|
/**
|
|
162
153
|
* Generate a new playback observer which can listen to other
|
|
@@ -169,63 +160,84 @@ var PlaybackObserver = /** @class */ (function () {
|
|
|
169
160
|
*
|
|
170
161
|
* As argument, this method takes a function which will allow to produce
|
|
171
162
|
* the new set of properties to be present on each observation.
|
|
172
|
-
* @param {Function}
|
|
163
|
+
* @param {Function} transform
|
|
173
164
|
* @returns {Object}
|
|
174
165
|
*/
|
|
175
|
-
PlaybackObserver.prototype.deriveReadOnlyObserver = function (
|
|
176
|
-
return generateReadOnlyObserver(this,
|
|
166
|
+
PlaybackObserver.prototype.deriveReadOnlyObserver = function (transform) {
|
|
167
|
+
return generateReadOnlyObserver(this, transform, this._canceller.signal);
|
|
177
168
|
};
|
|
178
169
|
/**
|
|
179
|
-
* Creates the
|
|
170
|
+
* Creates the `IReadOnlySharedReference` that will generate playback
|
|
171
|
+
* observations.
|
|
180
172
|
* @returns {Observable}
|
|
181
173
|
*/
|
|
182
|
-
PlaybackObserver.prototype.
|
|
174
|
+
PlaybackObserver.prototype._createSharedReference = function () {
|
|
183
175
|
var _this = this;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
176
|
+
if (this._observationRef !== undefined) {
|
|
177
|
+
return this._observationRef;
|
|
178
|
+
}
|
|
179
|
+
var lastObservation;
|
|
180
|
+
var _a = config.getCurrent(), SAMPLING_INTERVAL_MEDIASOURCE = _a.SAMPLING_INTERVAL_MEDIASOURCE, SAMPLING_INTERVAL_LOW_LATENCY = _a.SAMPLING_INTERVAL_LOW_LATENCY, SAMPLING_INTERVAL_NO_MEDIASOURCE = _a.SAMPLING_INTERVAL_NO_MEDIASOURCE;
|
|
181
|
+
var getCurrentObservation = function (event) {
|
|
182
|
+
var tmpEvt = event;
|
|
183
|
+
if (tmpEvt === "seeking" && _this._internalSeekingEventsIncomingCounter > 0) {
|
|
184
|
+
tmpEvt = "internal-seeking";
|
|
185
|
+
_this._internalSeekingEventsIncomingCounter -= 1;
|
|
186
|
+
}
|
|
187
|
+
var _lastObservation = lastObservation !== null && lastObservation !== void 0 ? lastObservation : _this._generateInitialObservation();
|
|
188
|
+
var mediaTimings = getMediaInfos(_this._mediaElement, tmpEvt);
|
|
189
|
+
var internalSeeking = mediaTimings.seeking &&
|
|
190
|
+
// We've just received the event for internally seeking
|
|
191
|
+
(tmpEvt === "internal-seeking" ||
|
|
192
|
+
// or We're still waiting on the previous internal-seek
|
|
193
|
+
(_lastObservation.internalSeeking && tmpEvt !== "seeking"));
|
|
194
|
+
var rebufferingStatus = getRebufferingStatus(_lastObservation, mediaTimings, { lowLatencyMode: _this._lowLatencyMode,
|
|
195
|
+
withMediaSource: _this._withMediaSource });
|
|
196
|
+
var freezingStatus = getFreezingStatus(_lastObservation, mediaTimings);
|
|
197
|
+
var timings = objectAssign({}, { rebuffering: rebufferingStatus,
|
|
198
|
+
freezing: freezingStatus, internalSeeking: internalSeeking }, mediaTimings);
|
|
199
|
+
if (log.hasLevel("DEBUG")) {
|
|
200
|
+
log.debug("API: current media element state tick", "event", timings.event, "position", timings.position, "seeking", timings.seeking, "internalSeeking", timings.internalSeeking, "rebuffering", timings.rebuffering !== null, "freezing", timings.freezing !== null, "ended", timings.ended, "paused", timings.paused, "playbackRate", timings.playbackRate, "readyState", timings.readyState);
|
|
201
|
+
}
|
|
202
|
+
return timings;
|
|
203
|
+
};
|
|
204
|
+
var returnedSharedReference = createSharedReference(getCurrentObservation("init"));
|
|
205
|
+
var generateObservationForEvent = function (event) {
|
|
206
|
+
var newObservation = getCurrentObservation(event);
|
|
207
|
+
if (log.hasLevel("DEBUG")) {
|
|
208
|
+
log.debug("API: current playback timeline:\n" +
|
|
209
|
+
prettyPrintBuffered(newObservation.buffered, newObservation.position), "\n".concat(event));
|
|
210
|
+
}
|
|
211
|
+
lastObservation = newObservation;
|
|
212
|
+
returnedSharedReference.setValue(newObservation);
|
|
213
|
+
};
|
|
214
|
+
var interval = this._lowLatencyMode ? SAMPLING_INTERVAL_LOW_LATENCY :
|
|
215
|
+
this._withMediaSource ? SAMPLING_INTERVAL_MEDIASOURCE :
|
|
216
|
+
SAMPLING_INTERVAL_NO_MEDIASOURCE;
|
|
217
|
+
var intervalId = setInterval(onInterval, interval);
|
|
218
|
+
var removeEventListeners = SCANNED_MEDIA_ELEMENTS_EVENTS.map(function (eventName) {
|
|
219
|
+
_this._mediaElement.addEventListener(eventName, onMediaEvent);
|
|
220
|
+
function onMediaEvent() {
|
|
221
|
+
restartInterval();
|
|
222
|
+
generateObservationForEvent(eventName);
|
|
223
|
+
}
|
|
224
|
+
return function () {
|
|
225
|
+
_this._mediaElement.removeEventListener(eventName, onMediaEvent);
|
|
209
226
|
};
|
|
210
|
-
var eventObs = SCANNED_MEDIA_ELEMENTS_EVENTS.map(function (eventName) {
|
|
211
|
-
return observableFromEvent(_this._mediaElement, eventName)
|
|
212
|
-
.pipe(map(function () { return eventName; }));
|
|
213
|
-
});
|
|
214
|
-
var interval = _this._lowLatencyMode ? SAMPLING_INTERVAL_LOW_LATENCY :
|
|
215
|
-
_this._withMediaSource ? SAMPLING_INTERVAL_MEDIASOURCE :
|
|
216
|
-
SAMPLING_INTERVAL_NO_MEDIASOURCE;
|
|
217
|
-
var interval$ = observableInterval(interval)
|
|
218
|
-
.pipe(map(function () { return "timeupdate"; }));
|
|
219
|
-
return observableMerge.apply(void 0, __spreadArray([interval$], eventObs, false)).pipe(map(function (event) {
|
|
220
|
-
var newObservation = getCurrentObservation(event);
|
|
221
|
-
if (log.hasLevel("DEBUG")) {
|
|
222
|
-
log.debug("API: current playback timeline:\n" +
|
|
223
|
-
prettyPrintBuffered(newObservation.buffered, newObservation.position), "\n".concat(event));
|
|
224
|
-
}
|
|
225
|
-
_this._lastObservation = newObservation;
|
|
226
|
-
return newObservation;
|
|
227
|
-
}));
|
|
228
227
|
});
|
|
228
|
+
this._canceller.signal.register(function () {
|
|
229
|
+
clearInterval(intervalId);
|
|
230
|
+
removeEventListeners.forEach(function (cb) { return cb(); });
|
|
231
|
+
returnedSharedReference.finish();
|
|
232
|
+
});
|
|
233
|
+
return returnedSharedReference;
|
|
234
|
+
function onInterval() {
|
|
235
|
+
generateObservationForEvent("timeupdate");
|
|
236
|
+
}
|
|
237
|
+
function restartInterval() {
|
|
238
|
+
clearInterval(intervalId);
|
|
239
|
+
intervalId = setInterval(onInterval, interval);
|
|
240
|
+
}
|
|
229
241
|
};
|
|
230
242
|
PlaybackObserver.prototype._generateInitialObservation = function () {
|
|
231
243
|
return objectAssign(getMediaInfos(this._mediaElement, "init"), { rebuffering: null,
|
|
@@ -480,13 +492,11 @@ function prettyPrintBuffered(buffered, currentTime) {
|
|
|
480
492
|
* Create `IReadOnlyPlaybackObserver` from a source `IReadOnlyPlaybackObserver`
|
|
481
493
|
* and a mapping function.
|
|
482
494
|
* @param {Object} src
|
|
483
|
-
* @param {Function}
|
|
495
|
+
* @param {Function} transform
|
|
484
496
|
* @returns {Object}
|
|
485
497
|
*/
|
|
486
|
-
function generateReadOnlyObserver(src,
|
|
487
|
-
var
|
|
488
|
-
return mapObservable(src.observe(true));
|
|
489
|
-
}).pipe(shareReplay({ bufferSize: 1, refCount: true }));
|
|
498
|
+
function generateReadOnlyObserver(src, transform, cancellationSignal) {
|
|
499
|
+
var mappedRef = transform(src.getReference(), cancellationSignal);
|
|
490
500
|
return {
|
|
491
501
|
getCurrentTime: function () {
|
|
492
502
|
return src.getCurrentTime();
|
|
@@ -497,28 +507,21 @@ function generateReadOnlyObserver(src, mapObservable) {
|
|
|
497
507
|
getIsPaused: function () {
|
|
498
508
|
return src.getIsPaused();
|
|
499
509
|
},
|
|
500
|
-
|
|
501
|
-
return
|
|
502
|
-
newObs.pipe(skip(1));
|
|
510
|
+
getReference: function () {
|
|
511
|
+
return mappedRef;
|
|
503
512
|
},
|
|
504
513
|
listen: function (cb, options) {
|
|
505
|
-
var _a
|
|
506
|
-
if (((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled) === true) {
|
|
507
|
-
return
|
|
514
|
+
var _a;
|
|
515
|
+
if (cancellationSignal.isCancelled || ((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled) === true) {
|
|
516
|
+
return;
|
|
508
517
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
sub.unsubscribe();
|
|
514
|
-
})) !== null && _c !== void 0 ? _c : noop;
|
|
515
|
-
return function () {
|
|
516
|
-
unregister();
|
|
517
|
-
sub.unsubscribe();
|
|
518
|
-
};
|
|
518
|
+
mappedRef.onUpdate(cb, {
|
|
519
|
+
clearSignal: options === null || options === void 0 ? void 0 : options.clearSignal,
|
|
520
|
+
emitCurrentValue: options === null || options === void 0 ? void 0 : options.includeLastObservation,
|
|
521
|
+
});
|
|
519
522
|
},
|
|
520
|
-
deriveReadOnlyObserver: function (
|
|
521
|
-
return generateReadOnlyObserver(this,
|
|
523
|
+
deriveReadOnlyObserver: function (newTransformFn) {
|
|
524
|
+
return generateReadOnlyObserver(this, newTransformFn, cancellationSignal);
|
|
522
525
|
},
|
|
523
526
|
};
|
|
524
527
|
}
|
|
@@ -29,7 +29,10 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
29
29
|
static version: string;
|
|
30
30
|
/** Current version of the RxPlayer. */
|
|
31
31
|
readonly version: string;
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Media element attached to the RxPlayer.
|
|
34
|
+
* Set to `null` when the RxPlayer is disposed.
|
|
35
|
+
*/
|
|
33
36
|
videoElement: HTMLMediaElement | null;
|
|
34
37
|
/** Logger the RxPlayer uses. */
|
|
35
38
|
readonly log: Logger;
|
|
@@ -693,11 +696,6 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
693
696
|
* @param {Error} error
|
|
694
697
|
*/
|
|
695
698
|
private _priv_onPlaybackError;
|
|
696
|
-
/**
|
|
697
|
-
* Triggered when the playback Observable completes.
|
|
698
|
-
* Clean-up ressources and signal that the content has ended.
|
|
699
|
-
*/
|
|
700
|
-
private _priv_onPlaybackFinished;
|
|
701
699
|
/**
|
|
702
700
|
* Triggered when we received a warning event during playback.
|
|
703
701
|
* Trigger the right API event.
|
|
@@ -88,7 +88,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
88
88
|
// Workaround to support Firefox autoplay on FF 42.
|
|
89
89
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
90
90
|
videoElement.preload = "auto";
|
|
91
|
-
_this.version = /* PLAYER_VERSION */ "3.28.0-dev.
|
|
91
|
+
_this.version = /* PLAYER_VERSION */ "3.28.0-dev.2022063000";
|
|
92
92
|
_this.log = log;
|
|
93
93
|
_this.state = "STOPPED";
|
|
94
94
|
_this.videoElement = videoElement;
|
|
@@ -359,6 +359,9 @@ var Player = /** @class */ (function (_super) {
|
|
|
359
359
|
withMediaSource: !isDirectFile,
|
|
360
360
|
lowLatencyMode: lowLatencyMode,
|
|
361
361
|
});
|
|
362
|
+
currentContentCanceller.signal.register(function () {
|
|
363
|
+
playbackObserver.stop();
|
|
364
|
+
});
|
|
362
365
|
/** Emit playback events. */
|
|
363
366
|
var playback$;
|
|
364
367
|
if (!isDirectFile) {
|
|
@@ -534,7 +537,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
534
537
|
return evt.type === "reloading-media-source";
|
|
535
538
|
}), share());
|
|
536
539
|
/** Emit when the media element emits a "seeking" event. */
|
|
537
|
-
var observation$ = playbackObserver.
|
|
540
|
+
var observation$ = playbackObserver.getReference().asObservable();
|
|
538
541
|
var stateChangingEvent$ = observation$.pipe(filter(function (o) {
|
|
539
542
|
return o.event === "seeking" || o.event === "ended" ||
|
|
540
543
|
o.event === "play" || o.event === "pause";
|
|
@@ -598,7 +601,14 @@ var Player = /** @class */ (function (_super) {
|
|
|
598
601
|
playback$.subscribe({
|
|
599
602
|
next: function (x) { return _this._priv_onPlaybackEvent(x); },
|
|
600
603
|
error: function (err) { return _this._priv_onPlaybackError(err); },
|
|
601
|
-
complete: function () {
|
|
604
|
+
complete: function () {
|
|
605
|
+
if (!contentInfos.currentContentCanceller.isUsed) {
|
|
606
|
+
log.info("API: Previous playback finished. Stopping and cleaning-up...");
|
|
607
|
+
contentInfos.currentContentCanceller.cancel();
|
|
608
|
+
_this._priv_cleanUpCurrentContentState();
|
|
609
|
+
_this._priv_setPlayerState(PLAYER_STATES.STOPPED);
|
|
610
|
+
}
|
|
611
|
+
},
|
|
602
612
|
});
|
|
603
613
|
// initialize the content only when the lock is inactive
|
|
604
614
|
this._priv_contentLock.asObservable()
|
|
@@ -1758,8 +1768,10 @@ var Player = /** @class */ (function (_super) {
|
|
|
1758
1768
|
this._priv_contentEventsMemory = {};
|
|
1759
1769
|
// DRM-related clean-up
|
|
1760
1770
|
var freeUpContentLock = function () {
|
|
1761
|
-
|
|
1762
|
-
|
|
1771
|
+
if (_this.videoElement !== null) { // If not disposed
|
|
1772
|
+
log.debug("Unlocking `contentLock`. Next content can begin.");
|
|
1773
|
+
_this._priv_contentLock.setValue(false);
|
|
1774
|
+
}
|
|
1763
1775
|
};
|
|
1764
1776
|
if (!isNullOrUndefined(this.videoElement)) {
|
|
1765
1777
|
clearOnStop(this.videoElement).then(function () {
|
|
@@ -1878,18 +1890,6 @@ var Player = /** @class */ (function (_super) {
|
|
|
1878
1890
|
this.trigger("error", formattedError);
|
|
1879
1891
|
}
|
|
1880
1892
|
};
|
|
1881
|
-
/**
|
|
1882
|
-
* Triggered when the playback Observable completes.
|
|
1883
|
-
* Clean-up ressources and signal that the content has ended.
|
|
1884
|
-
*/
|
|
1885
|
-
Player.prototype._priv_onPlaybackFinished = function () {
|
|
1886
|
-
log.info("API: Previous playback finished. Stopping and cleaning-up...");
|
|
1887
|
-
if (this._priv_contentInfos !== null) {
|
|
1888
|
-
this._priv_contentInfos.currentContentCanceller.cancel();
|
|
1889
|
-
}
|
|
1890
|
-
this._priv_cleanUpCurrentContentState();
|
|
1891
|
-
this._priv_setPlayerState(PLAYER_STATES.ENDED);
|
|
1892
|
-
};
|
|
1893
1893
|
/**
|
|
1894
1894
|
* Triggered when we received a warning event during playback.
|
|
1895
1895
|
* Trigger the right API event.
|
|
@@ -2295,5 +2295,5 @@ var Player = /** @class */ (function (_super) {
|
|
|
2295
2295
|
};
|
|
2296
2296
|
return Player;
|
|
2297
2297
|
}(EventEmitter));
|
|
2298
|
-
Player.version = /* PLAYER_VERSION */ "3.28.0-dev.
|
|
2298
|
+
Player.version = /* PLAYER_VERSION */ "3.28.0-dev.2022063000";
|
|
2299
2299
|
export default Player;
|
|
@@ -45,7 +45,7 @@ export default function ContentTimeBoundariesObserver(manifest, streams, playbac
|
|
|
45
45
|
var maximumPositionCalculator = new MaximumPositionCalculator(manifest);
|
|
46
46
|
// trigger warnings when the wanted time is before or after the manifest's
|
|
47
47
|
// segments
|
|
48
|
-
var outOfManifest$ = playbackObserver.
|
|
48
|
+
var outOfManifest$ = playbackObserver.getReference().asObservable().pipe(filterMap(function (_a) {
|
|
49
49
|
var _b;
|
|
50
50
|
var position = _a.position;
|
|
51
51
|
var wantedPosition = (_b = position.pending) !== null && _b !== void 0 ? _b : position.last;
|