rx-player 3.31.0-dev.2023052200 → 3.31.0
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 +3 -3
- package/VERSION +1 -1
- package/dist/_esm5.processed/core/api/public_api.d.ts +32 -0
- package/dist/_esm5.processed/core/api/public_api.js +92 -4
- package/dist/_esm5.processed/core/api/utils.d.ts +10 -0
- package/dist/_esm5.processed/core/api/utils.js +20 -0
- package/dist/_esm5.processed/core/decrypt/session_events_listener.js +7 -1
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +1 -1
- package/dist/_esm5.processed/core/init/types.d.ts +9 -1
- package/dist/rx-player.js +1015 -896
- package/dist/rx-player.min.js +1 -1
- package/package.json +31 -31
- package/scripts/build/generate_build.js +1 -1
- package/scripts/fast_demo_build.js +3 -2
- package/sonar-project.properties +1 -1
- package/src/core/api/public_api.ts +108 -4
- package/src/core/api/utils.ts +26 -0
- package/src/core/decrypt/session_events_listener.ts +6 -1
- package/src/core/init/media_source_content_initializer.ts +1 -1
- package/src/core/init/types.ts +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## v3.31.0
|
|
3
|
+
## v3.31.0 (2023-06-14)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
7
|
+
- Add `isContentLoaded`, `isBuffering`, `isPaused`, and `getLastStoredContentPosition` methods [#1248]
|
|
8
|
+
- Add `play` and `paused` events [#1253]
|
|
7
9
|
- Add `trackInfo` property to some `MediaError` to expose information on the track that caused the error [#1241]
|
|
8
10
|
|
|
9
11
|
### Bug fixes
|
|
@@ -12,13 +14,11 @@
|
|
|
12
14
|
- Return actual ending duration through the `getVideoDuration` method when playing dynamic contents whose future end is already known [#1235]
|
|
13
15
|
- DASH/WASM: actually reject the `DASH_WASM.initialize`'s Promise if it fails [#1238]
|
|
14
16
|
- On the PlayStation 5, set `Infinity` MediaSource duration for live contents to prevent playback issues [#1250]
|
|
15
|
-
- DASH/WASM: actually reject the DASH_WASM.initialize's Promise if it fails [#1238]
|
|
16
17
|
|
|
17
18
|
### Other improvements
|
|
18
19
|
|
|
19
20
|
- adaptive: Perform various adaptive tweaks to avoid switching too much between qualities in some conditions [#1237]
|
|
20
21
|
- Directfile: Detect "forced" subtitles on Safari when playing directfile contents (such as HLS) [#1239]
|
|
21
|
-
- DRM: Reload when playback is unexpectedly frozen with encrypted but only decipherable data in the buffer [#1236]
|
|
22
22
|
- Improve `"direct"` `audioTrackSwitchingMode` compatibility by re-seeking [#1246]
|
|
23
23
|
- The `DEBUG_ELEMENT` feature now uses the `monospace` fallback font as a default for a better rendering on apple devices
|
|
24
24
|
- doc: externalize documentation-generator code
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.31.0
|
|
1
|
+
3.31.0
|
|
@@ -105,6 +105,10 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
105
105
|
* It should refer to the last content being played.
|
|
106
106
|
*/
|
|
107
107
|
private _priv_reloadingMetadata;
|
|
108
|
+
/**
|
|
109
|
+
* Store last value of autoPlay, from the last load or reload.
|
|
110
|
+
*/
|
|
111
|
+
private _priv_lastAutoPlay;
|
|
108
112
|
/** All possible Error types emitted by the RxPlayer. */
|
|
109
113
|
static get ErrorTypes(): Record<IErrorType, IErrorType>;
|
|
110
114
|
/** All possible Error codes emitted by the RxPlayer. */
|
|
@@ -217,6 +221,26 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
217
221
|
* @returns {string} - The current Player's state
|
|
218
222
|
*/
|
|
219
223
|
getPlayerState(): string;
|
|
224
|
+
/**
|
|
225
|
+
* Returns true if a content is loaded.
|
|
226
|
+
* @returns {Boolean} - `true` if a content is loaded, `false` otherwise.
|
|
227
|
+
*/
|
|
228
|
+
isContentLoaded(): boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Returns true if the player is buffering.
|
|
231
|
+
* @returns {Boolean} - `true` if the player is buffering, `false` otherwise.
|
|
232
|
+
*/
|
|
233
|
+
isBuffering(): boolean;
|
|
234
|
+
/**
|
|
235
|
+
* Returns the play/pause status of the player :
|
|
236
|
+
* - when `LOADING` or `RELOADING`, returns the scheduled play/pause condition
|
|
237
|
+
* for when loading is over,
|
|
238
|
+
* - in other states, returns the `<video>` element .paused value,
|
|
239
|
+
* - if the player is disposed, returns `true`.
|
|
240
|
+
* @returns {Boolean} - `true` if the player is paused or will be after loading,
|
|
241
|
+
* `false` otherwise.
|
|
242
|
+
*/
|
|
243
|
+
isPaused(): boolean;
|
|
220
244
|
/**
|
|
221
245
|
* Returns true if both:
|
|
222
246
|
* - a content is loaded
|
|
@@ -303,6 +327,12 @@ declare class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
303
327
|
* @returns {Number}
|
|
304
328
|
*/
|
|
305
329
|
getPosition(): number;
|
|
330
|
+
/**
|
|
331
|
+
* Returns the last stored content position, in seconds.
|
|
332
|
+
*
|
|
333
|
+
* @returns {number|undefined}
|
|
334
|
+
*/
|
|
335
|
+
getLastStoredContentPosition(): number | undefined;
|
|
306
336
|
/**
|
|
307
337
|
* Returns the current playback rate at which the video plays.
|
|
308
338
|
* @returns {Number}
|
|
@@ -832,6 +862,8 @@ interface IPublicAPIEvent {
|
|
|
832
862
|
availableTextTracksChange: IAvailableTextTrack[];
|
|
833
863
|
availableVideoTracksChange: IAvailableVideoTrack[];
|
|
834
864
|
decipherabilityUpdate: IDecipherabilityUpdateContent[];
|
|
865
|
+
play: null;
|
|
866
|
+
pause: null;
|
|
835
867
|
seeking: null;
|
|
836
868
|
seeked: null;
|
|
837
869
|
streamEvent: IStreamEvent;
|
|
@@ -51,6 +51,7 @@ import { ErrorCodes, ErrorTypes, formatError, MediaError, } from "../../errors";
|
|
|
51
51
|
import features from "../../features";
|
|
52
52
|
import log from "../../log";
|
|
53
53
|
import areArraysOfNumbersEqual from "../../utils/are_arrays_of_numbers_equal";
|
|
54
|
+
import arrayIncludes from "../../utils/array_includes";
|
|
54
55
|
import assert from "../../utils/assert";
|
|
55
56
|
import EventEmitter from "../../utils/event_emitter";
|
|
56
57
|
import idGenerator from "../../utils/id_generator";
|
|
@@ -65,7 +66,7 @@ import MediaSourceContentInitializer from "../init/media_source_content_initiali
|
|
|
65
66
|
import { checkReloadOptions, parseConstructorOptions, parseLoadVideoOptions, } from "./option_utils";
|
|
66
67
|
import PlaybackObserver from "./playback_observer";
|
|
67
68
|
import TrackChoiceManager from "./tracks_management/track_choice_manager";
|
|
68
|
-
import { constructPlayerStateReference, emitSeekEvents, isLoadedState, } from "./utils";
|
|
69
|
+
import { constructPlayerStateReference, emitPlayPauseEvents, emitSeekEvents, isLoadedState, } from "./utils";
|
|
69
70
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
70
71
|
var generateContentId = idGenerator();
|
|
71
72
|
var getPageActivityRef = events.getPageActivityRef, getPictureOnPictureStateRef = events.getPictureOnPictureStateRef, getVideoVisibilityRef = events.getVideoVisibilityRef, getVideoWidthRef = events.getVideoWidthRef, onFullscreenChange = events.onFullscreenChange, onTextTrackAdded = events.onTextTrackAdded, onTextTrackRemoved = events.onTextTrackRemoved;
|
|
@@ -89,7 +90,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
89
90
|
// Workaround to support Firefox autoplay on FF 42.
|
|
90
91
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
91
92
|
videoElement.preload = "auto";
|
|
92
|
-
_this.version = /* PLAYER_VERSION */ "3.31.0
|
|
93
|
+
_this.version = /* PLAYER_VERSION */ "3.31.0";
|
|
93
94
|
_this.log = log;
|
|
94
95
|
_this.state = "STOPPED";
|
|
95
96
|
_this.videoElement = videoElement;
|
|
@@ -172,6 +173,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
172
173
|
_this._priv_preferredTextTracks = preferredTextTracks;
|
|
173
174
|
_this._priv_preferredVideoTracks = preferredVideoTracks;
|
|
174
175
|
_this._priv_reloadingMetadata = {};
|
|
176
|
+
_this._priv_lastAutoPlay = false;
|
|
175
177
|
return _this;
|
|
176
178
|
}
|
|
177
179
|
Object.defineProperty(Player, "ErrorTypes", {
|
|
@@ -269,6 +271,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
269
271
|
log.info("API: Calling loadvideo", options.url, options.transport);
|
|
270
272
|
this._priv_reloadingMetadata = { options: options };
|
|
271
273
|
this._priv_initializeContentPlayback(options);
|
|
274
|
+
this._priv_lastAutoPlay = options.autoPlay;
|
|
272
275
|
};
|
|
273
276
|
/**
|
|
274
277
|
* Reload the last loaded content.
|
|
@@ -485,11 +488,12 @@ var Player = /** @class */ (function (_super) {
|
|
|
485
488
|
log.warn("API: Sending warning:", formattedError);
|
|
486
489
|
_this.trigger("warning", formattedError);
|
|
487
490
|
});
|
|
488
|
-
initializer.addEventListener("reloadingMediaSource", function () {
|
|
491
|
+
initializer.addEventListener("reloadingMediaSource", function (payload) {
|
|
489
492
|
contentInfos.segmentBuffersStore = null;
|
|
490
493
|
if (contentInfos.trackChoiceManager !== null) {
|
|
491
494
|
contentInfos.trackChoiceManager.resetPeriods();
|
|
492
495
|
}
|
|
496
|
+
_this._priv_lastAutoPlay = payload.autoPlay;
|
|
493
497
|
});
|
|
494
498
|
initializer.addEventListener("inbandEvents", function (inbandEvents) {
|
|
495
499
|
return _this.trigger("inbandEvents", inbandEvents);
|
|
@@ -591,6 +595,48 @@ var Player = /** @class */ (function (_super) {
|
|
|
591
595
|
break;
|
|
592
596
|
}
|
|
593
597
|
};
|
|
598
|
+
/**
|
|
599
|
+
* `TaskCanceller` allowing to stop emitting `"play"` and `"pause"`
|
|
600
|
+
* events.
|
|
601
|
+
* `null` when such events are not emitted currently.
|
|
602
|
+
*/
|
|
603
|
+
var playPauseEventsCanceller = null;
|
|
604
|
+
/**
|
|
605
|
+
* Callback emitting `"play"` and `"pause`" events once the content is
|
|
606
|
+
* loaded, starting from the state indicated in argument.
|
|
607
|
+
* @param {boolean} willAutoPlay - If `false`, we're currently paused.
|
|
608
|
+
*/
|
|
609
|
+
var triggerPlayPauseEventsWhenReady = function (willAutoPlay) {
|
|
610
|
+
if (playPauseEventsCanceller !== null) {
|
|
611
|
+
playPauseEventsCanceller.cancel(); // cancel previous logic
|
|
612
|
+
playPauseEventsCanceller = null;
|
|
613
|
+
}
|
|
614
|
+
playerStateRef.onUpdate(function (val, stopListeningToStateUpdates) {
|
|
615
|
+
if (!isLoadedState(val)) {
|
|
616
|
+
return; // content not loaded yet: no event
|
|
617
|
+
}
|
|
618
|
+
stopListeningToStateUpdates();
|
|
619
|
+
if (playPauseEventsCanceller !== null) {
|
|
620
|
+
playPauseEventsCanceller.cancel();
|
|
621
|
+
}
|
|
622
|
+
playPauseEventsCanceller = new TaskCanceller();
|
|
623
|
+
playPauseEventsCanceller.linkToSignal(currentContentCanceller.signal);
|
|
624
|
+
if (willAutoPlay !== !videoElement.paused) {
|
|
625
|
+
// paused status is not at the expected value on load: emit event
|
|
626
|
+
if (videoElement.paused) {
|
|
627
|
+
_this.trigger("pause", null);
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
_this.trigger("play", null);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
emitPlayPauseEvents(videoElement, function () { return _this.trigger("play", null); }, function () { return _this.trigger("pause", null); }, currentContentCanceller.signal);
|
|
634
|
+
}, { emitCurrentValue: false, clearSignal: currentContentCanceller.signal });
|
|
635
|
+
};
|
|
636
|
+
triggerPlayPauseEventsWhenReady(autoPlay);
|
|
637
|
+
initializer.addEventListener("reloadingMediaSource", function (payload) {
|
|
638
|
+
triggerPlayPauseEventsWhenReady(payload.autoPlay);
|
|
639
|
+
});
|
|
594
640
|
/**
|
|
595
641
|
* `TaskCanceller` allowing to stop emitting `"seeking"` and `"seeked"`
|
|
596
642
|
* events.
|
|
@@ -732,6 +778,40 @@ var Player = /** @class */ (function (_super) {
|
|
|
732
778
|
Player.prototype.getPlayerState = function () {
|
|
733
779
|
return this.state;
|
|
734
780
|
};
|
|
781
|
+
/**
|
|
782
|
+
* Returns true if a content is loaded.
|
|
783
|
+
* @returns {Boolean} - `true` if a content is loaded, `false` otherwise.
|
|
784
|
+
*/
|
|
785
|
+
Player.prototype.isContentLoaded = function () {
|
|
786
|
+
return !arrayIncludes(["LOADING", "RELOADING", "STOPPED"], this.state);
|
|
787
|
+
};
|
|
788
|
+
/**
|
|
789
|
+
* Returns true if the player is buffering.
|
|
790
|
+
* @returns {Boolean} - `true` if the player is buffering, `false` otherwise.
|
|
791
|
+
*/
|
|
792
|
+
Player.prototype.isBuffering = function () {
|
|
793
|
+
return arrayIncludes(["BUFFERING", "SEEKING", "LOADING", "RELOADING"], this.state);
|
|
794
|
+
};
|
|
795
|
+
/**
|
|
796
|
+
* Returns the play/pause status of the player :
|
|
797
|
+
* - when `LOADING` or `RELOADING`, returns the scheduled play/pause condition
|
|
798
|
+
* for when loading is over,
|
|
799
|
+
* - in other states, returns the `<video>` element .paused value,
|
|
800
|
+
* - if the player is disposed, returns `true`.
|
|
801
|
+
* @returns {Boolean} - `true` if the player is paused or will be after loading,
|
|
802
|
+
* `false` otherwise.
|
|
803
|
+
*/
|
|
804
|
+
Player.prototype.isPaused = function () {
|
|
805
|
+
if (this.videoElement) {
|
|
806
|
+
if (arrayIncludes(["LOADING", "RELOADING"], this.state)) {
|
|
807
|
+
return !this._priv_lastAutoPlay;
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
810
|
+
return this.videoElement.paused;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
return true;
|
|
814
|
+
};
|
|
735
815
|
/**
|
|
736
816
|
* Returns true if both:
|
|
737
817
|
* - a content is loaded
|
|
@@ -897,6 +977,14 @@ var Player = /** @class */ (function (_super) {
|
|
|
897
977
|
}
|
|
898
978
|
return this.videoElement.currentTime;
|
|
899
979
|
};
|
|
980
|
+
/**
|
|
981
|
+
* Returns the last stored content position, in seconds.
|
|
982
|
+
*
|
|
983
|
+
* @returns {number|undefined}
|
|
984
|
+
*/
|
|
985
|
+
Player.prototype.getLastStoredContentPosition = function () {
|
|
986
|
+
return this._priv_reloadingMetadata.reloadPosition;
|
|
987
|
+
};
|
|
900
988
|
/**
|
|
901
989
|
* Returns the current playback rate at which the video plays.
|
|
902
990
|
* @returns {Number}
|
|
@@ -2340,5 +2428,5 @@ var Player = /** @class */ (function (_super) {
|
|
|
2340
2428
|
};
|
|
2341
2429
|
return Player;
|
|
2342
2430
|
}(EventEmitter));
|
|
2343
|
-
Player.version = /* PLAYER_VERSION */ "3.31.0
|
|
2431
|
+
Player.version = /* PLAYER_VERSION */ "3.31.0";
|
|
2344
2432
|
export default Player;
|
|
@@ -30,6 +30,16 @@ import { IPlaybackObservation, IReadOnlyPlaybackObserver } from "./playback_obse
|
|
|
30
30
|
* remove all listeners this function has registered.
|
|
31
31
|
*/
|
|
32
32
|
export declare function emitSeekEvents(mediaElement: HTMLMediaElement | null, playbackObserver: IReadOnlyPlaybackObserver<IPlaybackObservation>, onSeeking: () => void, onSeeked: () => void, cancelSignal: CancellationSignal): void;
|
|
33
|
+
/**
|
|
34
|
+
* @param {HTMLMediaElement} mediaElement
|
|
35
|
+
* @param {function} onPlay - Callback called when a play operation has started
|
|
36
|
+
* on `mediaElement`.
|
|
37
|
+
* @param {function} onPause - Callback called when a pause operation has
|
|
38
|
+
* started on `mediaElement`.
|
|
39
|
+
* @param {Object} cancelSignal - When triggered, stop calling callbacks and
|
|
40
|
+
* remove all listeners this function has registered.
|
|
41
|
+
*/
|
|
42
|
+
export declare function emitPlayPauseEvents(mediaElement: HTMLMediaElement | null, onPlay: () => void, onPause: () => void, cancelSignal: CancellationSignal): void;
|
|
33
43
|
/** Player state dictionnary. */
|
|
34
44
|
export declare const enum PLAYER_STATES {
|
|
35
45
|
STOPPED = "STOPPED",
|
|
@@ -49,6 +49,26 @@ export function emitSeekEvents(mediaElement, playbackObserver, onSeeking, onSeek
|
|
|
49
49
|
}
|
|
50
50
|
}, { includeLastObservation: true, clearSignal: cancelSignal });
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* @param {HTMLMediaElement} mediaElement
|
|
54
|
+
* @param {function} onPlay - Callback called when a play operation has started
|
|
55
|
+
* on `mediaElement`.
|
|
56
|
+
* @param {function} onPause - Callback called when a pause operation has
|
|
57
|
+
* started on `mediaElement`.
|
|
58
|
+
* @param {Object} cancelSignal - When triggered, stop calling callbacks and
|
|
59
|
+
* remove all listeners this function has registered.
|
|
60
|
+
*/
|
|
61
|
+
export function emitPlayPauseEvents(mediaElement, onPlay, onPause, cancelSignal) {
|
|
62
|
+
if (cancelSignal.isCancelled() || mediaElement === null) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
mediaElement.addEventListener("play", onPlay);
|
|
66
|
+
mediaElement.addEventListener("pause", onPause);
|
|
67
|
+
cancelSignal.register(function () {
|
|
68
|
+
mediaElement.removeEventListener("play", onPlay);
|
|
69
|
+
mediaElement.removeEventListener("pause", onPause);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
52
72
|
export function constructPlayerStateReference(initializer, mediaElement, playbackObserver, cancelSignal) {
|
|
53
73
|
var playerStateRef = createSharedReference("LOADING" /* PLAYER_STATES.LOADING */, cancelSignal);
|
|
54
74
|
initializer.addEventListener("loaded", function () {
|
|
@@ -130,7 +130,13 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
130
130
|
log.info("DRM: No license given, skipping session.update");
|
|
131
131
|
}
|
|
132
132
|
else {
|
|
133
|
-
|
|
133
|
+
try {
|
|
134
|
+
return updateSessionWithMessage(session, licenseObject);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
manualCanceller.cancel();
|
|
138
|
+
callbacks.onError(err);
|
|
139
|
+
}
|
|
134
140
|
}
|
|
135
141
|
})
|
|
136
142
|
.catch(function (err) {
|
|
@@ -249,7 +249,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
249
249
|
if (initCanceller.isUsed()) {
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
252
|
-
triggerEvent("reloadingMediaSource",
|
|
252
|
+
triggerEvent("reloadingMediaSource", reloadOrder);
|
|
253
253
|
if (initCanceller.isUsed()) {
|
|
254
254
|
return;
|
|
255
255
|
}
|
|
@@ -95,7 +95,15 @@ export interface IContentInitializerEvents {
|
|
|
95
95
|
* Event sent when we're starting attach a new MediaSource to the media element
|
|
96
96
|
* (after removing the previous one).
|
|
97
97
|
*/
|
|
98
|
-
reloadingMediaSource:
|
|
98
|
+
reloadingMediaSource: {
|
|
99
|
+
/** The position we're reloading at, in seconds. */
|
|
100
|
+
position: number;
|
|
101
|
+
/**
|
|
102
|
+
* If `true`, we'll play directly after finishing the reloading operation.
|
|
103
|
+
* If `false`, we'll be paused after it.
|
|
104
|
+
*/
|
|
105
|
+
autoPlay: boolean;
|
|
106
|
+
};
|
|
99
107
|
/** Event sent after the player stalled. */
|
|
100
108
|
stalled: IStallingSituation;
|
|
101
109
|
/** Event sent when the player goes out of a stalling situation. */
|