@gcorevideo/player 2.19.15 → 2.20.1
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/assets/level-selector/list.ejs +1 -1
- package/dist/core.js +2 -2
- package/dist/index.css +1634 -1634
- package/dist/index.js +585 -416
- package/dist/player.d.ts +268 -72
- package/dist/plugins/index.css +1567 -1567
- package/dist/plugins/index.js +526 -357
- package/docs/api/player.clapprnerdstats.md +12 -259
- package/docs/api/player.dvrcontrols.md +5 -1
- package/docs/api/player.errorscreen.attributes.md +3 -0
- package/docs/api/player.errorscreen.bindevents.md +3 -0
- package/docs/api/player.errorscreen.container.md +3 -0
- package/docs/api/player.errorscreen.hide.md +3 -0
- package/docs/api/player.errorscreen.md +27 -0
- package/docs/api/player.errorscreen.name.md +3 -0
- package/docs/api/player.errorscreen.render.md +3 -0
- package/docs/api/player.errorscreen.show.md +3 -0
- package/docs/api/player.errorscreen.supportedversion.md +3 -0
- package/docs/api/player.errorscreen.template.md +3 -0
- package/docs/api/player.errorscreen.unbindevents.md +3 -0
- package/docs/api/{player.playbackrate.template.md → player.initeventdata.event.md} +3 -3
- package/docs/api/{player.playbackrate.updateplaybackrate.md → player.initeventdata.md} +15 -11
- package/docs/api/player.md +88 -5
- package/docs/api/player.pictureinpicture.md +9 -197
- package/docs/api/player.playbackrate.md +10 -314
- package/docs/api/{player.playbackrate.onplay.md → player.stalleventdata.count.md} +5 -7
- package/docs/api/{player.playbackrate.name.md → player.stalleventdata.event.md} +3 -3
- package/docs/api/player.stalleventdata.md +112 -0
- package/docs/api/player.stalleventdata.time.md +13 -0
- package/docs/api/player.stalleventdata.total_ms.md +13 -0
- package/docs/api/{player.pluginsettings.md → player.starteventdata.event.md} +3 -5
- package/docs/api/{player.playbackrate.onrateselect.md → player.starteventdata.md} +15 -11
- package/docs/api/{player.statistics._constructor_.md → player.telemetry._constructor_.md} +6 -3
- package/docs/api/player.telemetry.md +146 -0
- package/docs/api/{player.volumefade.name.md → player.telemetry.name.md} +4 -2
- package/docs/api/{player.clapprnerdstats.supportedversion.md → player.telemetry.supportedversion.md} +4 -2
- package/docs/api/player.telemetryevent.md +89 -0
- package/docs/api/player.telemetryeventdata.md +15 -0
- package/docs/api/player.telemetrypluginsettings.md +57 -0
- package/docs/api/player.telemetrypluginsettings.send.md +13 -0
- package/docs/api/player.telemetryrecord.md +17 -0
- package/docs/api/player.volumefade.md +0 -93
- package/docs/api/{player.pictureinpicture.name.md → player.watcheventdata.event.md} +3 -3
- package/docs/api/{player.playbackrate.setselectedrate.md → player.watcheventdata.md} +15 -11
- package/lib/index.plugins.d.ts +2 -2
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +2 -2
- package/lib/playback/hls-playback/HlsPlayback.js +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +38 -5
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +63 -17
- package/lib/plugins/dvr-controls/DvrControls.d.ts +5 -2
- package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
- package/lib/plugins/dvr-controls/DvrControls.js +5 -2
- package/lib/plugins/error-screen/ErrorScreen.d.ts +5 -0
- package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
- package/lib/plugins/error-screen/ErrorScreen.js +5 -0
- package/lib/plugins/index.d.ts +2 -3
- package/lib/plugins/index.d.ts.map +1 -1
- package/lib/plugins/index.js +2 -3
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +32 -4
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
- package/lib/plugins/picture-in-picture/PictureInPicture.js +30 -2
- package/lib/plugins/playback-rate/PlaybackRate.d.ts +47 -14
- package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
- package/lib/plugins/playback-rate/PlaybackRate.js +38 -9
- package/lib/plugins/statistics/Statistics.d.ts +38 -3
- package/lib/plugins/statistics/Statistics.d.ts.map +1 -1
- package/lib/plugins/statistics/Statistics.js +51 -9
- package/lib/plugins/telemetry/Telemetry.d.ts +135 -0
- package/lib/plugins/telemetry/Telemetry.d.ts.map +1 -0
- package/lib/plugins/telemetry/Telemetry.js +180 -0
- package/lib/plugins/volume-fade/VolumeFade.d.ts +7 -1
- package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -1
- package/lib/plugins/volume-fade/VolumeFade.js +8 -1
- package/package.json +1 -1
- package/src/index.plugins.ts +2 -2
- package/src/playback/hls-playback/HlsPlayback.ts +1 -1
- package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +240 -173
- package/src/plugins/dvr-controls/DvrControls.ts +5 -2
- package/src/plugins/error-screen/ErrorScreen.ts +5 -0
- package/src/plugins/index.ts +2 -3
- package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +47 -26
- package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +18 -18
- package/src/plugins/picture-in-picture/PictureInPicture.ts +35 -7
- package/src/plugins/playback-rate/PlaybackRate.ts +53 -24
- package/src/plugins/telemetry/Telemetry.ts +299 -0
- package/src/plugins/volume-fade/VolumeFade.ts +9 -2
- package/temp/player.api.json +2322 -3281
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.clapprnerdstats.attributes.md +0 -17
- package/docs/api/player.clapprnerdstats.bindevents.md +0 -18
- package/docs/api/player.clapprnerdstats.events.md +0 -18
- package/docs/api/player.clapprnerdstats.name.md +0 -14
- package/docs/api/player.clapprnerdstats.playerheight.md +0 -14
- package/docs/api/player.clapprnerdstats.playerwidth.md +0 -14
- package/docs/api/player.clapprnerdstats.render.md +0 -18
- package/docs/api/player.clapprnerdstats.statsboxelem.md +0 -14
- package/docs/api/player.clapprnerdstats.statsboxwidththreshold.md +0 -14
- package/docs/api/player.clapprnerdstats.template.md +0 -14
- package/docs/api/player.pictureinpicture.bindevents.md +0 -15
- package/docs/api/player.pictureinpicture.events.md +0 -13
- package/docs/api/player.pictureinpicture.exitpictureinpicture.md +0 -15
- package/docs/api/player.pictureinpicture.render.md +0 -15
- package/docs/api/player.pictureinpicture.requestpictureinpicture.md +0 -15
- package/docs/api/player.pictureinpicture.supportedversion.md +0 -13
- package/docs/api/player.pictureinpicture.togglepictureinpicture.md +0 -15
- package/docs/api/player.pictureinpicture.version.md +0 -11
- package/docs/api/player.pictureinpicture.videoelement.md +0 -11
- package/docs/api/player.playbackrate.attributes.md +0 -14
- package/docs/api/player.playbackrate.bindevents.md +0 -15
- package/docs/api/player.playbackrate.events.md +0 -15
- package/docs/api/player.playbackrate.gettitle.md +0 -15
- package/docs/api/player.playbackrate.goback.md +0 -15
- package/docs/api/player.playbackrate.highlightcurrentrate.md +0 -15
- package/docs/api/player.playbackrate.onfinishad.md +0 -15
- package/docs/api/player.playbackrate.onshowmenu.md +0 -15
- package/docs/api/player.playbackrate.onstartad.md +0 -15
- package/docs/api/player.playbackrate.onstop.md +0 -15
- package/docs/api/player.playbackrate.reload.md +0 -15
- package/docs/api/player.playbackrate.render.md +0 -15
- package/docs/api/player.playbackrate.supportedversion.md +0 -13
- package/docs/api/player.playbackrate.unbindevents.md +0 -15
- package/docs/api/player.statistics.bindevents.md +0 -15
- package/docs/api/player.statistics.md +0 -141
- package/docs/api/player.statistics.name.md +0 -11
- package/docs/api/player.statistics.supportedversion.md +0 -13
- package/docs/api/player.volumefade.bindevents.md +0 -18
- package/docs/api/player.volumefade.unbindevents.md +0 -18
- package/src/plugins/statistics/Statistics.ts +0 -207
- /package/src/plugins/{statistics → telemetry}/Statistics copy.xts +0 -0
package/dist/index.js
CHANGED
|
@@ -12459,7 +12459,7 @@ var PlaybackErrorCode;
|
|
|
12459
12459
|
// license that can be found in the LICENSE file.
|
|
12460
12460
|
const AUTO$2 = -1;
|
|
12461
12461
|
const { now: now$2 } = Utils;
|
|
12462
|
-
const T$
|
|
12462
|
+
const T$f = 'playback.dash';
|
|
12463
12463
|
// @ts-expect-error
|
|
12464
12464
|
class DashPlayback extends HTML5Video {
|
|
12465
12465
|
_levels = null;
|
|
@@ -12729,10 +12729,10 @@ class DashPlayback extends HTML5Video {
|
|
|
12729
12729
|
}
|
|
12730
12730
|
_onPlaybackError = (event) => {
|
|
12731
12731
|
// TODO
|
|
12732
|
-
trace(`${T$
|
|
12732
|
+
trace(`${T$f} _onPlaybackError`, { event });
|
|
12733
12733
|
};
|
|
12734
12734
|
_onDASHJSSError = (event) => {
|
|
12735
|
-
trace(`${T$
|
|
12735
|
+
trace(`${T$f} _onDASHJSSError`, { event });
|
|
12736
12736
|
this._stopTimeUpdateTimer();
|
|
12737
12737
|
// Note that the other error types are deprecated
|
|
12738
12738
|
const e = event.error;
|
|
@@ -12767,7 +12767,7 @@ class DashPlayback extends HTML5Video {
|
|
|
12767
12767
|
}
|
|
12768
12768
|
};
|
|
12769
12769
|
triggerError(error) {
|
|
12770
|
-
trace(`${T$
|
|
12770
|
+
trace(`${T$f} triggerError`, { error });
|
|
12771
12771
|
this.trigger(Events$1.PLAYBACK_ERROR, {
|
|
12772
12772
|
...error,
|
|
12773
12773
|
origin: this.name,
|
|
@@ -12807,7 +12807,7 @@ class DashPlayback extends HTML5Video {
|
|
|
12807
12807
|
}
|
|
12808
12808
|
get dvrEnabled() {
|
|
12809
12809
|
if (!this._dash) {
|
|
12810
|
-
trace(`${T$
|
|
12810
|
+
trace(`${T$f} dvrEnable no dash player instance`);
|
|
12811
12811
|
return false;
|
|
12812
12812
|
}
|
|
12813
12813
|
return (this._dash?.getDVRWindowSize() >= this._minDvrSize &&
|
|
@@ -12829,7 +12829,7 @@ class DashPlayback extends HTML5Video {
|
|
|
12829
12829
|
this.trigger(Events$1.PLAYBACK_PROGRESS, progress, {});
|
|
12830
12830
|
}
|
|
12831
12831
|
play() {
|
|
12832
|
-
trace(`${T$
|
|
12832
|
+
trace(`${T$f} play`, { dash: !!this._dash });
|
|
12833
12833
|
if (!this._dash) {
|
|
12834
12834
|
this._setup();
|
|
12835
12835
|
}
|
|
@@ -41576,7 +41576,7 @@ const AUTO$1 = -1;
|
|
|
41576
41576
|
const DEFAULT_RECOVER_ATTEMPTS = 16;
|
|
41577
41577
|
Events$1.register('PLAYBACK_FRAGMENT_CHANGED');
|
|
41578
41578
|
Events$1.register('PLAYBACK_FRAGMENT_PARSING_METADATA');
|
|
41579
|
-
const T$
|
|
41579
|
+
const T$e = 'playback.hls';
|
|
41580
41580
|
// @ts-expect-error
|
|
41581
41581
|
class HlsPlayback extends HTML5Video {
|
|
41582
41582
|
_ccIsSetup = false;
|
|
@@ -41806,7 +41806,7 @@ class HlsPlayback extends HTML5Video {
|
|
|
41806
41806
|
maxBufferLength: 2,
|
|
41807
41807
|
maxMaxBufferLength: 4,
|
|
41808
41808
|
}, this.options.playback.hlsjsConfig);
|
|
41809
|
-
trace(`${T$
|
|
41809
|
+
trace(`${T$e} _createHLSInstance`, { config });
|
|
41810
41810
|
this._hls = new Hls(config);
|
|
41811
41811
|
}
|
|
41812
41812
|
_attachHLSMedia() {
|
|
@@ -41895,7 +41895,7 @@ class HlsPlayback extends HTML5Video {
|
|
|
41895
41895
|
}
|
|
41896
41896
|
else {
|
|
41897
41897
|
Log.error('hlsjs: failed to recover', { evt, data });
|
|
41898
|
-
trace(`${T$
|
|
41898
|
+
trace(`${T$e} _recover failed to recover`, {
|
|
41899
41899
|
type: data.type,
|
|
41900
41900
|
details: data.details,
|
|
41901
41901
|
});
|
|
@@ -41981,7 +41981,7 @@ class HlsPlayback extends HTML5Video {
|
|
|
41981
41981
|
this.trigger(Events$1.PLAYBACK_SETTINGSUPDATE);
|
|
41982
41982
|
}
|
|
41983
41983
|
_onHLSJSError(evt, data) {
|
|
41984
|
-
trace(`${T$
|
|
41984
|
+
trace(`${T$e} _onHLSJSError`, {
|
|
41985
41985
|
fatal: data.fatal,
|
|
41986
41986
|
type: data.type,
|
|
41987
41987
|
details: data.details,
|
|
@@ -42029,7 +42029,7 @@ class HlsPlayback extends HTML5Video {
|
|
|
42029
42029
|
evt,
|
|
42030
42030
|
data,
|
|
42031
42031
|
});
|
|
42032
|
-
trace(`${T$
|
|
42032
|
+
trace(`${T$e} _onHLSJSError trying to recover from network error`, {
|
|
42033
42033
|
details: data.details,
|
|
42034
42034
|
});
|
|
42035
42035
|
error.level = PlayerError.Levels.WARN;
|
|
@@ -42042,7 +42042,7 @@ class HlsPlayback extends HTML5Video {
|
|
|
42042
42042
|
evt,
|
|
42043
42043
|
data,
|
|
42044
42044
|
});
|
|
42045
|
-
trace(`${T$
|
|
42045
|
+
trace(`${T$e} _onHLSJSError trying to recover from media error`, {
|
|
42046
42046
|
details: data.details,
|
|
42047
42047
|
});
|
|
42048
42048
|
error.level = PlayerError.Levels.WARN;
|
|
@@ -42072,7 +42072,7 @@ class HlsPlayback extends HTML5Video {
|
|
|
42072
42072
|
return;
|
|
42073
42073
|
}
|
|
42074
42074
|
Log.warn('hlsjs: non-fatal error occurred', { evt, data });
|
|
42075
|
-
trace(`${T$
|
|
42075
|
+
trace(`${T$e} _onHLSJSError non-fatal error occurred`, {
|
|
42076
42076
|
type: data.type,
|
|
42077
42077
|
details: data.details,
|
|
42078
42078
|
});
|
|
@@ -42144,9 +42144,9 @@ class HlsPlayback extends HTML5Video {
|
|
|
42144
42144
|
}
|
|
42145
42145
|
play() {
|
|
42146
42146
|
!this._hls && this._setup();
|
|
42147
|
-
assert.ok(this._hls, 'Hls.js instance is not available');
|
|
42148
42147
|
!this._manifestParsed &&
|
|
42149
42148
|
!this.options.hlsPlayback.preload &&
|
|
42149
|
+
// @ts-expect-error
|
|
42150
42150
|
this._hls.loadSource(this.options.src);
|
|
42151
42151
|
super.play();
|
|
42152
42152
|
this._startTimeUpdateTimer();
|
|
@@ -42400,7 +42400,7 @@ function registerPlaybacks() {
|
|
|
42400
42400
|
Loader.registerPlayback(DashPlayback);
|
|
42401
42401
|
}
|
|
42402
42402
|
|
|
42403
|
-
const T$
|
|
42403
|
+
const T$d = 'GPlayer';
|
|
42404
42404
|
const DEFAULT_OPTIONS = {
|
|
42405
42405
|
autoPlay: false,
|
|
42406
42406
|
debug: 'none',
|
|
@@ -42495,7 +42495,7 @@ class Player {
|
|
|
42495
42495
|
}
|
|
42496
42496
|
const coreOpts = this.buildCoreOptions(playerElement);
|
|
42497
42497
|
const { core, container } = Loader.registeredPlugins;
|
|
42498
|
-
trace(`${T$
|
|
42498
|
+
trace(`${T$d} init`, {
|
|
42499
42499
|
registeredPlaybacks: Loader.registeredPlaybacks.map((p) => p.name),
|
|
42500
42500
|
});
|
|
42501
42501
|
coreOpts.plugins = {
|
|
@@ -42509,7 +42509,7 @@ class Player {
|
|
|
42509
42509
|
* Destroys the player, releasing all resources and unmounting its UI from the DOM.
|
|
42510
42510
|
*/
|
|
42511
42511
|
destroy() {
|
|
42512
|
-
trace(`${T$
|
|
42512
|
+
trace(`${T$d} destroy`, {
|
|
42513
42513
|
player: !!this.player,
|
|
42514
42514
|
});
|
|
42515
42515
|
if (this.player) {
|
|
@@ -42669,7 +42669,7 @@ class Player {
|
|
|
42669
42669
|
this.config = $.extend(true, this.config, config);
|
|
42670
42670
|
}
|
|
42671
42671
|
initPlayer(coreOptions) {
|
|
42672
|
-
trace(`${T$
|
|
42672
|
+
trace(`${T$d} initPlayer`, {
|
|
42673
42673
|
autoPlay: coreOptions.autoPlay,
|
|
42674
42674
|
sources: coreOptions.sources,
|
|
42675
42675
|
// TODO selected options
|
|
@@ -42694,7 +42694,7 @@ class Player {
|
|
|
42694
42694
|
}
|
|
42695
42695
|
}
|
|
42696
42696
|
triggerAutoPlay() {
|
|
42697
|
-
trace(`${T$
|
|
42697
|
+
trace(`${T$d} triggerAutoPlay`);
|
|
42698
42698
|
setTimeout(() => {
|
|
42699
42699
|
this.player?.play({
|
|
42700
42700
|
autoPlay: true,
|
|
@@ -42712,7 +42712,7 @@ class Player {
|
|
|
42712
42712
|
// TODO test
|
|
42713
42713
|
events = {
|
|
42714
42714
|
onReady: () => {
|
|
42715
|
-
trace(`${T$
|
|
42715
|
+
trace(`${T$d} onReady`, {
|
|
42716
42716
|
ready: this.ready,
|
|
42717
42717
|
});
|
|
42718
42718
|
if (this.ready) {
|
|
@@ -42746,7 +42746,7 @@ class Player {
|
|
|
42746
42746
|
buildCoreOptions(rootNode) {
|
|
42747
42747
|
const sources = this.buildMediaSourcesList();
|
|
42748
42748
|
const source = sources[0];
|
|
42749
|
-
trace(`${T$
|
|
42749
|
+
trace(`${T$d} buildCoreOptions`, {
|
|
42750
42750
|
source,
|
|
42751
42751
|
sources,
|
|
42752
42752
|
});
|
|
@@ -42805,7 +42805,7 @@ class Player {
|
|
|
42805
42805
|
bindCoreListeners() {
|
|
42806
42806
|
const core = this.player?.core;
|
|
42807
42807
|
core?.on(Events$1.CORE_SCREEN_ORIENTATION_CHANGED, ({ orientation }) => {
|
|
42808
|
-
trace(`${T$
|
|
42808
|
+
trace(`${T$d} on CORE_SCREEN_ORIENTATION_CHANGED`, {
|
|
42809
42809
|
orientation,
|
|
42810
42810
|
rootNode: {
|
|
42811
42811
|
width: this.rootNode?.clientWidth,
|
|
@@ -42820,14 +42820,14 @@ class Player {
|
|
|
42820
42820
|
}
|
|
42821
42821
|
}, null);
|
|
42822
42822
|
core?.on(Events$1.CORE_RESIZE, ({ width, height }) => {
|
|
42823
|
-
trace(`${T$
|
|
42823
|
+
trace(`${T$d} on CORE_RESIZE`, {
|
|
42824
42824
|
width,
|
|
42825
42825
|
height,
|
|
42826
42826
|
});
|
|
42827
42827
|
this.safeTriggerEvent(PlayerEvent.Resize, { width, height });
|
|
42828
42828
|
}, null);
|
|
42829
42829
|
core?.on(Events$1.CORE_FULLSCREEN, (isFullscreen) => {
|
|
42830
|
-
trace(`${T$
|
|
42830
|
+
trace(`${T$d} CORE_FULLSCREEN`, {
|
|
42831
42831
|
isFullscreen,
|
|
42832
42832
|
});
|
|
42833
42833
|
this.safeTriggerEvent(PlayerEvent.Fullscreen, isFullscreen);
|
|
@@ -42835,7 +42835,7 @@ class Player {
|
|
|
42835
42835
|
}
|
|
42836
42836
|
}
|
|
42837
42837
|
|
|
42838
|
-
var version$1 = "2.
|
|
42838
|
+
var version$1 = "2.20.1";
|
|
42839
42839
|
|
|
42840
42840
|
var packages = {
|
|
42841
42841
|
"node_modules/@clappr/core": {
|
|
@@ -43141,7 +43141,7 @@ const volumeOffIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
|
|
|
43141
43141
|
|
|
43142
43142
|
const pluginHtml$7 = "<div class=\"big-mute-icon-wrapper\" data-big-mute>\n <div class=\"big-mute-icon gcore-skin-border-color\" data-big-mute-icon></div>\n</div>\n";
|
|
43143
43143
|
|
|
43144
|
-
const T$
|
|
43144
|
+
const T$c = "plugins.big_mute_button";
|
|
43145
43145
|
/**
|
|
43146
43146
|
* @beta
|
|
43147
43147
|
*/
|
|
@@ -43170,7 +43170,7 @@ class BigMuteButton extends UICorePlugin {
|
|
|
43170
43170
|
this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
|
|
43171
43171
|
this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
|
|
43172
43172
|
this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
|
|
43173
|
-
trace(`${T$
|
|
43173
|
+
trace(`${T$c} bindEvents`, {
|
|
43174
43174
|
mediacontrol: !!this.core.mediaControl,
|
|
43175
43175
|
});
|
|
43176
43176
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
|
|
@@ -43206,12 +43206,12 @@ class BigMuteButton extends UICorePlugin {
|
|
|
43206
43206
|
}
|
|
43207
43207
|
mediaControlRendered() {
|
|
43208
43208
|
const container = this.core.activeContainer;
|
|
43209
|
-
trace(`${T$
|
|
43209
|
+
trace(`${T$c} mediaControlRendered`, {
|
|
43210
43210
|
container: !!container,
|
|
43211
43211
|
});
|
|
43212
43212
|
if (container) {
|
|
43213
43213
|
this.listenTo(container.playback, Events$1.PLAYBACK_PLAY, () => {
|
|
43214
|
-
trace(`${T$
|
|
43214
|
+
trace(`${T$c} PLAYBACK_PLAY`);
|
|
43215
43215
|
this.render();
|
|
43216
43216
|
});
|
|
43217
43217
|
}
|
|
@@ -43235,7 +43235,7 @@ class BigMuteButton extends UICorePlugin {
|
|
|
43235
43235
|
}
|
|
43236
43236
|
const { autoPlay, wasMuted } = this.options;
|
|
43237
43237
|
const volume = container.volume;
|
|
43238
|
-
trace(`${T$
|
|
43238
|
+
trace(`${T$c} shouldRender`, {
|
|
43239
43239
|
autoPlay,
|
|
43240
43240
|
wasMuted,
|
|
43241
43241
|
volume,
|
|
@@ -43244,7 +43244,7 @@ class BigMuteButton extends UICorePlugin {
|
|
|
43244
43244
|
}
|
|
43245
43245
|
render() {
|
|
43246
43246
|
if (this.shouldRender()) {
|
|
43247
|
-
trace(`${T$
|
|
43247
|
+
trace(`${T$c} render`, {
|
|
43248
43248
|
el: !!this.$el,
|
|
43249
43249
|
});
|
|
43250
43250
|
this.$el.html(this.template());
|
|
@@ -43290,7 +43290,7 @@ const gearIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"n
|
|
|
43290
43290
|
const gearHdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_28_1567)\">\n <path\n d=\"M19.14 12.94C19.18 12.64 19.2 12.33 19.2 12C19.2 11.68 19.18 11.36 19.13 11.06L21.16 9.47999C21.34 9.33999 21.39 9.06999 21.28 8.86999L19.36 5.54999C19.24 5.32999 18.99 5.25999 18.77 5.32999L16.38 6.28999C15.88 5.90999 15.35 5.58999 14.76 5.34999L14.4 2.80999C14.36 2.56999 14.16 2.39999 13.92 2.39999H10.08C9.83999 2.39999 9.64999 2.56999 9.60999 2.80999L9.24999 5.34999C8.65999 5.58999 8.11999 5.91999 7.62999 6.28999L5.23999 5.32999C5.01999 5.24999 4.76999 5.32999 4.64999 5.54999L2.73999 8.86999C2.61999 9.07999 2.65999 9.33999 2.85999 9.47999L4.88999 11.06C4.83999 11.36 4.79999 11.69 4.79999 12C4.79999 12.31 4.81999 12.64 4.86999 12.94L2.83999 14.52C2.65999 14.66 2.60999 14.93 2.71999 15.13L4.63999 18.45C4.75999 18.67 5.00999 18.74 5.22999 18.67L7.61999 17.71C8.11999 18.09 8.64999 18.41 9.23999 18.65L9.59999 21.19C9.64999 21.43 9.83999 21.6 10.08 21.6H13.92C14.16 21.6 14.36 21.43 14.39 21.19L14.75 18.65C15.34 18.41 15.88 18.09 16.37 17.71L18.76 18.67C18.98 18.75 19.23 18.67 19.35 18.45L21.27 15.13C21.39 14.91 21.34 14.66 21.15 14.52L19.14 12.94ZM12 15.6C10.02 15.6 8.39999 13.98 8.39999 12C8.39999 10.02 10.02 8.39999 12 8.39999C13.98 8.39999 15.6 10.02 15.6 12C15.6 13.98 13.98 15.6 12 15.6Z\"\n fill=\"#C9C9C9\"/>\n <rect x=\"13\" width=\"11\" height=\"7\" rx=\"1\" fill=\"#F6413B\"/>\n <path\n d=\"M14.6962 6V1.63636H15.3546V3.53267H17.53V1.63636H18.1905V6H17.53V4.0973H15.3546V6H14.6962ZM20.562 6H19.1493V1.63636H20.6067C21.0343 1.63636 21.4015 1.72372 21.7083 1.89844C22.0151 2.07173 22.2502 2.32102 22.4135 2.64631C22.5783 2.97017 22.6607 3.35866 22.6607 3.81179C22.6607 4.26634 22.5776 4.65696 22.4114 4.98366C22.2466 5.31037 22.008 5.56179 21.6955 5.73793C21.383 5.91264 21.0051 6 20.562 6ZM19.8077 5.42472H20.5257C20.8581 5.42472 21.1344 5.36222 21.3546 5.23722C21.5748 5.1108 21.7395 4.92827 21.8489 4.68963C21.9583 4.44957 22.013 4.15696 22.013 3.81179C22.013 3.46946 21.9583 3.17898 21.8489 2.94034C21.7409 2.7017 21.5797 2.5206 21.3652 2.39702C21.1507 2.27344 20.8844 2.21165 20.5662 2.21165H19.8077V5.42472Z\"\n fill=\"#C9C9C9\"/>\n </g>\n <defs>\n <clipPath id=\"clip0_28_1567\">\n <rect width=\"24\" height=\"24\" fill=\"white\"/>\n </clipPath>\n </defs>\n</svg>\n";
|
|
43291
43291
|
|
|
43292
43292
|
const VERSION$5 = '2.19.12';
|
|
43293
|
-
const T$
|
|
43293
|
+
const T$b = 'plugins.bottom_gear';
|
|
43294
43294
|
/**
|
|
43295
43295
|
* Custom events emitted by the plugin
|
|
43296
43296
|
*/
|
|
@@ -43375,11 +43375,11 @@ class BottomGear extends UICorePlugin {
|
|
|
43375
43375
|
this.$el.find('.gear-wrapper').html(content);
|
|
43376
43376
|
}
|
|
43377
43377
|
onActiveContainerChanged() {
|
|
43378
|
-
trace(`${T$
|
|
43378
|
+
trace(`${T$b} onActiveContainerChanged`);
|
|
43379
43379
|
this.bindContainerEvents();
|
|
43380
43380
|
}
|
|
43381
43381
|
bindContainerEvents() {
|
|
43382
|
-
trace(`${T$
|
|
43382
|
+
trace(`${T$b} bindContainerEvents`);
|
|
43383
43383
|
this.listenTo(this.core.activeContainer, Events$1.CONTAINER_HIGHDEFINITIONUPDATE, this.highDefinitionUpdate);
|
|
43384
43384
|
}
|
|
43385
43385
|
highDefinitionUpdate(isHd) {
|
|
@@ -45499,7 +45499,7 @@ const qualityClasses = [
|
|
|
45499
45499
|
'speedtest-quality-value-2',
|
|
45500
45500
|
'speedtest-quality-value-3',
|
|
45501
45501
|
'speedtest-quality-value-4',
|
|
45502
|
-
'speedtest-quality-value-5'
|
|
45502
|
+
'speedtest-quality-value-5',
|
|
45503
45503
|
];
|
|
45504
45504
|
const getDownloadQuality = (speedValue) => {
|
|
45505
45505
|
if (speedValue < 3) {
|
|
@@ -45563,7 +45563,22 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
|
|
|
45563
45563
|
};
|
|
45564
45564
|
// const T = 'plugins.clappr_nerd_stats';
|
|
45565
45565
|
/**
|
|
45566
|
+
* Displays useful network-related statistics.
|
|
45566
45567
|
* @beta
|
|
45568
|
+
*
|
|
45569
|
+
* @remarks
|
|
45570
|
+
* Depends on:
|
|
45571
|
+
*
|
|
45572
|
+
* - {@link MediaControl}
|
|
45573
|
+
*
|
|
45574
|
+
* - {@link BottomGear}
|
|
45575
|
+
*
|
|
45576
|
+
* - {@link ClapprStats}
|
|
45577
|
+
*
|
|
45578
|
+
* The plugin is rendered as an item in the gear menu.
|
|
45579
|
+
*
|
|
45580
|
+
* When clicked, it shows an overlay window with the information about the network speed, latency, etc,
|
|
45581
|
+
* and recommended quality level.
|
|
45567
45582
|
*/
|
|
45568
45583
|
class ClapprNerdStats extends UICorePlugin {
|
|
45569
45584
|
container = null;
|
|
@@ -45576,21 +45591,31 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45576
45591
|
showing = false;
|
|
45577
45592
|
shortcut;
|
|
45578
45593
|
iconPosition;
|
|
45594
|
+
/**
|
|
45595
|
+
* @internal
|
|
45596
|
+
*/
|
|
45579
45597
|
get name() {
|
|
45580
45598
|
return 'nerd_stats';
|
|
45581
45599
|
}
|
|
45600
|
+
/**
|
|
45601
|
+
* @internal
|
|
45602
|
+
*/
|
|
45582
45603
|
get supportedVersion() {
|
|
45583
45604
|
return { min: CLAPPR_VERSION };
|
|
45584
45605
|
}
|
|
45585
|
-
|
|
45586
|
-
|
|
45587
|
-
|
|
45606
|
+
static template = tmpl(pluginHtml$5);
|
|
45607
|
+
/**
|
|
45608
|
+
* @internal
|
|
45609
|
+
*/
|
|
45588
45610
|
get attributes() {
|
|
45589
45611
|
return {
|
|
45590
45612
|
'data-clappr-nerd-stats': '',
|
|
45591
|
-
|
|
45613
|
+
class: 'clappr-nerd-stats',
|
|
45592
45614
|
};
|
|
45593
45615
|
}
|
|
45616
|
+
/**
|
|
45617
|
+
* @internal
|
|
45618
|
+
*/
|
|
45594
45619
|
get events() {
|
|
45595
45620
|
return {
|
|
45596
45621
|
'click [data-show-stats-button]': 'showOrHide',
|
|
@@ -45612,8 +45637,12 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45612
45637
|
}
|
|
45613
45638
|
constructor(core) {
|
|
45614
45639
|
super(core);
|
|
45615
|
-
this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
|
|
45616
|
-
|
|
45640
|
+
this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
|
|
45641
|
+
'command+shift+s',
|
|
45642
|
+
'ctrl+shift+s',
|
|
45643
|
+
];
|
|
45644
|
+
this.iconPosition =
|
|
45645
|
+
core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
|
|
45617
45646
|
this.customMetrics = {
|
|
45618
45647
|
connectionSpeed: 0,
|
|
45619
45648
|
ping: 0,
|
|
@@ -45621,6 +45650,9 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45621
45650
|
};
|
|
45622
45651
|
configureSpeedTest(core.options.clapprNerdStats?.speedTestServers ?? []);
|
|
45623
45652
|
}
|
|
45653
|
+
/**
|
|
45654
|
+
* @internal
|
|
45655
|
+
*/
|
|
45624
45656
|
bindEvents() {
|
|
45625
45657
|
const mediaControl = this.core.getPlugin('media_control');
|
|
45626
45658
|
assert(mediaControl, 'media_control plugin is required');
|
|
@@ -45660,9 +45692,11 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45660
45692
|
this.core.$el.find(this.statsBoxElem).show();
|
|
45661
45693
|
this.showing = true;
|
|
45662
45694
|
this.refreshSpeedTest();
|
|
45663
|
-
initSpeedTest(this.customMetrics)
|
|
45695
|
+
initSpeedTest(this.customMetrics)
|
|
45696
|
+
.then(() => {
|
|
45664
45697
|
startSpeedtest();
|
|
45665
|
-
})
|
|
45698
|
+
})
|
|
45699
|
+
.catch((e) => {
|
|
45666
45700
|
reportError(e);
|
|
45667
45701
|
this.disable();
|
|
45668
45702
|
});
|
|
@@ -45677,13 +45711,19 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45677
45711
|
}
|
|
45678
45712
|
addGeneralMetrics() {
|
|
45679
45713
|
this.metrics.general = {
|
|
45680
|
-
displayResolution:
|
|
45681
|
-
volume: this.container?.volume
|
|
45714
|
+
displayResolution: this.playerWidth + 'x' + this.playerHeight,
|
|
45715
|
+
volume: this.container?.volume,
|
|
45682
45716
|
};
|
|
45683
45717
|
}
|
|
45684
45718
|
addCustomMetrics() {
|
|
45685
45719
|
this.metrics.custom = this.customMetrics;
|
|
45686
|
-
const videoQualityNames = [
|
|
45720
|
+
const videoQualityNames = [
|
|
45721
|
+
'SD (480p)',
|
|
45722
|
+
'HD (720p)',
|
|
45723
|
+
'Full HD (1080p)',
|
|
45724
|
+
'2K (1440p)',
|
|
45725
|
+
'4K (2160p)',
|
|
45726
|
+
];
|
|
45687
45727
|
const { connectionSpeed, ping } = this.customMetrics;
|
|
45688
45728
|
if (!connectionSpeed || !ping) {
|
|
45689
45729
|
const calculatingText = 'Calculating... Please wait.';
|
|
@@ -45695,17 +45735,19 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45695
45735
|
const pingQuality = getPingQuality(ping);
|
|
45696
45736
|
const liveQuality = Math.min(downloadQuality, pingQuality);
|
|
45697
45737
|
const prefix = 'Optimal for ';
|
|
45698
|
-
this.metrics.custom.vodQuality =
|
|
45699
|
-
|
|
45738
|
+
this.metrics.custom.vodQuality =
|
|
45739
|
+
prefix + videoQualityNames[downloadQuality - 1];
|
|
45740
|
+
this.metrics.custom.liveQuality =
|
|
45741
|
+
prefix + videoQualityNames[liveQuality - 1];
|
|
45700
45742
|
}
|
|
45701
45743
|
updateMetrics(metrics) {
|
|
45702
45744
|
Object.assign(this.metrics, metrics);
|
|
45703
45745
|
this.addGeneralMetrics();
|
|
45704
45746
|
this.addCustomMetrics();
|
|
45705
45747
|
const scrollTop = this.core.$el.find(this.statsBoxElem).scrollTop();
|
|
45706
|
-
this.$el.html(
|
|
45748
|
+
this.$el.html(ClapprNerdStats.template({
|
|
45707
45749
|
metrics: Formatter.format(this.metrics),
|
|
45708
|
-
iconPosition: this.iconPosition
|
|
45750
|
+
iconPosition: this.iconPosition,
|
|
45709
45751
|
}));
|
|
45710
45752
|
this.setStatsBoxSize();
|
|
45711
45753
|
drawSpeedTestResults();
|
|
@@ -45725,7 +45767,11 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
45725
45767
|
this.$el.find(this.statsBoxElem).addClass('narrow');
|
|
45726
45768
|
}
|
|
45727
45769
|
}
|
|
45770
|
+
/**
|
|
45771
|
+
* @internal
|
|
45772
|
+
*/
|
|
45728
45773
|
render() {
|
|
45774
|
+
// TODO append to the container
|
|
45729
45775
|
this.core.$el.append(this.$el[0]);
|
|
45730
45776
|
this.hide();
|
|
45731
45777
|
return this;
|
|
@@ -46108,7 +46154,7 @@ class ClapprStats extends ContainerPlugin {
|
|
|
46108
46154
|
//Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
46109
46155
|
// Use of this source code is governed by a BSD-style
|
|
46110
46156
|
// license that can be found in the LICENSE file.
|
|
46111
|
-
const T$
|
|
46157
|
+
const T$a = 'plugins.click_to_pause_custom';
|
|
46112
46158
|
class ClickToPause extends ContainerPlugin {
|
|
46113
46159
|
pointerEnabled = false;
|
|
46114
46160
|
timer = null;
|
|
@@ -46128,7 +46174,7 @@ class ClickToPause extends ContainerPlugin {
|
|
|
46128
46174
|
click() {
|
|
46129
46175
|
const isLivePlayback = this.container.getPlaybackType() === Playback.LIVE;
|
|
46130
46176
|
const isDvrEnabled = this.container.isDvrEnabled();
|
|
46131
|
-
trace(`${T$
|
|
46177
|
+
trace(`${T$a} click`, {
|
|
46132
46178
|
isLivePlayback,
|
|
46133
46179
|
isDvrEnabled,
|
|
46134
46180
|
});
|
|
@@ -46146,7 +46192,7 @@ class ClickToPause extends ContainerPlugin {
|
|
|
46146
46192
|
settingsUpdate() {
|
|
46147
46193
|
const isLivePlayback = this.container.getPlaybackType() === Playback.LIVE;
|
|
46148
46194
|
const pointerEnabled = !isLivePlayback || this.container.isDvrEnabled();
|
|
46149
|
-
trace(`${T$
|
|
46195
|
+
trace(`${T$a} settingsUpdate`, {
|
|
46150
46196
|
isLivePlayback,
|
|
46151
46197
|
pointerEnabled,
|
|
46152
46198
|
});
|
|
@@ -46537,8 +46583,11 @@ const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"butt
|
|
|
46537
46583
|
* @beta
|
|
46538
46584
|
*
|
|
46539
46585
|
* @remarks
|
|
46540
|
-
*
|
|
46541
|
-
*
|
|
46586
|
+
* Depends on:
|
|
46587
|
+
*
|
|
46588
|
+
* - {@link MediaControl | media_control}
|
|
46589
|
+
*
|
|
46590
|
+
* The plugin renders the live stream indicator and the DVR seek bar, if DVR is enabled, in the media control UI.
|
|
46542
46591
|
*/
|
|
46543
46592
|
class DvrControls extends UICorePlugin {
|
|
46544
46593
|
static template = tmpl(dvrHTML);
|
|
@@ -46673,7 +46722,12 @@ const templateHtml = "<div class=\"player-error-screen__content\" data-error-scr
|
|
|
46673
46722
|
|
|
46674
46723
|
const TIME_FOR_UPDATE = 10000;
|
|
46675
46724
|
const MAX_RETRY = 10;
|
|
46676
|
-
const T$
|
|
46725
|
+
const T$9 = 'plugins.error_screen';
|
|
46726
|
+
/**
|
|
46727
|
+
* Displays a descriptive error in the overlay on top of the player.
|
|
46728
|
+
* @beta
|
|
46729
|
+
* TODO
|
|
46730
|
+
*/
|
|
46677
46731
|
class ErrorScreen extends UICorePlugin {
|
|
46678
46732
|
_retry = 0;
|
|
46679
46733
|
err = null;
|
|
@@ -46706,17 +46760,17 @@ class ErrorScreen extends UICorePlugin {
|
|
|
46706
46760
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.onContainerChanged);
|
|
46707
46761
|
}
|
|
46708
46762
|
onCoreReady() {
|
|
46709
|
-
trace(`${T$
|
|
46763
|
+
trace(`${T$9} onCoreReady`);
|
|
46710
46764
|
if (this.core.activePlayback) {
|
|
46711
46765
|
this.listenTo(this.core.activePlayback, Events$1.PLAYBACK_PLAY, this.onPlay);
|
|
46712
46766
|
}
|
|
46713
46767
|
}
|
|
46714
46768
|
onPlay() {
|
|
46715
|
-
trace(`${T$
|
|
46769
|
+
trace(`${T$9} onPlay`);
|
|
46716
46770
|
this.destroyError();
|
|
46717
46771
|
}
|
|
46718
46772
|
destroyError() {
|
|
46719
|
-
trace(`${T$
|
|
46773
|
+
trace(`${T$9} destroyError`);
|
|
46720
46774
|
this._retry = 0;
|
|
46721
46775
|
this.err = null;
|
|
46722
46776
|
if (this.timeout !== null) {
|
|
@@ -46772,7 +46826,7 @@ class ErrorScreen extends UICorePlugin {
|
|
|
46772
46826
|
}
|
|
46773
46827
|
}
|
|
46774
46828
|
onError(err) {
|
|
46775
|
-
trace(`${T$
|
|
46829
|
+
trace(`${T$9} onError`, { err });
|
|
46776
46830
|
if (err.level === PlayerError.Levels.FATAL ||
|
|
46777
46831
|
err.details === 'bufferStalledError' ||
|
|
46778
46832
|
err.details === 'manifestParsingError') {
|
|
@@ -47267,7 +47321,7 @@ function keyName(keyCode) {
|
|
|
47267
47321
|
|
|
47268
47322
|
const buttonHtml$2 = "<button class='gplayer-lite-btn gcore-skin-text-color gear-option'>\n <% if (isHd) { %>\n <span class=\"gear-option_hd-icon\"><%= hdIcon %></span>\n <% } %>\n <span>Quality</span>\n <span class=\"gear-option_arrow-right-icon\"><%= arrowRightIcon %></span>\n <span class='gear-option_value'><%= currentText %></span>\n</button>\n";
|
|
47269
47323
|
|
|
47270
|
-
const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Quality\n</button>\n<ul class=\"gear-sub-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n Auto\n </a>\n </li>\n <% } %>\n <% for (const level of levels.slice().reverse()) { %>\n <li <% if (maxLevel >= 0 && level.level > maxLevel) { %>class=\"level-disabled\"<% } %>>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"<%= level.level %>\" id=\"level_selector_<%= level.
|
|
47324
|
+
const listHtml$1 = "<button class=\"gplayer-lite-btn go-back gcore-skin-text-color\">\n <span class=\"arrow-left-icon\"><%= arrowLeftIcon %></span>\n Quality\n</button>\n<ul class=\"gear-sub-menu\">\n <% if (!removeAuto) { %>\n <li>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"-1\" id=\"level_selector_auto\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n Auto\n </a>\n </li>\n <% } %>\n <% for (const level of levels.slice().reverse()) { %>\n <li <% if (maxLevel >= 0 && level.level > maxLevel) { %>class=\"level-disabled\"<% } %>>\n <a href=\"#\" class='gear-sub-menu_btn gcore-skin-text-color' data-id=\"<%= level.level %>\" id=\"level_selector_<%= level.height %>\">\n <span class=\"check-icon\"><%= checkIcon %></span>\n <%= labels[level.level] %>\n </a>\n </li>\n <% } %>\n</ul>\n";
|
|
47271
47325
|
|
|
47272
47326
|
const hdIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14.9562 8.22232H13.9961V15.1873H14.9562C15.8914 15.1873 16.766 14.8253 17.4195 14.1676C18.0786 13.5037 18.4415 12.6281 18.4415 11.7026C18.4415 9.7837 16.8781 8.22253 14.9561 8.22253L14.9562 8.22232Z\"\n fill=\"#C9C9C9\"/>\n <path\n d=\"M22.0801 4H1.91994C0.859222 4 0 4.86406 0 5.91994V17.4878C0 18.5437 0.859222 19.4078 1.91994 19.4078H22.0801C23.1408 19.4078 24 18.5437 24 17.4878V5.91994C24 4.86406 23.1408 4 22.0801 4ZM10.3975 15.3473C10.3975 15.6124 10.1827 15.8272 9.91754 15.8272C9.65216 15.8272 9.43761 15.6122 9.43761 15.3473V12.0239H5.55956V15.3473C5.55956 15.6124 5.34481 15.8272 5.07963 15.8272C4.81425 15.8272 4.5997 15.6122 4.5997 15.3473L4.59949 7.74042C4.59949 7.47524 4.81425 7.26049 5.07943 7.26049C5.34481 7.26049 5.55936 7.47544 5.55936 7.74042V11.0636H9.43741V7.74042C9.43741 7.47524 9.65216 7.26049 9.91734 7.26049C10.1827 7.26049 10.3973 7.47544 10.3973 7.74042L10.3975 15.3473ZM18.1005 14.8438C17.2652 15.6844 16.1486 16.1472 14.9561 16.1472H13.5161C13.2507 16.1472 13.0361 15.9323 13.0361 15.6673V7.74263C13.0361 7.47745 13.2509 7.26269 13.5161 7.26269H14.9561C17.4072 7.26269 19.4013 9.25438 19.4013 11.7027C19.4013 12.8835 18.9392 13.9991 18.1005 14.844V14.8438Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
|
|
47273
47327
|
|
|
@@ -47277,7 +47331,7 @@ const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
|
|
|
47277
47331
|
|
|
47278
47332
|
const checkIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M20.5793 4.19296C20.1216 3.86696 19.4777 3.96396 19.1424 4.40896L9.37295 17.3809L4.81634 12.107C4.45222 11.683 3.80218 11.6289 3.36709 11.9839C2.932 12.3389 2.87543 12.97 3.2416 13.393L8.64165 19.643C8.83708 19.869 9.12506 20 9.42849 20C9.4398 20 9.45114 20 9.46246 19.999C9.77926 19.989 10.0724 19.838 10.2586 19.59L20.8015 5.58996C21.1368 5.14496 21.0371 4.51896 20.5793 4.19296Z\"\n fill=\"#C9C9C9\"/>\n</svg>\n";
|
|
47279
47333
|
|
|
47280
|
-
const T$
|
|
47334
|
+
const T$8 = 'plugins.level_selector';
|
|
47281
47335
|
const VERSION$4 = '2.19.4';
|
|
47282
47336
|
/**
|
|
47283
47337
|
* A {@link MediaControl | media control} plugin that provides a UI to control the quality level of the playback.
|
|
@@ -47379,10 +47433,10 @@ class LevelSelector extends UICorePlugin {
|
|
|
47379
47433
|
}
|
|
47380
47434
|
}
|
|
47381
47435
|
onStop() {
|
|
47382
|
-
trace(`${T$
|
|
47436
|
+
trace(`${T$8} onStop`);
|
|
47383
47437
|
const currentPlayback = this.core.activePlayback;
|
|
47384
47438
|
this.listenToOnce(currentPlayback, Events$1.PLAYBACK_PLAY, () => {
|
|
47385
|
-
trace(`${T$
|
|
47439
|
+
trace(`${T$8} on PLAYBACK_PLAY after stop`, { selectedLevelId: this.selectedLevelId });
|
|
47386
47440
|
if (currentPlayback.getPlaybackType() === 'live') {
|
|
47387
47441
|
if (this.selectedLevelId !== -1) {
|
|
47388
47442
|
currentPlayback.currentLevel = this.selectedLevelId;
|
|
@@ -47478,13 +47532,13 @@ class LevelSelector extends UICorePlugin {
|
|
|
47478
47532
|
return false;
|
|
47479
47533
|
}
|
|
47480
47534
|
goBack() {
|
|
47481
|
-
trace(`${T$
|
|
47535
|
+
trace(`${T$8} goBack`);
|
|
47482
47536
|
this.isOpen = false;
|
|
47483
47537
|
this.core.trigger('gear:refresh');
|
|
47484
47538
|
this.deferRender();
|
|
47485
47539
|
}
|
|
47486
47540
|
setLevel(index) {
|
|
47487
|
-
trace(`${T$
|
|
47541
|
+
trace(`${T$8} setIndexLevel`, { index });
|
|
47488
47542
|
this.selectedLevelId = index;
|
|
47489
47543
|
if (!this.core.activePlayback) {
|
|
47490
47544
|
return;
|
|
@@ -47502,7 +47556,7 @@ class LevelSelector extends UICorePlugin {
|
|
|
47502
47556
|
this.deferRender();
|
|
47503
47557
|
}
|
|
47504
47558
|
onShowLevelSelectMenu() {
|
|
47505
|
-
trace(`${T$
|
|
47559
|
+
trace(`${T$8} onShowLevelSelectMenu`);
|
|
47506
47560
|
this.isOpen = true;
|
|
47507
47561
|
this.renderDropdown();
|
|
47508
47562
|
this.highlightCurrentLevel();
|
|
@@ -47538,11 +47592,11 @@ class LevelSelector extends UICorePlugin {
|
|
|
47538
47592
|
return this.levelLabels[index] ?? formatLevelLabel(this.levels[index]);
|
|
47539
47593
|
}
|
|
47540
47594
|
updateCurrentLevel(info) {
|
|
47541
|
-
trace(`${T$
|
|
47595
|
+
trace(`${T$8} updateCurrentLevel`, { info });
|
|
47542
47596
|
this.highlightCurrentLevel();
|
|
47543
47597
|
}
|
|
47544
47598
|
highlightCurrentLevel() {
|
|
47545
|
-
trace(`${T$
|
|
47599
|
+
trace(`${T$8} highlightCurrentLevel`, {
|
|
47546
47600
|
selectedLevelId: this.selectedLevelId,
|
|
47547
47601
|
});
|
|
47548
47602
|
this.allLevelElements().removeClass('current');
|
|
@@ -48868,7 +48922,7 @@ const streamsMomentoIcon = "<svg id=\"Слой_1\" data-name=\"Слой 1\" xmln
|
|
|
48868
48922
|
const streamsWhiteNightsIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"50\" height=\"50\" viewBox=\"0 0 50 50\">\n <defs>\n <clipPath id=\"clip-Icon\">\n <rect width=\"50\" height=\"50\"/>\n </clipPath>\n </defs>\n <g id=\"Icon\" clip-path=\"url(#clip-Icon)\">\n <g id=\"icon2\" transform=\"translate(-0.041 0)\">\n <path id=\"Контур_77\" data-name=\"Контур 77\" d=\"M6.493,13v8.266h6.275V19.74H8.31V17.714h4.006V16.3H8.31V14.53h4.365V13Zm7.5,0v8.266h1.7V15.732h.023l3.438,5.534h1.818V13h-1.7v5.545h-.023L15.8,13Z\" fill=\"#fff\"/>\n <path id=\"Контур_76\" data-name=\"Контур 76\" d=\"M29.949,29.1V26.774H31.94a1.4,1.4,0,0,1,.938.272,1.1,1.1,0,0,1,.313.874,1.155,1.155,0,0,1-.313.9,1.375,1.375,0,0,1-.938.278ZM28.132,25.36v8.266h1.817V30.4h1.818a1.353,1.353,0,0,1,.984.3,1.637,1.637,0,0,1,.394.949c.046.333.079.681.1,1.042a3.2,3.2,0,0,0,.185.938h1.819a1.218,1.218,0,0,1-.191-.423,3.611,3.611,0,0,1-.093-.527c-.019-.185-.033-.367-.041-.544s-.016-.332-.023-.463a5.052,5.052,0,0,0-.087-.625,2.109,2.109,0,0,0-.2-.573,1.586,1.586,0,0,0-.359-.451,1.414,1.414,0,0,0-.556-.284v-.023a1.926,1.926,0,0,0,1-.81,2.494,2.494,0,0,0,.307-1.262,2.308,2.308,0,0,0-.165-.88,2.128,2.128,0,0,0-.486-.724,2.3,2.3,0,0,0-.764-.492,2.67,2.67,0,0,0-1-.179ZM43.506,30.5V25.36H41.689V30.5a2.065,2.065,0,0,1-.37,1.36,1.7,1.7,0,0,1-1.343.434,2.086,2.086,0,0,1-.886-.156,1.283,1.283,0,0,1-.758-.978,3.748,3.748,0,0,1-.058-.66V25.36H36.456V30.5a3.16,3.16,0,0,0,.92,2.5,3.807,3.807,0,0,0,2.6.81,3.82,3.82,0,0,0,2.593-.816,3.132,3.132,0,0,0,.937-2.492Z\" fill=\"#fff\"/>\n <path id=\"Контур_80\" data-name=\"Контур 80\" d=\"M22.646,31.2H4.689a4.505,4.505,0,0,1-4.5-4.5V8.5A4.505,4.505,0,0,1,4.689,4h18.2a4.505,4.505,0,0,1,4.5,4.5v8.445l-.893.1a3.184,3.184,0,0,0-2.846,3.177V30.5l-.465.7ZM4.689,6a2.5,2.5,0,0,0-2.5,2.5V26.7a2.5,2.5,0,0,0,2.5,2.5H21.65V20.22a5.18,5.18,0,0,1,3.739-4.992V8.5a2.5,2.5,0,0,0-2.5-2.5Z\" fill=\"#fff\"/>\n <path id=\"Контур_81\" data-name=\"Контур 81\" d=\"M30.127,47.884a1,1,0,0,1-1-1V43.267H26.846a5.206,5.206,0,0,1-5.2-5.2V20.222a5.206,5.206,0,0,1,5.2-5.2H44.692a5.206,5.206,0,0,1,5.2,5.2V38.068a5.206,5.206,0,0,1-5.2,5.2H35.058l-4.216,4.316A1,1,0,0,1,30.127,47.884ZM26.846,17.022a3.2,3.2,0,0,0-3.2,3.2V38.067a3.2,3.2,0,0,0,3.2,3.2h3.281a1,1,0,0,1,1,1v2.162l2.8-2.86a1,1,0,0,1,.715-.3H44.692a3.2,3.2,0,0,0,3.2-3.2V20.222a3.2,3.2,0,0,0-3.2-3.2Z\" fill=\"#fff\"/>\n </g>\n </g>\n</svg>\n";
|
|
48869
48923
|
|
|
48870
48924
|
const VERSION$3 = '0.0.1';
|
|
48871
|
-
const T$
|
|
48925
|
+
const T$7 = 'plugins.media_control_multicamera';
|
|
48872
48926
|
class MultiCamera extends UICorePlugin {
|
|
48873
48927
|
currentCamera = null;
|
|
48874
48928
|
currentTime = 0;
|
|
@@ -49010,7 +49064,7 @@ class MultiCamera extends UICorePlugin {
|
|
|
49010
49064
|
}
|
|
49011
49065
|
onCameraSelect(event) {
|
|
49012
49066
|
const value = event.currentTarget.dataset.multicameraSelectorSelect;
|
|
49013
|
-
trace(`${T$
|
|
49067
|
+
trace(`${T$7} onCameraSelect`, { value });
|
|
49014
49068
|
if (value !== undefined) {
|
|
49015
49069
|
this.changeById(parseInt(value, 10));
|
|
49016
49070
|
}
|
|
@@ -49137,13 +49191,13 @@ class MultiCamera extends UICorePlugin {
|
|
|
49137
49191
|
}
|
|
49138
49192
|
}
|
|
49139
49193
|
changeById(id) {
|
|
49140
|
-
trace(`${T$
|
|
49194
|
+
trace(`${T$7} changeById`, { id });
|
|
49141
49195
|
queueMicrotask(() => {
|
|
49142
49196
|
const playbackOptions = this.core.options.playback || {};
|
|
49143
49197
|
// TODO figure out what this does
|
|
49144
49198
|
playbackOptions.recycleVideo = Browser.isMobile;
|
|
49145
49199
|
this.currentCamera = this.findElementById(id) ?? null;
|
|
49146
|
-
trace(`${T$
|
|
49200
|
+
trace(`${T$7} changeById`, { id, currentCamera: this.currentCamera, multicamera: this.multicamera });
|
|
49147
49201
|
if (!this.currentCamera) {
|
|
49148
49202
|
return;
|
|
49149
49203
|
}
|
|
@@ -49160,7 +49214,7 @@ class MultiCamera extends UICorePlugin {
|
|
|
49160
49214
|
// TODO remove?
|
|
49161
49215
|
// for html5 playback:
|
|
49162
49216
|
this.options.dvrEnabled = this.currentCamera.dvr;
|
|
49163
|
-
trace(`${T$
|
|
49217
|
+
trace(`${T$7} changeById`, { currentCamera: this.currentCamera });
|
|
49164
49218
|
// TODO
|
|
49165
49219
|
this.core.configure({
|
|
49166
49220
|
playback: playbackOptions,
|
|
@@ -49218,17 +49272,39 @@ const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"no
|
|
|
49218
49272
|
const buttonHtml$1 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <span><%= pipIcon %></span>\n</button>\n";
|
|
49219
49273
|
|
|
49220
49274
|
const VERSION$2 = '0.0.1';
|
|
49221
|
-
const T$
|
|
49275
|
+
const T$6 = `plugins.pip`;
|
|
49276
|
+
/**
|
|
49277
|
+
* Enables picture in picture mode.
|
|
49278
|
+
* @beta
|
|
49279
|
+
* @remarks
|
|
49280
|
+
* Depends on:
|
|
49281
|
+
*
|
|
49282
|
+
* - {@link MediaControl}
|
|
49283
|
+
*
|
|
49284
|
+
* It renders a button to toggle picture in picture mode in the media control UI.
|
|
49285
|
+
*/
|
|
49222
49286
|
class PictureInPicture extends UICorePlugin {
|
|
49287
|
+
/**
|
|
49288
|
+
* @internal
|
|
49289
|
+
*/
|
|
49223
49290
|
get name() {
|
|
49224
|
-
return '
|
|
49291
|
+
return 'pip';
|
|
49225
49292
|
}
|
|
49293
|
+
/**
|
|
49294
|
+
* @internal
|
|
49295
|
+
*/
|
|
49226
49296
|
get supportedVersion() {
|
|
49227
49297
|
return { min: CLAPPR_VERSION };
|
|
49228
49298
|
}
|
|
49299
|
+
/**
|
|
49300
|
+
* @internal
|
|
49301
|
+
*/
|
|
49229
49302
|
static get version() {
|
|
49230
49303
|
return VERSION$2;
|
|
49231
49304
|
}
|
|
49305
|
+
/**
|
|
49306
|
+
* @internal
|
|
49307
|
+
*/
|
|
49232
49308
|
get events() {
|
|
49233
49309
|
return {
|
|
49234
49310
|
'click button': 'togglePictureInPicture',
|
|
@@ -49237,16 +49313,22 @@ class PictureInPicture extends UICorePlugin {
|
|
|
49237
49313
|
get videoElement() {
|
|
49238
49314
|
return this.core.activePlayback.el;
|
|
49239
49315
|
}
|
|
49316
|
+
/**
|
|
49317
|
+
* @internal
|
|
49318
|
+
*/
|
|
49240
49319
|
bindEvents() {
|
|
49241
49320
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
|
|
49242
49321
|
}
|
|
49243
49322
|
isPiPSupported() {
|
|
49244
|
-
trace(`${T$
|
|
49323
|
+
trace(`${T$6} isPiPSupported`, {
|
|
49245
49324
|
pictureInPictureEnabled: document.pictureInPictureEnabled,
|
|
49246
49325
|
requestPictureInPicture: HTMLVideoElement.prototype.requestPictureInPicture,
|
|
49247
49326
|
});
|
|
49248
49327
|
return document.pictureInPictureEnabled && !!HTMLVideoElement.prototype.requestPictureInPicture;
|
|
49249
49328
|
}
|
|
49329
|
+
/**
|
|
49330
|
+
* @internal
|
|
49331
|
+
*/
|
|
49250
49332
|
render() {
|
|
49251
49333
|
if (!this.isPiPSupported()) {
|
|
49252
49334
|
return this;
|
|
@@ -49260,7 +49342,7 @@ class PictureInPicture extends UICorePlugin {
|
|
|
49260
49342
|
return this;
|
|
49261
49343
|
}
|
|
49262
49344
|
togglePictureInPicture() {
|
|
49263
|
-
trace(`${T$
|
|
49345
|
+
trace(`${T$6} togglePictureInPicture`);
|
|
49264
49346
|
if (this.videoElement !== document.pictureInPictureElement) {
|
|
49265
49347
|
this.requestPictureInPicture();
|
|
49266
49348
|
}
|
|
@@ -49269,13 +49351,13 @@ class PictureInPicture extends UICorePlugin {
|
|
|
49269
49351
|
}
|
|
49270
49352
|
}
|
|
49271
49353
|
requestPictureInPicture() {
|
|
49272
|
-
trace(`${T$
|
|
49354
|
+
trace(`${T$6} requestPictureInPicture`, {
|
|
49273
49355
|
videoElement: !!this.videoElement,
|
|
49274
49356
|
});
|
|
49275
49357
|
this.videoElement.requestPictureInPicture();
|
|
49276
49358
|
}
|
|
49277
49359
|
exitPictureInPicture() {
|
|
49278
|
-
trace(`${T$
|
|
49360
|
+
trace(`${T$6} exitPictureInPicture`);
|
|
49279
49361
|
document.exitPictureInPicture();
|
|
49280
49362
|
}
|
|
49281
49363
|
}
|
|
@@ -49300,26 +49382,51 @@ const DEFAULT_PLAYBACK_RATES = [
|
|
|
49300
49382
|
const DEFAULT_PLAYBACK_RATE = '1.0';
|
|
49301
49383
|
// TODO
|
|
49302
49384
|
const MEDIACONTROL_PLAYBACKRATE = 'playbackRate';
|
|
49385
|
+
/**
|
|
49386
|
+
* Allows changing the playback speed of the video.
|
|
49387
|
+
* @beta
|
|
49388
|
+
*
|
|
49389
|
+
* @remarks
|
|
49390
|
+
* Depends on:
|
|
49391
|
+
*
|
|
49392
|
+
* - {@link MediaControl | media_control}
|
|
49393
|
+
*
|
|
49394
|
+
* - {@link BottomGear | bottom_gear}
|
|
49395
|
+
*
|
|
49396
|
+
* It renders a button in the gear menu, which opens a dropdown with the available playback rates.
|
|
49397
|
+
*/
|
|
49303
49398
|
class PlaybackRate extends UICorePlugin {
|
|
49304
49399
|
currentPlayback = null;
|
|
49305
49400
|
playbackRates = DEFAULT_PLAYBACK_RATES;
|
|
49306
49401
|
prevSelectedRate;
|
|
49307
49402
|
selectedRate = DEFAULT_PLAYBACK_RATE;
|
|
49403
|
+
/**
|
|
49404
|
+
* @internal
|
|
49405
|
+
*/
|
|
49308
49406
|
get name() {
|
|
49309
|
-
return '
|
|
49407
|
+
return 'playback_rate';
|
|
49310
49408
|
}
|
|
49409
|
+
/**
|
|
49410
|
+
* @internal
|
|
49411
|
+
*/
|
|
49311
49412
|
get supportedVersion() {
|
|
49312
49413
|
return { min: CLAPPR_VERSION };
|
|
49313
49414
|
}
|
|
49314
|
-
|
|
49315
|
-
|
|
49316
|
-
|
|
49415
|
+
static template = tmpl(pluginHtml$3);
|
|
49416
|
+
static buttonTemplate = tmpl(buttonHtml);
|
|
49417
|
+
static listTemplate = tmpl(listHtml);
|
|
49418
|
+
/**
|
|
49419
|
+
* @internal
|
|
49420
|
+
*/
|
|
49317
49421
|
get attributes() {
|
|
49318
49422
|
return {
|
|
49319
49423
|
'class': this.name,
|
|
49320
49424
|
'data-playback-rate-select': ''
|
|
49321
49425
|
};
|
|
49322
49426
|
}
|
|
49427
|
+
/**
|
|
49428
|
+
* @internal
|
|
49429
|
+
*/
|
|
49323
49430
|
get events() {
|
|
49324
49431
|
return {
|
|
49325
49432
|
'click .gear-sub-menu_btn': 'onRateSelect',
|
|
@@ -49327,8 +49434,12 @@ class PlaybackRate extends UICorePlugin {
|
|
|
49327
49434
|
'click .go-back': 'goBack',
|
|
49328
49435
|
};
|
|
49329
49436
|
}
|
|
49437
|
+
/**
|
|
49438
|
+
* @internal
|
|
49439
|
+
*/
|
|
49330
49440
|
bindEvents() {
|
|
49331
49441
|
this.listenTo(this.core, 'gear:rendered', this.render);
|
|
49442
|
+
// TODO this.core.getPlugin('media_control'), bottom_gear
|
|
49332
49443
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
|
|
49333
49444
|
this.listenTo(this.core.mediaControl, MEDIACONTROL_PLAYBACKRATE, this.updatePlaybackRate);
|
|
49334
49445
|
this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
|
|
@@ -49382,6 +49493,9 @@ class PlaybackRate extends UICorePlugin {
|
|
|
49382
49493
|
this.currentPlayback = this.core.activePlayback;
|
|
49383
49494
|
return !(this.currentPlayback?.tagName !== 'video' && this.currentPlayback?.tagName !== 'audio');
|
|
49384
49495
|
}
|
|
49496
|
+
/**
|
|
49497
|
+
* @internal
|
|
49498
|
+
*/
|
|
49385
49499
|
render() {
|
|
49386
49500
|
const container = this.core.activeContainer;
|
|
49387
49501
|
if (this.core.getPlaybackType() === Playback.LIVE && !container.isDvrEnabled()) {
|
|
@@ -49395,9 +49509,7 @@ class PlaybackRate extends UICorePlugin {
|
|
|
49395
49509
|
this.selectedRate = cfg.defaultValue || DEFAULT_PLAYBACK_RATE;
|
|
49396
49510
|
}
|
|
49397
49511
|
if (this.shouldRender()) {
|
|
49398
|
-
const
|
|
49399
|
-
// const html = t({ playbackRates: this.playbackRates, title: this.getTitle() });
|
|
49400
|
-
const button = t({
|
|
49512
|
+
const button = PlaybackRate.buttonTemplate({
|
|
49401
49513
|
title: this.getTitle(),
|
|
49402
49514
|
speedIcon,
|
|
49403
49515
|
arrowRightIcon,
|
|
@@ -49445,8 +49557,7 @@ class PlaybackRate extends UICorePlugin {
|
|
|
49445
49557
|
return false;
|
|
49446
49558
|
}
|
|
49447
49559
|
onShowMenu() {
|
|
49448
|
-
|
|
49449
|
-
this.$el.html(t({
|
|
49560
|
+
this.$el.html(PlaybackRate.listTemplate({
|
|
49450
49561
|
playbackRates: this.playbackRates,
|
|
49451
49562
|
arrowLeftIcon,
|
|
49452
49563
|
checkIcon,
|
|
@@ -49490,7 +49601,7 @@ const posterHTML = "<div class=\"play-wrapper\" data-poster></div>\n";
|
|
|
49490
49601
|
//Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
49491
49602
|
// Use of this source code is governed by a BSD-style
|
|
49492
49603
|
// license that can be found in the LICENSE file.
|
|
49493
|
-
const T$
|
|
49604
|
+
const T$5 = 'plugins.poster_custom';
|
|
49494
49605
|
/**
|
|
49495
49606
|
* Displays a poster image in the background and a big play button on top when playback is stopped
|
|
49496
49607
|
* @beta
|
|
@@ -49593,13 +49704,13 @@ class Poster extends UIContainerPlugin {
|
|
|
49593
49704
|
* Disables the plugin, unmounting it from the DOM
|
|
49594
49705
|
*/
|
|
49595
49706
|
disable() {
|
|
49596
|
-
trace(`${T$
|
|
49707
|
+
trace(`${T$5} disable`);
|
|
49597
49708
|
this.hasStartedPlaying = false;
|
|
49598
49709
|
this.playRequested = false;
|
|
49599
49710
|
super.disable();
|
|
49600
49711
|
}
|
|
49601
49712
|
onError(error) {
|
|
49602
|
-
trace(`${T$
|
|
49713
|
+
trace(`${T$5} onError`, {
|
|
49603
49714
|
error,
|
|
49604
49715
|
enabled: this.enabled,
|
|
49605
49716
|
});
|
|
@@ -49612,18 +49723,18 @@ class Poster extends UIContainerPlugin {
|
|
|
49612
49723
|
}
|
|
49613
49724
|
}
|
|
49614
49725
|
onPlay() {
|
|
49615
|
-
trace(`${T$
|
|
49726
|
+
trace(`${T$5} onPlay`);
|
|
49616
49727
|
this.hasStartedPlaying = true;
|
|
49617
49728
|
this.playRequested = false;
|
|
49618
49729
|
this.update();
|
|
49619
49730
|
}
|
|
49620
49731
|
onPlayIntent() {
|
|
49621
|
-
trace(`${T$
|
|
49732
|
+
trace(`${T$5} onPlayIntent`);
|
|
49622
49733
|
this.playRequested = true;
|
|
49623
49734
|
this.update();
|
|
49624
49735
|
}
|
|
49625
49736
|
onStop() {
|
|
49626
|
-
trace(`${T$
|
|
49737
|
+
trace(`${T$5} onStop`, {
|
|
49627
49738
|
enabled: this.enabled,
|
|
49628
49739
|
});
|
|
49629
49740
|
this.hasStartedPlaying = false;
|
|
@@ -49631,7 +49742,7 @@ class Poster extends UIContainerPlugin {
|
|
|
49631
49742
|
this.update();
|
|
49632
49743
|
}
|
|
49633
49744
|
updatePlayButton(show) {
|
|
49634
|
-
trace(`${T$
|
|
49745
|
+
trace(`${T$5} updatePlayButton`, {
|
|
49635
49746
|
show,
|
|
49636
49747
|
chromeless: this.options.chromeless,
|
|
49637
49748
|
allowUserInteraction: this.options.allowUserInteraction,
|
|
@@ -49660,7 +49771,7 @@ class Poster extends UIContainerPlugin {
|
|
|
49660
49771
|
this.$el.removeClass('clickable');
|
|
49661
49772
|
}
|
|
49662
49773
|
clicked() {
|
|
49663
|
-
trace(`${T$
|
|
49774
|
+
trace(`${T$5} clicked`, {
|
|
49664
49775
|
hasStartedPlaying: this.hasStartedPlaying,
|
|
49665
49776
|
chromeless: this.options.chromeless,
|
|
49666
49777
|
allowUserInteraction: this.options.allowUserInteraction,
|
|
@@ -49684,7 +49795,7 @@ class Poster extends UIContainerPlugin {
|
|
|
49684
49795
|
return !this.container.playback.isAudioOnly;
|
|
49685
49796
|
}
|
|
49686
49797
|
update() {
|
|
49687
|
-
trace(`${T$
|
|
49798
|
+
trace(`${T$5} update`, {
|
|
49688
49799
|
shouldRender: this.shouldRender,
|
|
49689
49800
|
});
|
|
49690
49801
|
if (!this.shouldRender) {
|
|
@@ -49697,7 +49808,7 @@ class Poster extends UIContainerPlugin {
|
|
|
49697
49808
|
this.updatePoster();
|
|
49698
49809
|
}
|
|
49699
49810
|
updatePoster() {
|
|
49700
|
-
trace(`${T$
|
|
49811
|
+
trace(`${T$5} updatePoster`, {
|
|
49701
49812
|
hasStartedPlaying: this.hasStartedPlaying,
|
|
49702
49813
|
});
|
|
49703
49814
|
if (!this.hasStartedPlaying) {
|
|
@@ -49712,7 +49823,7 @@ class Poster extends UIContainerPlugin {
|
|
|
49712
49823
|
this.$el.show();
|
|
49713
49824
|
}
|
|
49714
49825
|
hidePoster() {
|
|
49715
|
-
trace(`${T$
|
|
49826
|
+
trace(`${T$5} hidePoster`, {
|
|
49716
49827
|
shouldHideOnPlay: this.shouldHideOnPlay(),
|
|
49717
49828
|
});
|
|
49718
49829
|
if (!this.options.disableMediaControl) {
|
|
@@ -50129,7 +50240,7 @@ const spinnerHTML = "<div data-bounce1></div>\n<div data-bounce2></div>\n<div da
|
|
|
50129
50240
|
// Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
50130
50241
|
// Use of this source code is governed by a BSD-style
|
|
50131
50242
|
// license that can be found in the LICENSE file.
|
|
50132
|
-
const T$
|
|
50243
|
+
const T$4 = 'plugins.spinner';
|
|
50133
50244
|
/**
|
|
50134
50245
|
* Custom events emitted by the plugin
|
|
50135
50246
|
*/
|
|
@@ -50194,11 +50305,11 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
50194
50305
|
this.hasBuffering = false;
|
|
50195
50306
|
}
|
|
50196
50307
|
onPlay() {
|
|
50197
|
-
trace(`${T$
|
|
50308
|
+
trace(`${T$4} onPlay`);
|
|
50198
50309
|
this.hide();
|
|
50199
50310
|
}
|
|
50200
50311
|
onStop() {
|
|
50201
|
-
trace(`${T$
|
|
50312
|
+
trace(`${T$4} onStop`, {
|
|
50202
50313
|
showOnError: this.options.spinner?.showOnError,
|
|
50203
50314
|
hasFatalError: this.hasFatalError,
|
|
50204
50315
|
});
|
|
@@ -50208,7 +50319,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
50208
50319
|
}
|
|
50209
50320
|
onError(e) {
|
|
50210
50321
|
this.hasFatalError = e.code === PlaybackErrorCode.MediaSourceUnavailable;
|
|
50211
|
-
trace(`${T$
|
|
50322
|
+
trace(`${T$4} onError`, {
|
|
50212
50323
|
e,
|
|
50213
50324
|
showOnError: this.options.spinner?.showOnError,
|
|
50214
50325
|
hasFatalError: this.hasFatalError,
|
|
@@ -50242,7 +50353,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
50242
50353
|
*/
|
|
50243
50354
|
render() {
|
|
50244
50355
|
const showOnStart = this.options.spinner?.showOnStart;
|
|
50245
|
-
trace(`${T$
|
|
50356
|
+
trace(`${T$4} render`, {
|
|
50246
50357
|
buffering: this.container.buffering,
|
|
50247
50358
|
showOnStart,
|
|
50248
50359
|
});
|
|
@@ -50261,129 +50372,200 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
50261
50372
|
}
|
|
50262
50373
|
}
|
|
50263
50374
|
|
|
50264
|
-
|
|
50265
|
-
const
|
|
50266
|
-
const
|
|
50267
|
-
const
|
|
50268
|
-
|
|
50269
|
-
|
|
50375
|
+
const T$3 = 'plugins.source_controller';
|
|
50376
|
+
const INITIAL_RETRY_DELAY = 1000;
|
|
50377
|
+
const MAX_RETRY_DELAY = 5000;
|
|
50378
|
+
const RETRY_DELAY_BLUR = 500;
|
|
50379
|
+
const VERSION$1 = '0.0.1';
|
|
50380
|
+
function noSync(cb) {
|
|
50381
|
+
queueMicrotask(cb);
|
|
50382
|
+
}
|
|
50383
|
+
/**
|
|
50384
|
+
* This plugin is responsible for managing the automatic failover between sources.
|
|
50385
|
+
* @beta
|
|
50386
|
+
* @remarks
|
|
50387
|
+
* Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
|
|
50388
|
+
* on how sources ordering and selection works.
|
|
50389
|
+
*
|
|
50390
|
+
* This plugin does not expose any public methods apart from required by the Clappr plugin interface.
|
|
50391
|
+
* It is supposed to work autonomously.
|
|
50392
|
+
*
|
|
50393
|
+
* @example
|
|
50394
|
+
* ```ts
|
|
50395
|
+
* import { SourceController } from '@gcorevideo/player'
|
|
50396
|
+
*
|
|
50397
|
+
* Player.registerPlugin(SourceController)
|
|
50398
|
+
* ```
|
|
50399
|
+
*/
|
|
50400
|
+
class SourceController extends CorePlugin {
|
|
50401
|
+
/*
|
|
50402
|
+
* The Logic itself is quite simple:
|
|
50403
|
+
* * Here is the short diagram:
|
|
50404
|
+
*
|
|
50405
|
+
* sources_list:
|
|
50406
|
+
* - a.mpd | +--------------------+
|
|
50407
|
+
* - b.m3u8 |--->| init |
|
|
50408
|
+
* - ... | |--------------------|
|
|
50409
|
+
* | current_source = 0 |
|
|
50410
|
+
* +--------------------+
|
|
50411
|
+
* |
|
|
50412
|
+
* | source = a.mpd
|
|
50413
|
+
* | playback = dash.js
|
|
50414
|
+
* v
|
|
50415
|
+
* +------------------+
|
|
50416
|
+
* +-->| load source |
|
|
50417
|
+
* | +---------|--------+
|
|
50418
|
+
* | v
|
|
50419
|
+
* | +------------------+
|
|
50420
|
+
* | | play |
|
|
50421
|
+
* | +---------|--------+
|
|
50422
|
+
* | |
|
|
50423
|
+
* | v
|
|
50424
|
+
* | +-----------------------+
|
|
50425
|
+
* | | on playback_error |
|
|
50426
|
+
* | |-----------------------|
|
|
50427
|
+
* | | current_source = |
|
|
50428
|
+
* | | (current_source + 1) |
|
|
50429
|
+
* | | % len sources_list |
|
|
50430
|
+
* | | |
|
|
50431
|
+
* | | delay 1..3s |
|
|
50432
|
+
* | +---------------|-------+
|
|
50433
|
+
* | |
|
|
50434
|
+
* | source=b.m3u8 |
|
|
50435
|
+
* | playback=hls.js |
|
|
50436
|
+
* +-------------------+
|
|
50437
|
+
*
|
|
50438
|
+
*/
|
|
50439
|
+
sourcesList = [];
|
|
50440
|
+
currentSourceIndex = 0;
|
|
50441
|
+
sourcesDelay = {};
|
|
50442
|
+
active = false;
|
|
50443
|
+
sync = noSync;
|
|
50444
|
+
/**
|
|
50445
|
+
* @internal
|
|
50446
|
+
*/
|
|
50270
50447
|
get name() {
|
|
50271
|
-
return '
|
|
50448
|
+
return 'source_controller';
|
|
50272
50449
|
}
|
|
50450
|
+
/**
|
|
50451
|
+
* @internal
|
|
50452
|
+
*/
|
|
50273
50453
|
get supportedVersion() {
|
|
50274
50454
|
return { min: CLAPPR_VERSION };
|
|
50275
50455
|
}
|
|
50276
|
-
|
|
50277
|
-
|
|
50278
|
-
|
|
50279
|
-
|
|
50280
|
-
|
|
50281
|
-
|
|
50282
|
-
|
|
50283
|
-
|
|
50284
|
-
|
|
50285
|
-
|
|
50286
|
-
|
|
50456
|
+
constructor(core) {
|
|
50457
|
+
super(core);
|
|
50458
|
+
this.sourcesList = this.core.options.sources;
|
|
50459
|
+
if (this.core.options.source !== undefined) {
|
|
50460
|
+
// prevent Clappr from loading all sources simultaneously
|
|
50461
|
+
this.core.options.sources = [this.core.options.source];
|
|
50462
|
+
}
|
|
50463
|
+
else {
|
|
50464
|
+
this.core.options.sources = this.core.options.sources.slice(0, 1);
|
|
50465
|
+
}
|
|
50466
|
+
}
|
|
50287
50467
|
/**
|
|
50288
|
-
*
|
|
50468
|
+
* @internal
|
|
50289
50469
|
*/
|
|
50290
|
-
bufAccDuration = 0;
|
|
50291
|
-
constructor(container) {
|
|
50292
|
-
super(container);
|
|
50293
|
-
assert(this.options.statistics &&
|
|
50294
|
-
typeof this.options.statistics.send === 'function', 'Statistics plugin requires statistics options');
|
|
50295
|
-
}
|
|
50296
50470
|
bindEvents() {
|
|
50297
|
-
|
|
50298
|
-
this.
|
|
50299
|
-
this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
|
|
50300
|
-
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
50301
|
-
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
|
|
50302
|
-
this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdateLive);
|
|
50303
|
-
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
|
|
50304
|
-
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.stopLevelSwitch);
|
|
50305
|
-
}
|
|
50306
|
-
startLevelSwitch() {
|
|
50307
|
-
this.bufTracking = false;
|
|
50308
|
-
}
|
|
50309
|
-
stopLevelSwitch() {
|
|
50310
|
-
this.bufTracking = true;
|
|
50471
|
+
super.bindEvents();
|
|
50472
|
+
this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
|
|
50311
50473
|
}
|
|
50312
|
-
|
|
50313
|
-
|
|
50314
|
-
this.
|
|
50474
|
+
onReady() {
|
|
50475
|
+
trace(`${T$3} onReady`, {
|
|
50476
|
+
retrying: this.active,
|
|
50477
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
50478
|
+
});
|
|
50479
|
+
const spinner = this.core.activeContainer?.getPlugin('spinner');
|
|
50480
|
+
if (spinner) {
|
|
50481
|
+
this.sync = (cb) => {
|
|
50482
|
+
spinner.once(SpinnerEvents.SYNC, cb);
|
|
50483
|
+
};
|
|
50315
50484
|
}
|
|
50316
|
-
|
|
50317
|
-
|
|
50318
|
-
if (this.bufTracking && this.bufLastStarted) {
|
|
50319
|
-
this.bufAccDuration += performance.now() - this.bufLastStarted;
|
|
50320
|
-
this.lags++;
|
|
50485
|
+
else {
|
|
50486
|
+
this.sync = noSync;
|
|
50321
50487
|
}
|
|
50322
|
-
this.
|
|
50323
|
-
|
|
50324
|
-
|
|
50325
|
-
|
|
50326
|
-
if (this.options.autoPlay) {
|
|
50327
|
-
this.onStart();
|
|
50488
|
+
this.bindContainerEventListeners();
|
|
50489
|
+
if (this.active) {
|
|
50490
|
+
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
50491
|
+
spinner?.show();
|
|
50328
50492
|
}
|
|
50329
50493
|
}
|
|
50330
|
-
|
|
50331
|
-
this.
|
|
50332
|
-
|
|
50333
|
-
|
|
50334
|
-
|
|
50335
|
-
|
|
50336
|
-
|
|
50494
|
+
bindContainerEventListeners() {
|
|
50495
|
+
this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
|
|
50496
|
+
trace(`${T$3} on PLAYBACK_ERROR`, {
|
|
50497
|
+
error: {
|
|
50498
|
+
code: error?.code,
|
|
50499
|
+
description: error?.description,
|
|
50500
|
+
level: error?.level,
|
|
50501
|
+
},
|
|
50502
|
+
retrying: this.active,
|
|
50503
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
50504
|
+
});
|
|
50505
|
+
switch (error.code) {
|
|
50506
|
+
case PlaybackErrorCode.MediaSourceUnavailable:
|
|
50507
|
+
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
50508
|
+
this.retryPlayback();
|
|
50509
|
+
break;
|
|
50510
|
+
}
|
|
50337
50511
|
});
|
|
50338
|
-
|
|
50339
|
-
|
|
50340
|
-
|
|
50341
|
-
|
|
50342
|
-
|
|
50343
|
-
|
|
50512
|
+
this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
|
|
50513
|
+
trace(`${T$3} on PLAYBACK_PLAY`, {
|
|
50514
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
50515
|
+
retrying: this.active,
|
|
50516
|
+
});
|
|
50517
|
+
if (this.active) {
|
|
50518
|
+
this.reset();
|
|
50519
|
+
// TODO make poster reset its state on enable
|
|
50520
|
+
this.core.activeContainer?.getPlugin('poster_custom')?.enable();
|
|
50521
|
+
this.core.activeContainer?.getPlugin('spinner')?.hide();
|
|
50522
|
+
}
|
|
50344
50523
|
});
|
|
50345
50524
|
}
|
|
50346
|
-
|
|
50347
|
-
|
|
50348
|
-
|
|
50349
|
-
lags: this.lags,
|
|
50350
|
-
};
|
|
50351
|
-
this.bufAccDuration = 0;
|
|
50352
|
-
this.lags = 0;
|
|
50353
|
-
if (this.container.getPlaybackType() === Playback.VOD) {
|
|
50354
|
-
res.timestamp = time;
|
|
50355
|
-
}
|
|
50356
|
-
this.send('heatmap', res);
|
|
50357
|
-
this.heatmapSent = true;
|
|
50358
|
-
this.heatmapLastTime = time;
|
|
50525
|
+
reset() {
|
|
50526
|
+
this.active = false;
|
|
50527
|
+
this.sourcesDelay = {};
|
|
50359
50528
|
}
|
|
50360
|
-
|
|
50361
|
-
|
|
50362
|
-
|
|
50363
|
-
this.
|
|
50364
|
-
}
|
|
50365
|
-
|
|
50366
|
-
|
|
50367
|
-
|
|
50368
|
-
|
|
50369
|
-
|
|
50370
|
-
|
|
50371
|
-
|
|
50372
|
-
|
|
50373
|
-
this.
|
|
50374
|
-
|
|
50375
|
-
|
|
50376
|
-
|
|
50377
|
-
|
|
50378
|
-
|
|
50379
|
-
|
|
50529
|
+
retryPlayback() {
|
|
50530
|
+
trace(`${T$3} retryPlayback enter`, {
|
|
50531
|
+
currentSourceIndex: this.currentSourceIndex,
|
|
50532
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
50533
|
+
});
|
|
50534
|
+
this.active = true;
|
|
50535
|
+
this.getNextMediaSource().then((nextSource) => {
|
|
50536
|
+
trace(`${T$3} retryPlayback syncing...`, {
|
|
50537
|
+
nextSource,
|
|
50538
|
+
});
|
|
50539
|
+
const rnd = RETRY_DELAY_BLUR * Math.random();
|
|
50540
|
+
this.sync(() => {
|
|
50541
|
+
trace(`${T$3} retryPlayback loading...`);
|
|
50542
|
+
this.core.load(nextSource.source, nextSource.mimeType);
|
|
50543
|
+
trace(`${T$3} retryPlayback loaded`, {
|
|
50544
|
+
nextSource,
|
|
50545
|
+
});
|
|
50546
|
+
setTimeout(() => {
|
|
50547
|
+
// this.core.activePlayback.consent()
|
|
50548
|
+
this.core.activePlayback.play();
|
|
50549
|
+
trace(`${T$3} retryPlayback playing`);
|
|
50550
|
+
}, rnd);
|
|
50551
|
+
});
|
|
50552
|
+
});
|
|
50380
50553
|
}
|
|
50381
|
-
|
|
50382
|
-
|
|
50383
|
-
|
|
50384
|
-
|
|
50385
|
-
|
|
50386
|
-
|
|
50554
|
+
getNextMediaSource() {
|
|
50555
|
+
return new Promise((resolve) => {
|
|
50556
|
+
this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
|
|
50557
|
+
this.currentSourceIndex =
|
|
50558
|
+
(this.currentSourceIndex + 1) % this.sourcesList.length;
|
|
50559
|
+
const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
|
|
50560
|
+
const s = this.sourcesList[this.currentSourceIndex];
|
|
50561
|
+
setTimeout(() => resolve(s), delay);
|
|
50562
|
+
});
|
|
50563
|
+
}
|
|
50564
|
+
/**
|
|
50565
|
+
* @internal
|
|
50566
|
+
*/
|
|
50567
|
+
static get version() {
|
|
50568
|
+
return VERSION$1;
|
|
50387
50569
|
}
|
|
50388
50570
|
}
|
|
50389
50571
|
|
|
@@ -50395,7 +50577,7 @@ const comboboxHTML = "<button data-subtitles-button class='media-control-button
|
|
|
50395
50577
|
|
|
50396
50578
|
const stringHTML = "<div class=\"subtitle-string\">\n <p></p>\n</div>\n";
|
|
50397
50579
|
|
|
50398
|
-
const VERSION
|
|
50580
|
+
const VERSION = '2.19.14';
|
|
50399
50581
|
const LOCAL_STORAGE_SUBTITLES_ID = 'gplayer.plugins.subtitles.selected';
|
|
50400
50582
|
const T$2 = 'plugins.subtitles';
|
|
50401
50583
|
const NO_TRACK = { language: 'off' };
|
|
@@ -50449,7 +50631,7 @@ class Subtitles extends UICorePlugin {
|
|
|
50449
50631
|
* @internal
|
|
50450
50632
|
*/
|
|
50451
50633
|
static get version() {
|
|
50452
|
-
return VERSION
|
|
50634
|
+
return VERSION;
|
|
50453
50635
|
}
|
|
50454
50636
|
static template = tmpl(comboboxHTML);
|
|
50455
50637
|
static templateString = tmpl(stringHTML);
|
|
@@ -50761,6 +50943,183 @@ class Subtitles extends UICorePlugin {
|
|
|
50761
50943
|
}
|
|
50762
50944
|
}
|
|
50763
50945
|
|
|
50946
|
+
// An example implementation of client side performancestatistics
|
|
50947
|
+
const WATCH_CUTOFF = 5;
|
|
50948
|
+
const STALL_MEASURE_PERIOD = 10;
|
|
50949
|
+
const T$1 = 'plugins.telemetry';
|
|
50950
|
+
/**
|
|
50951
|
+
* Telemetry event type
|
|
50952
|
+
*/
|
|
50953
|
+
var TelemetryEvent;
|
|
50954
|
+
(function (TelemetryEvent) {
|
|
50955
|
+
TelemetryEvent[TelemetryEvent["Init"] = 1] = "Init";
|
|
50956
|
+
TelemetryEvent[TelemetryEvent["Start"] = 2] = "Start";
|
|
50957
|
+
TelemetryEvent[TelemetryEvent["Watch"] = 3] = "Watch";
|
|
50958
|
+
TelemetryEvent[TelemetryEvent["Stall"] = 4] = "Stall";
|
|
50959
|
+
})(TelemetryEvent || (TelemetryEvent = {}));
|
|
50960
|
+
/**
|
|
50961
|
+
* Collects and reports the performance statistics.
|
|
50962
|
+
* @beta
|
|
50963
|
+
* @remarks
|
|
50964
|
+
* This plugin is experimental and its API is likely to change.
|
|
50965
|
+
*
|
|
50966
|
+
* Configuration options {@link TelemetryPluginSettings}
|
|
50967
|
+
*
|
|
50968
|
+
* @example
|
|
50969
|
+
* ```ts
|
|
50970
|
+
* import { Statistics } from '@gcorevideo/player'
|
|
50971
|
+
*
|
|
50972
|
+
* Player.registerPlugin(Statistics)
|
|
50973
|
+
*
|
|
50974
|
+
* const player = new Player({
|
|
50975
|
+
* statistics: {
|
|
50976
|
+
* send: (data) => {
|
|
50977
|
+
* fetch('/stats', {
|
|
50978
|
+
* method: 'POST',
|
|
50979
|
+
* body: JSON.stringify(data),
|
|
50980
|
+
* headers: { 'content-type': 'application/json' },
|
|
50981
|
+
* })
|
|
50982
|
+
* },
|
|
50983
|
+
* },
|
|
50984
|
+
* ...
|
|
50985
|
+
* })
|
|
50986
|
+
* ```
|
|
50987
|
+
*/
|
|
50988
|
+
class Telemetry extends ContainerPlugin {
|
|
50989
|
+
/**
|
|
50990
|
+
* The name of the plugin.
|
|
50991
|
+
*/
|
|
50992
|
+
get name() {
|
|
50993
|
+
return 'telemetry';
|
|
50994
|
+
}
|
|
50995
|
+
/**
|
|
50996
|
+
* The supported version of the plugin.
|
|
50997
|
+
*/
|
|
50998
|
+
get supportedVersion() {
|
|
50999
|
+
return { min: CLAPPR_VERSION };
|
|
51000
|
+
}
|
|
51001
|
+
started = false;
|
|
51002
|
+
timeStart = 0;
|
|
51003
|
+
stallSent = false;
|
|
51004
|
+
stallLastTime = 0;
|
|
51005
|
+
watchSent = false;
|
|
51006
|
+
bufTracking = false;
|
|
51007
|
+
numStalls = 0;
|
|
51008
|
+
/**
|
|
51009
|
+
* The time when buffering last started.
|
|
51010
|
+
*/
|
|
51011
|
+
bufLastStarted = 0;
|
|
51012
|
+
/**
|
|
51013
|
+
* The accumulated buffering duration.
|
|
51014
|
+
*/
|
|
51015
|
+
stallAcc = 0;
|
|
51016
|
+
constructor(container) {
|
|
51017
|
+
super(container);
|
|
51018
|
+
assert(this.options.telemetry &&
|
|
51019
|
+
typeof this.options.telemetry.send === 'function', 'Telemetry plugin configuration is invalid: `send` option is required');
|
|
51020
|
+
}
|
|
51021
|
+
/**
|
|
51022
|
+
* @internal
|
|
51023
|
+
*/
|
|
51024
|
+
bindEvents() {
|
|
51025
|
+
// TODO remove this
|
|
51026
|
+
// this.listenToOnce(
|
|
51027
|
+
// this.container,
|
|
51028
|
+
// CUSTOM_EVENTS_CONTAINER_START,
|
|
51029
|
+
// this.onStart,
|
|
51030
|
+
// )
|
|
51031
|
+
this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
|
|
51032
|
+
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
51033
|
+
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
|
|
51034
|
+
this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
|
|
51035
|
+
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
|
|
51036
|
+
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.endLevelSwitch);
|
|
51037
|
+
}
|
|
51038
|
+
startLevelSwitch() {
|
|
51039
|
+
this.bufTracking = false;
|
|
51040
|
+
}
|
|
51041
|
+
endLevelSwitch() {
|
|
51042
|
+
this.bufTracking = true;
|
|
51043
|
+
}
|
|
51044
|
+
onBuffering() {
|
|
51045
|
+
if (this.bufTracking) {
|
|
51046
|
+
this.bufLastStarted = performance.now();
|
|
51047
|
+
}
|
|
51048
|
+
}
|
|
51049
|
+
onBufferFull() {
|
|
51050
|
+
if (this.bufTracking && this.bufLastStarted) {
|
|
51051
|
+
this.stallAcc += performance.now() - this.bufLastStarted;
|
|
51052
|
+
this.numStalls++;
|
|
51053
|
+
}
|
|
51054
|
+
this.bufTracking = true;
|
|
51055
|
+
}
|
|
51056
|
+
onReady() {
|
|
51057
|
+
this.sendInit();
|
|
51058
|
+
trace(`${T$1} onReady`, {
|
|
51059
|
+
autoPlay: this.options.autoPlay,
|
|
51060
|
+
});
|
|
51061
|
+
if (this.options.autoPlay) {
|
|
51062
|
+
this.onStart();
|
|
51063
|
+
}
|
|
51064
|
+
else {
|
|
51065
|
+
this.listenToOnce(this.container.playback, Events$1.PLAYBACK_PLAY_INTENT, this.onStart);
|
|
51066
|
+
}
|
|
51067
|
+
}
|
|
51068
|
+
sendInit() {
|
|
51069
|
+
this.send({ event: TelemetryEvent.Init });
|
|
51070
|
+
}
|
|
51071
|
+
send(event) {
|
|
51072
|
+
this.options.telemetry.send({
|
|
51073
|
+
type: this.container.getPlaybackType(),
|
|
51074
|
+
...event,
|
|
51075
|
+
});
|
|
51076
|
+
}
|
|
51077
|
+
sendStall(time) {
|
|
51078
|
+
// TODO don't send if no stalls?
|
|
51079
|
+
const res = {
|
|
51080
|
+
event: TelemetryEvent.Stall,
|
|
51081
|
+
count: this.numStalls,
|
|
51082
|
+
time,
|
|
51083
|
+
total_ms: Math.round(this.stallAcc * 1000),
|
|
51084
|
+
};
|
|
51085
|
+
this.stallAcc = 0;
|
|
51086
|
+
this.numStalls = 0;
|
|
51087
|
+
this.send(res);
|
|
51088
|
+
this.stallSent = true;
|
|
51089
|
+
this.stallLastTime = time;
|
|
51090
|
+
}
|
|
51091
|
+
onTimeUpdate({ current }) {
|
|
51092
|
+
if (!this.timeStart) {
|
|
51093
|
+
this.timeStart = current;
|
|
51094
|
+
}
|
|
51095
|
+
try {
|
|
51096
|
+
const elapsed = current - this.timeStart;
|
|
51097
|
+
const stallElapsed = current - this.stallLastTime;
|
|
51098
|
+
if (!this.stallSent || stallElapsed >= STALL_MEASURE_PERIOD) {
|
|
51099
|
+
this.sendStall(current);
|
|
51100
|
+
}
|
|
51101
|
+
if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
|
|
51102
|
+
this.watchSent = true;
|
|
51103
|
+
this.send({
|
|
51104
|
+
event: TelemetryEvent.Watch,
|
|
51105
|
+
});
|
|
51106
|
+
}
|
|
51107
|
+
}
|
|
51108
|
+
catch (error) {
|
|
51109
|
+
reportError(error);
|
|
51110
|
+
}
|
|
51111
|
+
}
|
|
51112
|
+
onStart() {
|
|
51113
|
+
if (this.started) {
|
|
51114
|
+
return;
|
|
51115
|
+
}
|
|
51116
|
+
this.started = true;
|
|
51117
|
+
this.send({
|
|
51118
|
+
event: TelemetryEvent.Start,
|
|
51119
|
+
});
|
|
51120
|
+
}
|
|
51121
|
+
}
|
|
51122
|
+
|
|
50764
51123
|
var parseSrt$1 = {exports: {}};
|
|
50765
51124
|
|
|
50766
51125
|
var parseSrt = parseSrt$1.exports;
|
|
@@ -50877,7 +51236,7 @@ const parseSRT = /*@__PURE__*/getDefaultExportFromCjs$1(parseSrtExports);
|
|
|
50877
51236
|
|
|
50878
51237
|
const pluginHtml = "<div class=\"thumbnails-text\"></div>\n<% if (backdropHeight) { %>\n <div class=\"backdrop\" style=\"height: <%= backdropHeight %>px;\">\n <div class=\"carousel\"></div>\n </div>\n<% }; %>\n<% if (spotlightHeight) { %>\n <div class=\"spotlight\" style=\"height: <%= spotlightHeight %>px;\">\n </div>\n<% }; %>\n";
|
|
50879
51238
|
|
|
50880
|
-
const T
|
|
51239
|
+
const T = 'plugins.media_control_thumbnails';
|
|
50881
51240
|
class Thumbnails extends UICorePlugin {
|
|
50882
51241
|
_$spotlight = null;
|
|
50883
51242
|
_$backdrop = null;
|
|
@@ -51148,7 +51507,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
51148
51507
|
// calculate how far along the carousel should currently be slid
|
|
51149
51508
|
// depending on where the user is hovering on the progress bar
|
|
51150
51509
|
_updateCarousel() {
|
|
51151
|
-
trace(`${T
|
|
51510
|
+
trace(`${T} _updateCarousel`, {
|
|
51152
51511
|
backdropHeight: this._getOptions().backdropHeight,
|
|
51153
51512
|
});
|
|
51154
51513
|
if (!this._getOptions().backdropHeight) {
|
|
@@ -51207,7 +51566,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
51207
51566
|
}
|
|
51208
51567
|
}
|
|
51209
51568
|
_updateSpotlightThumb() {
|
|
51210
|
-
trace(`${T
|
|
51569
|
+
trace(`${T} _updateSpotlightThumb`, {
|
|
51211
51570
|
spotlightHeight: this._getOptions().spotlightHeight,
|
|
51212
51571
|
});
|
|
51213
51572
|
if (!this._getOptions().spotlightHeight) {
|
|
@@ -51252,7 +51611,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
51252
51611
|
return 0;
|
|
51253
51612
|
}
|
|
51254
51613
|
_renderPlugin() {
|
|
51255
|
-
trace(`${T
|
|
51614
|
+
trace(`${T} _renderPlugin`, {
|
|
51256
51615
|
show: this._show,
|
|
51257
51616
|
thumbsLoaded: this._thumbsLoaded,
|
|
51258
51617
|
thumbs: this._thumbs.length,
|
|
@@ -51270,7 +51629,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
51270
51629
|
}
|
|
51271
51630
|
}
|
|
51272
51631
|
_createElements() {
|
|
51273
|
-
trace(`${T
|
|
51632
|
+
trace(`${T} _createElements`);
|
|
51274
51633
|
this.$el.html(this.template({
|
|
51275
51634
|
'backdropHeight': this._getOptions().backdropHeight,
|
|
51276
51635
|
'spotlightHeight': this._getOptions().spotlightHeight
|
|
@@ -51285,203 +51644,6 @@ class Thumbnails extends UICorePlugin {
|
|
|
51285
51644
|
}
|
|
51286
51645
|
}
|
|
51287
51646
|
|
|
51288
|
-
const T = 'plugins.source_controller';
|
|
51289
|
-
const INITIAL_RETRY_DELAY = 1000;
|
|
51290
|
-
const MAX_RETRY_DELAY = 5000;
|
|
51291
|
-
const RETRY_DELAY_BLUR = 500;
|
|
51292
|
-
const VERSION = '0.0.1';
|
|
51293
|
-
function noSync(cb) {
|
|
51294
|
-
queueMicrotask(cb);
|
|
51295
|
-
}
|
|
51296
|
-
/**
|
|
51297
|
-
* This plugin is responsible for managing the automatic failover between sources.
|
|
51298
|
-
* @beta
|
|
51299
|
-
* @remarks
|
|
51300
|
-
* Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
|
|
51301
|
-
* on how sources ordering and selection works.
|
|
51302
|
-
*
|
|
51303
|
-
* This plugin does not expose any public methods apart from required by the Clappr plugin interface.
|
|
51304
|
-
* It is supposed to work autonomously.
|
|
51305
|
-
*
|
|
51306
|
-
* @example
|
|
51307
|
-
* ```ts
|
|
51308
|
-
* import { SourceController } from '@gcorevideo/player'
|
|
51309
|
-
*
|
|
51310
|
-
* Player.registerPlugin(SourceController)
|
|
51311
|
-
* ```
|
|
51312
|
-
*/
|
|
51313
|
-
class SourceController extends CorePlugin {
|
|
51314
|
-
/*
|
|
51315
|
-
* The Logic itself is quite simple:
|
|
51316
|
-
* * Here is the short diagram:
|
|
51317
|
-
*
|
|
51318
|
-
* sources_list:
|
|
51319
|
-
* - a.mpd | +--------------------+
|
|
51320
|
-
* - b.m3u8 |--->| init |
|
|
51321
|
-
* - ... | |--------------------|
|
|
51322
|
-
* | current_source = 0 |
|
|
51323
|
-
* +--------------------+
|
|
51324
|
-
* |
|
|
51325
|
-
* | source = a.mpd
|
|
51326
|
-
* | playback = dash.js
|
|
51327
|
-
* v
|
|
51328
|
-
* +------------------+
|
|
51329
|
-
* +-->| load source |
|
|
51330
|
-
* | +---------|--------+
|
|
51331
|
-
* | v
|
|
51332
|
-
* | +------------------+
|
|
51333
|
-
* | | play |
|
|
51334
|
-
* | +---------|--------+
|
|
51335
|
-
* | |
|
|
51336
|
-
* | v
|
|
51337
|
-
* | +-----------------------+
|
|
51338
|
-
* | | on playback_error |
|
|
51339
|
-
* | |-----------------------|
|
|
51340
|
-
* | | current_source = |
|
|
51341
|
-
* | | (current_source + 1) |
|
|
51342
|
-
* | | % len sources_list |
|
|
51343
|
-
* | | |
|
|
51344
|
-
* | | delay 1..3s |
|
|
51345
|
-
* | +---------------|-------+
|
|
51346
|
-
* | |
|
|
51347
|
-
* | source=b.m3u8 |
|
|
51348
|
-
* | playback=hls.js |
|
|
51349
|
-
* +-------------------+
|
|
51350
|
-
*
|
|
51351
|
-
*/
|
|
51352
|
-
sourcesList = [];
|
|
51353
|
-
currentSourceIndex = 0;
|
|
51354
|
-
sourcesDelay = {};
|
|
51355
|
-
active = false;
|
|
51356
|
-
sync = noSync;
|
|
51357
|
-
/**
|
|
51358
|
-
* @internal
|
|
51359
|
-
*/
|
|
51360
|
-
get name() {
|
|
51361
|
-
return 'source_controller';
|
|
51362
|
-
}
|
|
51363
|
-
/**
|
|
51364
|
-
* @internal
|
|
51365
|
-
*/
|
|
51366
|
-
get supportedVersion() {
|
|
51367
|
-
return { min: CLAPPR_VERSION };
|
|
51368
|
-
}
|
|
51369
|
-
constructor(core) {
|
|
51370
|
-
super(core);
|
|
51371
|
-
this.sourcesList = this.core.options.sources;
|
|
51372
|
-
if (this.core.options.source !== undefined) {
|
|
51373
|
-
// prevent Clappr from loading all sources simultaneously
|
|
51374
|
-
this.core.options.sources = [this.core.options.source];
|
|
51375
|
-
}
|
|
51376
|
-
else {
|
|
51377
|
-
this.core.options.sources = this.core.options.sources.slice(0, 1);
|
|
51378
|
-
}
|
|
51379
|
-
}
|
|
51380
|
-
/**
|
|
51381
|
-
* @internal
|
|
51382
|
-
*/
|
|
51383
|
-
bindEvents() {
|
|
51384
|
-
super.bindEvents();
|
|
51385
|
-
this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
|
|
51386
|
-
}
|
|
51387
|
-
onReady() {
|
|
51388
|
-
trace(`${T} onReady`, {
|
|
51389
|
-
retrying: this.active,
|
|
51390
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
51391
|
-
});
|
|
51392
|
-
const spinner = this.core.activeContainer?.getPlugin('spinner');
|
|
51393
|
-
if (spinner) {
|
|
51394
|
-
this.sync = (cb) => {
|
|
51395
|
-
spinner.once(SpinnerEvents.SYNC, cb);
|
|
51396
|
-
};
|
|
51397
|
-
}
|
|
51398
|
-
else {
|
|
51399
|
-
this.sync = noSync;
|
|
51400
|
-
}
|
|
51401
|
-
this.bindContainerEventListeners();
|
|
51402
|
-
if (this.active) {
|
|
51403
|
-
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
51404
|
-
spinner?.show();
|
|
51405
|
-
}
|
|
51406
|
-
}
|
|
51407
|
-
bindContainerEventListeners() {
|
|
51408
|
-
this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
|
|
51409
|
-
trace(`${T} on PLAYBACK_ERROR`, {
|
|
51410
|
-
error: {
|
|
51411
|
-
code: error?.code,
|
|
51412
|
-
description: error?.description,
|
|
51413
|
-
level: error?.level,
|
|
51414
|
-
},
|
|
51415
|
-
retrying: this.active,
|
|
51416
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
51417
|
-
});
|
|
51418
|
-
switch (error.code) {
|
|
51419
|
-
case PlaybackErrorCode.MediaSourceUnavailable:
|
|
51420
|
-
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
51421
|
-
this.retryPlayback();
|
|
51422
|
-
break;
|
|
51423
|
-
}
|
|
51424
|
-
});
|
|
51425
|
-
this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
|
|
51426
|
-
trace(`${T} on PLAYBACK_PLAY`, {
|
|
51427
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
51428
|
-
retrying: this.active,
|
|
51429
|
-
});
|
|
51430
|
-
if (this.active) {
|
|
51431
|
-
this.reset();
|
|
51432
|
-
// TODO make poster reset its state on enable
|
|
51433
|
-
this.core.activeContainer?.getPlugin('poster_custom')?.enable();
|
|
51434
|
-
this.core.activeContainer?.getPlugin('spinner')?.hide();
|
|
51435
|
-
}
|
|
51436
|
-
});
|
|
51437
|
-
}
|
|
51438
|
-
reset() {
|
|
51439
|
-
this.active = false;
|
|
51440
|
-
this.sourcesDelay = {};
|
|
51441
|
-
}
|
|
51442
|
-
retryPlayback() {
|
|
51443
|
-
trace(`${T} retryPlayback enter`, {
|
|
51444
|
-
currentSourceIndex: this.currentSourceIndex,
|
|
51445
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
51446
|
-
});
|
|
51447
|
-
this.active = true;
|
|
51448
|
-
this.getNextMediaSource().then((nextSource) => {
|
|
51449
|
-
trace(`${T} retryPlayback syncing...`, {
|
|
51450
|
-
nextSource,
|
|
51451
|
-
});
|
|
51452
|
-
const rnd = RETRY_DELAY_BLUR * Math.random();
|
|
51453
|
-
this.sync(() => {
|
|
51454
|
-
trace(`${T} retryPlayback loading...`);
|
|
51455
|
-
this.core.load(nextSource.source, nextSource.mimeType);
|
|
51456
|
-
trace(`${T} retryPlayback loaded`, {
|
|
51457
|
-
nextSource,
|
|
51458
|
-
});
|
|
51459
|
-
setTimeout(() => {
|
|
51460
|
-
// this.core.activePlayback.consent()
|
|
51461
|
-
this.core.activePlayback.play();
|
|
51462
|
-
trace(`${T} retryPlayback playing`);
|
|
51463
|
-
}, rnd);
|
|
51464
|
-
});
|
|
51465
|
-
});
|
|
51466
|
-
}
|
|
51467
|
-
getNextMediaSource() {
|
|
51468
|
-
return new Promise((resolve) => {
|
|
51469
|
-
this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
|
|
51470
|
-
this.currentSourceIndex =
|
|
51471
|
-
(this.currentSourceIndex + 1) % this.sourcesList.length;
|
|
51472
|
-
const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
|
|
51473
|
-
const s = this.sourcesList[this.currentSourceIndex];
|
|
51474
|
-
setTimeout(() => resolve(s), delay);
|
|
51475
|
-
});
|
|
51476
|
-
}
|
|
51477
|
-
/**
|
|
51478
|
-
* @internal
|
|
51479
|
-
*/
|
|
51480
|
-
static get version() {
|
|
51481
|
-
return VERSION;
|
|
51482
|
-
}
|
|
51483
|
-
}
|
|
51484
|
-
|
|
51485
51647
|
var VolumeFadeEvents;
|
|
51486
51648
|
(function (VolumeFadeEvents) {
|
|
51487
51649
|
VolumeFadeEvents["FADE"] = "core:volume:fade";
|
|
@@ -51494,15 +51656,22 @@ class VolumeFade extends UICorePlugin {
|
|
|
51494
51656
|
container = null;
|
|
51495
51657
|
delay = 0;
|
|
51496
51658
|
interval = null;
|
|
51659
|
+
/**
|
|
51660
|
+
* @internal
|
|
51661
|
+
*/
|
|
51497
51662
|
get name() {
|
|
51498
51663
|
return 'volume_fade';
|
|
51499
51664
|
}
|
|
51665
|
+
/**
|
|
51666
|
+
* @internal
|
|
51667
|
+
*/
|
|
51500
51668
|
bindEvents() {
|
|
51669
|
+
// TODO on container changed
|
|
51501
51670
|
this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
|
|
51502
51671
|
if (this.core.mediaControl) {
|
|
51503
51672
|
this.listenTo(this.core.mediaControl, 'mediacontrol:volume:user', this._onUserChangeVolume);
|
|
51504
51673
|
}
|
|
51505
|
-
this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
|
|
51674
|
+
// this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
|
|
51506
51675
|
}
|
|
51507
51676
|
unBindEvents() {
|
|
51508
51677
|
this.core.$el.off('mouseleave.volume');
|
|
@@ -51574,4 +51743,4 @@ class VolumeFade extends UICorePlugin {
|
|
|
51574
51743
|
}
|
|
51575
51744
|
}
|
|
51576
51745
|
|
|
51577
|
-
export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DisableControls, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, LogTracer, Logger, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackErrorCode, PlaybackRate, Player, PlayerEvent, Poster, SeekTime, SentryTracer, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce,
|
|
51746
|
+
export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DisableControls, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, LogTracer, Logger, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackErrorCode, PlaybackRate, Player, PlayerEvent, Poster, SeekTime, SentryTracer, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents, reportError, setTracer, trace, version };
|