rx-player 3.29.0-dev.2022103100 → 3.29.0-dev.2022110200
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 -3
- package/VERSION +1 -1
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +5 -0
- package/dist/_esm5.processed/core/api/playback_observer.js +7 -0
- package/dist/_esm5.processed/core/api/public_api.js +2 -2
- package/dist/_esm5.processed/core/init/initialize_directfile.js +3 -8
- package/dist/_esm5.processed/core/init/load_on_media_source.js +3 -11
- package/dist/_esm5.processed/core/init/{stall_avoider.d.ts → rebuffering_controller.d.ts} +5 -2
- package/dist/_esm5.processed/core/init/{stall_avoider.js → rebuffering_controller.js} +93 -4
- package/dist/_esm5.processed/core/init/update_playback_rate.d.ts +0 -32
- package/dist/_esm5.processed/core/init/update_playback_rate.js +1 -46
- package/dist/_esm5.processed/default_config.js +1 -1
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_extent.js +1 -8
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_origin.js +1 -9
- package/dist/rx-player.js +193 -182
- package/dist/rx-player.min.js +1 -1
- package/package.json +1 -1
- package/sonar-project.properties +1 -1
- package/src/core/api/playback_observer.ts +8 -0
- package/src/core/api/public_api.ts +2 -2
- package/src/core/init/initialize_directfile.ts +3 -11
- package/src/core/init/load_on_media_source.ts +12 -23
- package/src/core/init/{stall_avoider.ts → rebuffering_controller.ts} +106 -3
- package/src/core/init/update_playback_rate.ts +0 -70
- package/src/default_config.ts +1 -1
- package/src/parsers/texttracks/ttml/html/apply_extent.ts +1 -8
- package/src/parsers/texttracks/ttml/html/apply_origin.ts +1 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## v3.29.0 (
|
|
3
|
+
## v3.29.0-dev.2022110200 (2022-11-02)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
@@ -22,11 +22,10 @@
|
|
|
22
22
|
- Compat/DRM: Fix infinite loading on WebOS (LG TVs) 2021 and 2022 when loading more than once an encrypted content by resetting decryption capabilities each time [#1175]
|
|
23
23
|
- Compat: To work around an issue on WebOS (LG TVs), also specify a request timeout manually through a `setTimeout` call when XMLHttpRequests are created for Manifest and segment requests [#1152]
|
|
24
24
|
- Compat/Directfile: Fix an issue on Tizen (Samsung TVs) where playing directfile contents could randomly lead to not having audio [#1170]
|
|
25
|
-
- Compat: Fix issue with Tizen (Samsung TVs) where starting playback on a discontinuity could lead to infinite rebuffering [#1140]
|
|
25
|
+
- Compat: Fix issue with Tizen (Samsung TVs) where starting playback on a discontinuity could lead to infinite rebuffering [#1140, #1176]
|
|
26
26
|
- Compat/Directfile: For `"directfile"` contents, also consider `AudioTrack` with a `description` (without an "s") as audio-description audio tracks to work-around what seems to be a Safari typo [#1160]
|
|
27
27
|
- DRM: When using persistent licenses, create new MediaKeySession when `load` resolves with `false`, instead of relying the same, to fix issues with such persistent sessions if the browser cleaned it up [#1139]
|
|
28
28
|
- Only call "MediaSource.endOfStream" once, the most visible side-effect should have been repeated logs [#1163]
|
|
29
|
-
- TTML: put saner values for extent and origins when weird ones are found
|
|
30
29
|
|
|
31
30
|
### Other improvements
|
|
32
31
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.29.0-dev.
|
|
1
|
+
3.29.0-dev.2022110200
|
|
@@ -116,6 +116,11 @@ export default class PlaybackObserver {
|
|
|
116
116
|
* @param {number} time
|
|
117
117
|
*/
|
|
118
118
|
setCurrentTime(time: number): void;
|
|
119
|
+
/**
|
|
120
|
+
* Update the playback rate of the `HTMLMediaElement`.
|
|
121
|
+
* @param {number} playbackRate
|
|
122
|
+
*/
|
|
123
|
+
setPlaybackRate(playbackRate: number): void;
|
|
119
124
|
/**
|
|
120
125
|
* Returns the current `readyState` advertised by the `HTMLMediaElement`.
|
|
121
126
|
* @returns {number}
|
|
@@ -117,6 +117,13 @@ var PlaybackObserver = /** @class */ (function () {
|
|
|
117
117
|
this._internalSeeksIncoming.push(time);
|
|
118
118
|
this._mediaElement.currentTime = time;
|
|
119
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* Update the playback rate of the `HTMLMediaElement`.
|
|
122
|
+
* @param {number} playbackRate
|
|
123
|
+
*/
|
|
124
|
+
PlaybackObserver.prototype.setPlaybackRate = function (playbackRate) {
|
|
125
|
+
this._mediaElement.playbackRate = playbackRate;
|
|
126
|
+
};
|
|
120
127
|
/**
|
|
121
128
|
* Returns the current `readyState` advertised by the `HTMLMediaElement`.
|
|
122
129
|
* @returns {number}
|
|
@@ -87,7 +87,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
87
87
|
// Workaround to support Firefox autoplay on FF 42.
|
|
88
88
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
89
89
|
videoElement.preload = "auto";
|
|
90
|
-
_this.version = /* PLAYER_VERSION */ "3.29.0-dev.
|
|
90
|
+
_this.version = /* PLAYER_VERSION */ "3.29.0-dev.2022110200";
|
|
91
91
|
_this.log = log;
|
|
92
92
|
_this.state = "STOPPED";
|
|
93
93
|
_this.videoElement = videoElement;
|
|
@@ -2312,5 +2312,5 @@ var Player = /** @class */ (function (_super) {
|
|
|
2312
2312
|
};
|
|
2313
2313
|
return Player;
|
|
2314
2314
|
}(EventEmitter));
|
|
2315
|
-
Player.version = /* PLAYER_VERSION */ "3.29.0-dev.
|
|
2315
|
+
Player.version = /* PLAYER_VERSION */ "3.29.0-dev.2022110200";
|
|
2316
2316
|
export default Player;
|
|
@@ -24,9 +24,8 @@ import deferSubscriptions from "../../utils/defer_subscriptions";
|
|
|
24
24
|
import emitLoadedEvent from "./emit_loaded_event";
|
|
25
25
|
import initialSeekAndPlay from "./initial_seek_and_play";
|
|
26
26
|
import linkDrmAndContent from "./link_drm_and_content";
|
|
27
|
-
import
|
|
27
|
+
import RebufferingController from "./rebuffering_controller";
|
|
28
28
|
import throwOnMediaError from "./throw_on_media_error";
|
|
29
|
-
import updatePlaybackRate from "./update_playback_rate";
|
|
30
29
|
// NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
|
|
31
30
|
// first type parameter as `any` instead of the perfectly fine `unknown`,
|
|
32
31
|
// leading to linter issues, as it forbids the usage of `any`.
|
|
@@ -100,15 +99,11 @@ export default function initializeDirectfileContent(_a) {
|
|
|
100
99
|
// through a throwing Observable.
|
|
101
100
|
var mediaError$ = throwOnMediaError(mediaElement);
|
|
102
101
|
var observation$ = playbackObserver.getReference().asObservable();
|
|
103
|
-
// Set the speed set by the user on the media element while pausing a
|
|
104
|
-
// little longer while the buffer is empty.
|
|
105
|
-
var playbackRate$ = updatePlaybackRate(mediaElement, speed, observation$)
|
|
106
|
-
.pipe(ignoreElements());
|
|
107
102
|
/**
|
|
108
103
|
* Observable trying to avoid various stalling situations, emitting "stalled"
|
|
109
104
|
* events when it cannot, as well as "unstalled" events when it get out of one.
|
|
110
105
|
*/
|
|
111
|
-
var
|
|
106
|
+
var rebuffer$ = RebufferingController(playbackObserver, null, speed, EMPTY, EMPTY);
|
|
112
107
|
/**
|
|
113
108
|
* Emit a "loaded" events once the initial play has been performed and the
|
|
114
109
|
* media can begin playback.
|
|
@@ -121,5 +116,5 @@ export default function initializeDirectfileContent(_a) {
|
|
|
121
116
|
}
|
|
122
117
|
return emitLoadedEvent(observation$, mediaElement, null, true);
|
|
123
118
|
}));
|
|
124
|
-
return observableMerge(loadingEvts$, drmEvents$.pipe(ignoreElements()), mediaError$,
|
|
119
|
+
return observableMerge(loadingEvts$, drmEvents$.pipe(ignoreElements()), mediaError$, rebuffer$);
|
|
125
120
|
}
|
|
@@ -25,9 +25,8 @@ import emitLoadedEvent from "./emit_loaded_event";
|
|
|
25
25
|
import { maintainEndOfStream } from "./end_of_stream";
|
|
26
26
|
import initialSeekAndPlay from "./initial_seek_and_play";
|
|
27
27
|
import MediaDurationUpdater from "./media_duration_updater";
|
|
28
|
-
import
|
|
28
|
+
import RebufferingController from "./rebuffering_controller";
|
|
29
29
|
import streamEventsEmitter from "./stream_events_emitter";
|
|
30
|
-
import updatePlaybackRate from "./update_playback_rate";
|
|
31
30
|
/**
|
|
32
31
|
* Returns a function allowing to load or reload the content in arguments into
|
|
33
32
|
* a single or multiple MediaSources.
|
|
@@ -101,18 +100,11 @@ export default function createMediaSourceLoader(_a) {
|
|
|
101
100
|
return observableOf(evt);
|
|
102
101
|
}
|
|
103
102
|
}));
|
|
104
|
-
/**
|
|
105
|
-
* On subscription, keep the playback speed synchronized to the speed set by
|
|
106
|
-
* the user on the media element and force a speed of `0` when the buffer is
|
|
107
|
-
* empty, so it can build back buffer.
|
|
108
|
-
*/
|
|
109
|
-
var playbackRate$ = updatePlaybackRate(mediaElement, speed, observation$)
|
|
110
|
-
.pipe(ignoreElements());
|
|
111
103
|
/**
|
|
112
104
|
* Observable trying to avoid various stalling situations, emitting "stalled"
|
|
113
105
|
* events when it cannot, as well as "unstalled" events when it get out of one.
|
|
114
106
|
*/
|
|
115
|
-
var
|
|
107
|
+
var rebuffer$ = RebufferingController(playbackObserver, manifest, speed, lockedStream$, discontinuityUpdate$);
|
|
116
108
|
/**
|
|
117
109
|
* Emit a "loaded" events once the initial play has been performed and the
|
|
118
110
|
* media can begin playback.
|
|
@@ -123,7 +115,7 @@ export default function createMediaSourceLoader(_a) {
|
|
|
123
115
|
observableOf(evt) :
|
|
124
116
|
emitLoadedEvent(observation$, mediaElement, segmentBuffersStore, false);
|
|
125
117
|
}));
|
|
126
|
-
return observableMerge(loadingEvts$,
|
|
118
|
+
return observableMerge(loadingEvts$, rebuffer$, streams$, contentTimeObserver, streamEvents$).pipe(finalize(function () {
|
|
127
119
|
mediaDurationUpdater.stop();
|
|
128
120
|
// clean-up every created SegmentBuffers
|
|
129
121
|
segmentBuffersStore.disposeAll();
|
|
@@ -63,7 +63,10 @@ export interface IDiscontinuityTimeInfo {
|
|
|
63
63
|
end: number | null;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
|
-
* Monitor
|
|
66
|
+
* Monitor playback, trying to avoid stalling situation.
|
|
67
|
+
* If stopping the player to build buffer is needed, temporarily set the
|
|
68
|
+
* playback rate (i.e. speed) at `0` until enough buffer is available again.
|
|
69
|
+
*
|
|
67
70
|
* Emit "stalled" then "unstalled" respectively when an unavoidable stall is
|
|
68
71
|
* encountered and exited.
|
|
69
72
|
* @param {object} playbackObserver - emit the current playback conditions.
|
|
@@ -75,4 +78,4 @@ export interface IDiscontinuityTimeInfo {
|
|
|
75
78
|
* discontinuities for loaded Period and buffer types.
|
|
76
79
|
* @returns {Observable}
|
|
77
80
|
*/
|
|
78
|
-
export default function
|
|
81
|
+
export default function RebufferingController(playbackObserver: PlaybackObserver, manifest: Manifest | null, speed: IReadOnlySharedReference<number>, lockedStream$: Observable<ILockedStreamEvent>, discontinuityUpdate$: Observable<IDiscontinuityEvent>): Observable<IStalledEvent | IUnstalledEvent | IWarningEvent>;
|
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { ignoreElements, map, merge as observableMerge, scan, tap, withLatestFrom, } from "rxjs";
|
|
16
|
+
import { finalize, ignoreElements, map, merge as observableMerge, scan, tap, withLatestFrom, } from "rxjs";
|
|
17
17
|
import isSeekingApproximate from "../../compat/is_seeking_approximate";
|
|
18
18
|
import config from "../../config";
|
|
19
19
|
import { MediaError } from "../../errors";
|
|
20
20
|
import log from "../../log";
|
|
21
21
|
import { getNextRangeGap } from "../../utils/ranges";
|
|
22
|
+
import TaskCanceller from "../../utils/task_canceller";
|
|
22
23
|
import EVENTS from "../stream/events_generators";
|
|
23
24
|
/**
|
|
24
25
|
* Work-around rounding errors with floating points by setting an acceptable,
|
|
@@ -26,7 +27,10 @@ import EVENTS from "../stream/events_generators";
|
|
|
26
27
|
*/
|
|
27
28
|
var EPSILON = 1 / 60;
|
|
28
29
|
/**
|
|
29
|
-
* Monitor
|
|
30
|
+
* Monitor playback, trying to avoid stalling situation.
|
|
31
|
+
* If stopping the player to build buffer is needed, temporarily set the
|
|
32
|
+
* playback rate (i.e. speed) at `0` until enough buffer is available again.
|
|
33
|
+
*
|
|
30
34
|
* Emit "stalled" then "unstalled" respectively when an unavoidable stall is
|
|
31
35
|
* encountered and exited.
|
|
32
36
|
* @param {object} playbackObserver - emit the current playback conditions.
|
|
@@ -38,7 +42,7 @@ var EPSILON = 1 / 60;
|
|
|
38
42
|
* discontinuities for loaded Period and buffer types.
|
|
39
43
|
* @returns {Observable}
|
|
40
44
|
*/
|
|
41
|
-
export default function
|
|
45
|
+
export default function RebufferingController(playbackObserver, manifest, speed, lockedStream$, discontinuityUpdate$) {
|
|
42
46
|
var initialDiscontinuitiesStore = [];
|
|
43
47
|
/**
|
|
44
48
|
* Emit every known audio and video buffer discontinuities in chronological
|
|
@@ -103,6 +107,7 @@ export default function StallAvoider(playbackObserver, manifest, speed, lockedSt
|
|
|
103
107
|
// This is why we're disabling the eslint rule.
|
|
104
108
|
/* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
|
|
105
109
|
ignoreElements());
|
|
110
|
+
var playbackRateUpdater = new PlaybackRateUpdater(playbackObserver, speed);
|
|
106
111
|
var stall$ = playbackObserver.getReference().asObservable().pipe(withLatestFrom(discontinuitiesStore$), map(function (_a) {
|
|
107
112
|
var _b;
|
|
108
113
|
var observation = _a[0], discontinuitiesStore = _a[1];
|
|
@@ -131,6 +136,12 @@ export default function StallAvoider(playbackObserver, manifest, speed, lockedSt
|
|
|
131
136
|
prevFreezingState = { attemptTimestamp: now };
|
|
132
137
|
}
|
|
133
138
|
if (now - freezing.timestamp > FREEZING_STALLED_DELAY) {
|
|
139
|
+
if (rebuffering === null || ignoredStallTimeStamp !== null) {
|
|
140
|
+
playbackRateUpdater.stopRebuffering();
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
playbackRateUpdater.startRebuffering();
|
|
144
|
+
}
|
|
134
145
|
return { type: "stalled",
|
|
135
146
|
value: "freezing" };
|
|
136
147
|
}
|
|
@@ -139,6 +150,7 @@ export default function StallAvoider(playbackObserver, manifest, speed, lockedSt
|
|
|
139
150
|
prevFreezingState = null;
|
|
140
151
|
}
|
|
141
152
|
if (rebuffering === null) {
|
|
153
|
+
playbackRateUpdater.stopRebuffering();
|
|
142
154
|
if (readyState === 1) {
|
|
143
155
|
// With a readyState set to 1, we should still not be able to play:
|
|
144
156
|
// Return that we're stalled
|
|
@@ -165,6 +177,7 @@ export default function StallAvoider(playbackObserver, manifest, speed, lockedSt
|
|
|
165
177
|
if (ignoredStallTimeStamp !== null) {
|
|
166
178
|
var now = performance.now();
|
|
167
179
|
if (now - ignoredStallTimeStamp < FORCE_DISCONTINUITY_SEEK_DELAY) {
|
|
180
|
+
playbackRateUpdater.stopRebuffering();
|
|
168
181
|
log.debug("Init: letting the device get out of a stall by itself");
|
|
169
182
|
return { type: "stalled",
|
|
170
183
|
value: stalledReason };
|
|
@@ -174,6 +187,7 @@ export default function StallAvoider(playbackObserver, manifest, speed, lockedSt
|
|
|
174
187
|
}
|
|
175
188
|
}
|
|
176
189
|
ignoredStallTimeStamp = null;
|
|
190
|
+
playbackRateUpdater.startRebuffering();
|
|
177
191
|
if (manifest === null) {
|
|
178
192
|
return { type: "stalled",
|
|
179
193
|
value: stalledReason };
|
|
@@ -231,7 +245,10 @@ export default function StallAvoider(playbackObserver, manifest, speed, lockedSt
|
|
|
231
245
|
return { type: "stalled",
|
|
232
246
|
value: stalledReason };
|
|
233
247
|
}));
|
|
234
|
-
return observableMerge(unlock$, stall$)
|
|
248
|
+
return observableMerge(unlock$, stall$)
|
|
249
|
+
.pipe(finalize(function () {
|
|
250
|
+
playbackRateUpdater.dispose();
|
|
251
|
+
}));
|
|
235
252
|
}
|
|
236
253
|
/**
|
|
237
254
|
* @param {Array.<Object>} discontinuitiesStore
|
|
@@ -348,3 +365,75 @@ function generateDiscontinuityError(stalledPosition, seekTo) {
|
|
|
348
365
|
String(stalledPosition) + ", seeked at position " +
|
|
349
366
|
String(seekTo));
|
|
350
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Manage playback speed, allowing to force a playback rate of `0` when
|
|
370
|
+
* rebuffering is wanted.
|
|
371
|
+
*
|
|
372
|
+
* Only one `PlaybackRateUpdater` should be created per HTMLMediaElement.
|
|
373
|
+
* Note that the `PlaybackRateUpdater` reacts to playback event and wanted
|
|
374
|
+
* speed change. You should call its `dispose` method once you don't need it
|
|
375
|
+
* anymore.
|
|
376
|
+
* @class PlaybackRateUpdater
|
|
377
|
+
*/
|
|
378
|
+
var PlaybackRateUpdater = /** @class */ (function () {
|
|
379
|
+
/**
|
|
380
|
+
* Create a new `PlaybackRateUpdater`.
|
|
381
|
+
* @param {Object} playbackObserver
|
|
382
|
+
* @param {Object} speed
|
|
383
|
+
*/
|
|
384
|
+
function PlaybackRateUpdater(playbackObserver, speed) {
|
|
385
|
+
this._speedUpdateCanceller = new TaskCanceller();
|
|
386
|
+
this._isRebuffering = false;
|
|
387
|
+
this._playbackObserver = playbackObserver;
|
|
388
|
+
this._isDisposed = false;
|
|
389
|
+
this._speed = speed;
|
|
390
|
+
this._updateSpeed();
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Force the playback rate to `0`, to start a rebuffering phase.
|
|
394
|
+
*
|
|
395
|
+
* You can call `stopRebuffering` when you want the rebuffering phase to end.
|
|
396
|
+
*/
|
|
397
|
+
PlaybackRateUpdater.prototype.startRebuffering = function () {
|
|
398
|
+
if (this._isRebuffering || this._isDisposed) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
this._isRebuffering = true;
|
|
402
|
+
this._speedUpdateCanceller.cancel();
|
|
403
|
+
log.info("Init: Pause playback to build buffer");
|
|
404
|
+
this._playbackObserver.setPlaybackRate(0);
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* If in a rebuffering phase (during which the playback rate is forced to
|
|
408
|
+
* `0`), exit that phase to apply the wanted playback rate instead.
|
|
409
|
+
*
|
|
410
|
+
* Do nothing if not in a rebuffering phase.
|
|
411
|
+
*/
|
|
412
|
+
PlaybackRateUpdater.prototype.stopRebuffering = function () {
|
|
413
|
+
if (!this._isRebuffering || this._isDisposed) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
this._isRebuffering = false;
|
|
417
|
+
this._speedUpdateCanceller = new TaskCanceller();
|
|
418
|
+
this._updateSpeed();
|
|
419
|
+
};
|
|
420
|
+
/**
|
|
421
|
+
* The `PlaybackRateUpdater` allocate resources to for example listen to
|
|
422
|
+
* wanted speed changes and react to it.
|
|
423
|
+
*
|
|
424
|
+
* Consequently, you should call the `dispose` method, when you don't want the
|
|
425
|
+
* `PlaybackRateUpdater` to have an effect anymore.
|
|
426
|
+
*/
|
|
427
|
+
PlaybackRateUpdater.prototype.dispose = function () {
|
|
428
|
+
this._speedUpdateCanceller.cancel();
|
|
429
|
+
this._isDisposed = true;
|
|
430
|
+
};
|
|
431
|
+
PlaybackRateUpdater.prototype._updateSpeed = function () {
|
|
432
|
+
var _this = this;
|
|
433
|
+
this._speed.onUpdate(function (lastSpeed) {
|
|
434
|
+
log.info("Init: Resume playback speed", lastSpeed);
|
|
435
|
+
_this._playbackObserver.setPlaybackRate(lastSpeed);
|
|
436
|
+
}, { clearSignal: this._speedUpdateCanceller.signal, emitCurrentValue: true });
|
|
437
|
+
};
|
|
438
|
+
return PlaybackRateUpdater;
|
|
439
|
+
}());
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright 2015 CANAL+ Group
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { Observable } from "rxjs";
|
|
17
|
-
import { IReadOnlySharedReference } from "../../utils/reference";
|
|
18
|
-
import { IPlaybackObservation } from "../api";
|
|
19
|
-
export interface IPlaybackRateOptions {
|
|
20
|
-
pauseWhenRebuffering?: boolean;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Manage playback speed.
|
|
24
|
-
* Set playback rate set by the user, pause playback when the player appear to
|
|
25
|
-
* rebuffering and restore the speed once it appears to exit rebuffering status.
|
|
26
|
-
*
|
|
27
|
-
* @param {HTMLMediaElement} mediaElement
|
|
28
|
-
* @param {Observable} speed - last speed set by the user
|
|
29
|
-
* @param {Observable} observation$ - Current playback conditions
|
|
30
|
-
* @returns {Observable}
|
|
31
|
-
*/
|
|
32
|
-
export default function updatePlaybackRate(mediaElement: HTMLMediaElement, speed: IReadOnlySharedReference<number>, observation$: Observable<IPlaybackObservation>): Observable<number>;
|
|
@@ -1,46 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Copyright 2015 CANAL+ Group
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { defer as observableDefer, distinctUntilChanged, map, of as observableOf, startWith, switchMap, tap, } from "rxjs";
|
|
17
|
-
import log from "../../log";
|
|
18
|
-
/**
|
|
19
|
-
* Manage playback speed.
|
|
20
|
-
* Set playback rate set by the user, pause playback when the player appear to
|
|
21
|
-
* rebuffering and restore the speed once it appears to exit rebuffering status.
|
|
22
|
-
*
|
|
23
|
-
* @param {HTMLMediaElement} mediaElement
|
|
24
|
-
* @param {Observable} speed - last speed set by the user
|
|
25
|
-
* @param {Observable} observation$ - Current playback conditions
|
|
26
|
-
* @returns {Observable}
|
|
27
|
-
*/
|
|
28
|
-
export default function updatePlaybackRate(mediaElement, speed, observation$) {
|
|
29
|
-
var forcePause$ = observation$
|
|
30
|
-
.pipe(map(function (observation) { return observation.rebuffering !== null; }), startWith(false), distinctUntilChanged());
|
|
31
|
-
return forcePause$
|
|
32
|
-
.pipe(switchMap(function (shouldForcePause) {
|
|
33
|
-
if (shouldForcePause) {
|
|
34
|
-
return observableDefer(function () {
|
|
35
|
-
log.info("Init: Pause playback to build buffer");
|
|
36
|
-
mediaElement.playbackRate = 0;
|
|
37
|
-
return observableOf(0);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
return speed.asObservable()
|
|
41
|
-
.pipe(tap(function (lastSpeed) {
|
|
42
|
-
log.info("Init: Resume playback speed", lastSpeed);
|
|
43
|
-
mediaElement.playbackRate = lastSpeed;
|
|
44
|
-
}));
|
|
45
|
-
}));
|
|
46
|
-
}
|
|
1
|
+
"use strict";
|
|
@@ -312,7 +312,7 @@ var DEFAULT_CONFIG = {
|
|
|
312
312
|
* small enough so this (arguably rare) situation won't lead to too much
|
|
313
313
|
* waiting time.
|
|
314
314
|
*/
|
|
315
|
-
FORCE_DISCONTINUITY_SEEK_DELAY:
|
|
315
|
+
FORCE_DISCONTINUITY_SEEK_DELAY: 5000,
|
|
316
316
|
/**
|
|
317
317
|
* Ratio used to know if an already loaded segment should be re-buffered.
|
|
318
318
|
* We re-load the given segment if the current one times that ratio is
|
|
@@ -48,14 +48,7 @@ export default function applyExtent(element, extent) {
|
|
|
48
48
|
if (secondExtent[2] === "px" ||
|
|
49
49
|
secondExtent[2] === "%" ||
|
|
50
50
|
secondExtent[2] === "em") {
|
|
51
|
-
|
|
52
|
-
if (secondExtent[2] === "%" && !isNaN(toNum) &&
|
|
53
|
-
(toNum < 0 || toNum > 100)) {
|
|
54
|
-
element.style.width = "80%";
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
element.style.height = secondExtent[1] + secondExtent[2];
|
|
58
|
-
}
|
|
51
|
+
element.style.height = secondExtent[1] + secondExtent[2];
|
|
59
52
|
}
|
|
60
53
|
else if (secondExtent[2] === "c") {
|
|
61
54
|
addClassName(element, "proportional-style");
|
|
@@ -47,15 +47,7 @@ export default function applyOrigin(element, origin) {
|
|
|
47
47
|
if (secondOrigin[2] === "px" ||
|
|
48
48
|
secondOrigin[2] === "%" ||
|
|
49
49
|
secondOrigin[2] === "em") {
|
|
50
|
-
|
|
51
|
-
if (secondOrigin[2] === "%" && !isNaN(toNum) &&
|
|
52
|
-
(toNum < 0 || toNum > 100)) {
|
|
53
|
-
element.style.bottom = "5%";
|
|
54
|
-
element.style.left = "10%";
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
element.style.top = secondOrigin[1] + secondOrigin[2];
|
|
58
|
-
}
|
|
50
|
+
element.style.top = secondOrigin[1] + secondOrigin[2];
|
|
59
51
|
}
|
|
60
52
|
else if (secondOrigin[2] === "c") {
|
|
61
53
|
addClassName(element, "proportional-style");
|