@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/plugins/index.js
CHANGED
|
@@ -31717,7 +31717,7 @@ const volumeOffIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
|
|
|
31717
31717
|
|
|
31718
31718
|
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";
|
|
31719
31719
|
|
|
31720
|
-
const T$
|
|
31720
|
+
const T$9 = "plugins.big_mute_button";
|
|
31721
31721
|
/**
|
|
31722
31722
|
* @beta
|
|
31723
31723
|
*/
|
|
@@ -31746,7 +31746,7 @@ class BigMuteButton extends UICorePlugin {
|
|
|
31746
31746
|
this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
|
|
31747
31747
|
this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
|
|
31748
31748
|
this.listenTo(this.core, 'core:advertisement:finish', this.onFinishAd);
|
|
31749
|
-
trace(`${T$
|
|
31749
|
+
trace(`${T$9} bindEvents`, {
|
|
31750
31750
|
mediacontrol: !!this.core.mediaControl,
|
|
31751
31751
|
});
|
|
31752
31752
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.mediaControlRendered);
|
|
@@ -31811,7 +31811,7 @@ class BigMuteButton extends UICorePlugin {
|
|
|
31811
31811
|
}
|
|
31812
31812
|
render() {
|
|
31813
31813
|
if (this.shouldRender()) {
|
|
31814
|
-
trace(`${T$
|
|
31814
|
+
trace(`${T$9} render`, {
|
|
31815
31815
|
el: !!this.$el,
|
|
31816
31816
|
});
|
|
31817
31817
|
this.$el.html(this.template());
|
|
@@ -34962,7 +34962,7 @@ const qualityClasses = [
|
|
|
34962
34962
|
'speedtest-quality-value-2',
|
|
34963
34963
|
'speedtest-quality-value-3',
|
|
34964
34964
|
'speedtest-quality-value-4',
|
|
34965
|
-
'speedtest-quality-value-5'
|
|
34965
|
+
'speedtest-quality-value-5',
|
|
34966
34966
|
];
|
|
34967
34967
|
const getDownloadQuality = (speedValue) => {
|
|
34968
34968
|
if (speedValue < 3) {
|
|
@@ -35026,7 +35026,22 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
|
|
|
35026
35026
|
};
|
|
35027
35027
|
// const T = 'plugins.clappr_nerd_stats';
|
|
35028
35028
|
/**
|
|
35029
|
+
* Displays useful network-related statistics.
|
|
35029
35030
|
* @beta
|
|
35031
|
+
*
|
|
35032
|
+
* @remarks
|
|
35033
|
+
* Depends on:
|
|
35034
|
+
*
|
|
35035
|
+
* - {@link MediaControl}
|
|
35036
|
+
*
|
|
35037
|
+
* - {@link BottomGear}
|
|
35038
|
+
*
|
|
35039
|
+
* - {@link ClapprStats}
|
|
35040
|
+
*
|
|
35041
|
+
* The plugin is rendered as an item in the gear menu.
|
|
35042
|
+
*
|
|
35043
|
+
* When clicked, it shows an overlay window with the information about the network speed, latency, etc,
|
|
35044
|
+
* and recommended quality level.
|
|
35030
35045
|
*/
|
|
35031
35046
|
class ClapprNerdStats extends UICorePlugin {
|
|
35032
35047
|
container = null;
|
|
@@ -35039,21 +35054,31 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35039
35054
|
showing = false;
|
|
35040
35055
|
shortcut;
|
|
35041
35056
|
iconPosition;
|
|
35057
|
+
/**
|
|
35058
|
+
* @internal
|
|
35059
|
+
*/
|
|
35042
35060
|
get name() {
|
|
35043
35061
|
return 'nerd_stats';
|
|
35044
35062
|
}
|
|
35063
|
+
/**
|
|
35064
|
+
* @internal
|
|
35065
|
+
*/
|
|
35045
35066
|
get supportedVersion() {
|
|
35046
35067
|
return { min: CLAPPR_VERSION };
|
|
35047
35068
|
}
|
|
35048
|
-
|
|
35049
|
-
|
|
35050
|
-
|
|
35069
|
+
static template = tmpl(pluginHtml$5);
|
|
35070
|
+
/**
|
|
35071
|
+
* @internal
|
|
35072
|
+
*/
|
|
35051
35073
|
get attributes() {
|
|
35052
35074
|
return {
|
|
35053
35075
|
'data-clappr-nerd-stats': '',
|
|
35054
|
-
|
|
35076
|
+
class: 'clappr-nerd-stats',
|
|
35055
35077
|
};
|
|
35056
35078
|
}
|
|
35079
|
+
/**
|
|
35080
|
+
* @internal
|
|
35081
|
+
*/
|
|
35057
35082
|
get events() {
|
|
35058
35083
|
return {
|
|
35059
35084
|
'click [data-show-stats-button]': 'showOrHide',
|
|
@@ -35075,8 +35100,12 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35075
35100
|
}
|
|
35076
35101
|
constructor(core) {
|
|
35077
35102
|
super(core);
|
|
35078
|
-
this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
|
|
35079
|
-
|
|
35103
|
+
this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
|
|
35104
|
+
'command+shift+s',
|
|
35105
|
+
'ctrl+shift+s',
|
|
35106
|
+
];
|
|
35107
|
+
this.iconPosition =
|
|
35108
|
+
core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
|
|
35080
35109
|
this.customMetrics = {
|
|
35081
35110
|
connectionSpeed: 0,
|
|
35082
35111
|
ping: 0,
|
|
@@ -35084,6 +35113,9 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35084
35113
|
};
|
|
35085
35114
|
configureSpeedTest(core.options.clapprNerdStats?.speedTestServers ?? []);
|
|
35086
35115
|
}
|
|
35116
|
+
/**
|
|
35117
|
+
* @internal
|
|
35118
|
+
*/
|
|
35087
35119
|
bindEvents() {
|
|
35088
35120
|
const mediaControl = this.core.getPlugin('media_control');
|
|
35089
35121
|
assert(mediaControl, 'media_control plugin is required');
|
|
@@ -35120,9 +35152,11 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35120
35152
|
this.core.$el.find(this.statsBoxElem).show();
|
|
35121
35153
|
this.showing = true;
|
|
35122
35154
|
this.refreshSpeedTest();
|
|
35123
|
-
initSpeedTest(this.customMetrics)
|
|
35155
|
+
initSpeedTest(this.customMetrics)
|
|
35156
|
+
.then(() => {
|
|
35124
35157
|
startSpeedtest();
|
|
35125
|
-
})
|
|
35158
|
+
})
|
|
35159
|
+
.catch((e) => {
|
|
35126
35160
|
this.disable();
|
|
35127
35161
|
});
|
|
35128
35162
|
}
|
|
@@ -35136,13 +35170,19 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35136
35170
|
}
|
|
35137
35171
|
addGeneralMetrics() {
|
|
35138
35172
|
this.metrics.general = {
|
|
35139
|
-
displayResolution:
|
|
35140
|
-
volume: this.container?.volume
|
|
35173
|
+
displayResolution: this.playerWidth + 'x' + this.playerHeight,
|
|
35174
|
+
volume: this.container?.volume,
|
|
35141
35175
|
};
|
|
35142
35176
|
}
|
|
35143
35177
|
addCustomMetrics() {
|
|
35144
35178
|
this.metrics.custom = this.customMetrics;
|
|
35145
|
-
const videoQualityNames = [
|
|
35179
|
+
const videoQualityNames = [
|
|
35180
|
+
'SD (480p)',
|
|
35181
|
+
'HD (720p)',
|
|
35182
|
+
'Full HD (1080p)',
|
|
35183
|
+
'2K (1440p)',
|
|
35184
|
+
'4K (2160p)',
|
|
35185
|
+
];
|
|
35146
35186
|
const { connectionSpeed, ping } = this.customMetrics;
|
|
35147
35187
|
if (!connectionSpeed || !ping) {
|
|
35148
35188
|
const calculatingText = 'Calculating... Please wait.';
|
|
@@ -35154,17 +35194,19 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35154
35194
|
const pingQuality = getPingQuality(ping);
|
|
35155
35195
|
const liveQuality = Math.min(downloadQuality, pingQuality);
|
|
35156
35196
|
const prefix = 'Optimal for ';
|
|
35157
|
-
this.metrics.custom.vodQuality =
|
|
35158
|
-
|
|
35197
|
+
this.metrics.custom.vodQuality =
|
|
35198
|
+
prefix + videoQualityNames[downloadQuality - 1];
|
|
35199
|
+
this.metrics.custom.liveQuality =
|
|
35200
|
+
prefix + videoQualityNames[liveQuality - 1];
|
|
35159
35201
|
}
|
|
35160
35202
|
updateMetrics(metrics) {
|
|
35161
35203
|
Object.assign(this.metrics, metrics);
|
|
35162
35204
|
this.addGeneralMetrics();
|
|
35163
35205
|
this.addCustomMetrics();
|
|
35164
35206
|
const scrollTop = this.core.$el.find(this.statsBoxElem).scrollTop();
|
|
35165
|
-
this.$el.html(
|
|
35207
|
+
this.$el.html(ClapprNerdStats.template({
|
|
35166
35208
|
metrics: Formatter.format(this.metrics),
|
|
35167
|
-
iconPosition: this.iconPosition
|
|
35209
|
+
iconPosition: this.iconPosition,
|
|
35168
35210
|
}));
|
|
35169
35211
|
this.setStatsBoxSize();
|
|
35170
35212
|
drawSpeedTestResults();
|
|
@@ -35184,7 +35226,11 @@ class ClapprNerdStats extends UICorePlugin {
|
|
|
35184
35226
|
this.$el.find(this.statsBoxElem).addClass('narrow');
|
|
35185
35227
|
}
|
|
35186
35228
|
}
|
|
35229
|
+
/**
|
|
35230
|
+
* @internal
|
|
35231
|
+
*/
|
|
35187
35232
|
render() {
|
|
35233
|
+
// TODO append to the container
|
|
35188
35234
|
this.core.$el.append(this.$el[0]);
|
|
35189
35235
|
this.hide();
|
|
35190
35236
|
return this;
|
|
@@ -35986,8 +36032,11 @@ const dvrHTML = "<div class=\"live-info\"><%= live %></div>\n<button type=\"butt
|
|
|
35986
36032
|
* @beta
|
|
35987
36033
|
*
|
|
35988
36034
|
* @remarks
|
|
35989
|
-
*
|
|
35990
|
-
*
|
|
36035
|
+
* Depends on:
|
|
36036
|
+
*
|
|
36037
|
+
* - {@link MediaControl | media_control}
|
|
36038
|
+
*
|
|
36039
|
+
* The plugin renders the live stream indicator and the DVR seek bar, if DVR is enabled, in the media control UI.
|
|
35991
36040
|
*/
|
|
35992
36041
|
class DvrControls extends UICorePlugin {
|
|
35993
36042
|
static template = tmpl(dvrHTML);
|
|
@@ -36122,6 +36171,11 @@ const templateHtml = "<div class=\"player-error-screen__content\" data-error-scr
|
|
|
36122
36171
|
|
|
36123
36172
|
const TIME_FOR_UPDATE = 10000;
|
|
36124
36173
|
const MAX_RETRY = 10;
|
|
36174
|
+
/**
|
|
36175
|
+
* Displays a descriptive error in the overlay on top of the player.
|
|
36176
|
+
* @beta
|
|
36177
|
+
* TODO
|
|
36178
|
+
*/
|
|
36125
36179
|
class ErrorScreen extends UICorePlugin {
|
|
36126
36180
|
_retry = 0;
|
|
36127
36181
|
err = null;
|
|
@@ -36711,7 +36765,7 @@ function keyName(keyCode) {
|
|
|
36711
36765
|
|
|
36712
36766
|
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";
|
|
36713
36767
|
|
|
36714
|
-
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.
|
|
36768
|
+
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";
|
|
36715
36769
|
|
|
36716
36770
|
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";
|
|
36717
36771
|
|
|
@@ -36721,7 +36775,7 @@ const arrowLeftIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fil
|
|
|
36721
36775
|
|
|
36722
36776
|
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";
|
|
36723
36777
|
|
|
36724
|
-
const T$
|
|
36778
|
+
const T$8 = 'plugins.level_selector';
|
|
36725
36779
|
const VERSION$4 = '2.19.4';
|
|
36726
36780
|
/**
|
|
36727
36781
|
* A {@link MediaControl | media control} plugin that provides a UI to control the quality level of the playback.
|
|
@@ -36825,7 +36879,7 @@ class LevelSelector extends UICorePlugin {
|
|
|
36825
36879
|
onStop() {
|
|
36826
36880
|
const currentPlayback = this.core.activePlayback;
|
|
36827
36881
|
this.listenToOnce(currentPlayback, Events$1.PLAYBACK_PLAY, () => {
|
|
36828
|
-
trace(`${T$
|
|
36882
|
+
trace(`${T$8} on PLAYBACK_PLAY after stop`, { selectedLevelId: this.selectedLevelId });
|
|
36829
36883
|
if (currentPlayback.getPlaybackType() === 'live') {
|
|
36830
36884
|
if (this.selectedLevelId !== -1) {
|
|
36831
36885
|
currentPlayback.currentLevel = this.selectedLevelId;
|
|
@@ -36980,7 +37034,7 @@ class LevelSelector extends UICorePlugin {
|
|
|
36980
37034
|
this.highlightCurrentLevel();
|
|
36981
37035
|
}
|
|
36982
37036
|
highlightCurrentLevel() {
|
|
36983
|
-
trace(`${T$
|
|
37037
|
+
trace(`${T$8} highlightCurrentLevel`, {
|
|
36984
37038
|
selectedLevelId: this.selectedLevelId,
|
|
36985
37039
|
});
|
|
36986
37040
|
this.allLevelElements().removeClass('current');
|
|
@@ -38305,7 +38359,7 @@ const streamsMomentoIcon = "<svg id=\"Слой_1\" data-name=\"Слой 1\" xmln
|
|
|
38305
38359
|
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";
|
|
38306
38360
|
|
|
38307
38361
|
const VERSION$3 = '0.0.1';
|
|
38308
|
-
const T$
|
|
38362
|
+
const T$7 = 'plugins.media_control_multicamera';
|
|
38309
38363
|
class MultiCamera extends UICorePlugin {
|
|
38310
38364
|
currentCamera = null;
|
|
38311
38365
|
currentTime = 0;
|
|
@@ -38574,7 +38628,7 @@ class MultiCamera extends UICorePlugin {
|
|
|
38574
38628
|
// TODO figure out what this does
|
|
38575
38629
|
playbackOptions.recycleVideo = Browser.isMobile;
|
|
38576
38630
|
this.currentCamera = this.findElementById(id) ?? null;
|
|
38577
|
-
trace(`${T$
|
|
38631
|
+
trace(`${T$7} changeById`, { currentCamera: this.currentCamera, multicamera: this.multicamera });
|
|
38578
38632
|
if (!this.currentCamera) {
|
|
38579
38633
|
return;
|
|
38580
38634
|
}
|
|
@@ -38590,7 +38644,7 @@ class MultiCamera extends UICorePlugin {
|
|
|
38590
38644
|
// TODO remove?
|
|
38591
38645
|
// for html5 playback:
|
|
38592
38646
|
this.options.dvrEnabled = this.currentCamera.dvr;
|
|
38593
|
-
trace(`${T$
|
|
38647
|
+
trace(`${T$7} changeById`, { currentCamera: this.currentCamera });
|
|
38594
38648
|
// TODO
|
|
38595
38649
|
this.core.configure({
|
|
38596
38650
|
playback: playbackOptions,
|
|
@@ -38648,17 +38702,39 @@ const pipIcon = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"no
|
|
|
38648
38702
|
const buttonHtml$1 = "<button class=\"gplayer-lite-btn gcore-skin-button-color\">\n <span><%= pipIcon %></span>\n</button>\n";
|
|
38649
38703
|
|
|
38650
38704
|
const VERSION$2 = '0.0.1';
|
|
38651
|
-
const T$
|
|
38705
|
+
const T$6 = `plugins.pip`;
|
|
38706
|
+
/**
|
|
38707
|
+
* Enables picture in picture mode.
|
|
38708
|
+
* @beta
|
|
38709
|
+
* @remarks
|
|
38710
|
+
* Depends on:
|
|
38711
|
+
*
|
|
38712
|
+
* - {@link MediaControl}
|
|
38713
|
+
*
|
|
38714
|
+
* It renders a button to toggle picture in picture mode in the media control UI.
|
|
38715
|
+
*/
|
|
38652
38716
|
class PictureInPicture extends UICorePlugin {
|
|
38717
|
+
/**
|
|
38718
|
+
* @internal
|
|
38719
|
+
*/
|
|
38653
38720
|
get name() {
|
|
38654
|
-
return '
|
|
38721
|
+
return 'pip';
|
|
38655
38722
|
}
|
|
38723
|
+
/**
|
|
38724
|
+
* @internal
|
|
38725
|
+
*/
|
|
38656
38726
|
get supportedVersion() {
|
|
38657
38727
|
return { min: CLAPPR_VERSION };
|
|
38658
38728
|
}
|
|
38729
|
+
/**
|
|
38730
|
+
* @internal
|
|
38731
|
+
*/
|
|
38659
38732
|
static get version() {
|
|
38660
38733
|
return VERSION$2;
|
|
38661
38734
|
}
|
|
38735
|
+
/**
|
|
38736
|
+
* @internal
|
|
38737
|
+
*/
|
|
38662
38738
|
get events() {
|
|
38663
38739
|
return {
|
|
38664
38740
|
'click button': 'togglePictureInPicture',
|
|
@@ -38667,12 +38743,18 @@ class PictureInPicture extends UICorePlugin {
|
|
|
38667
38743
|
get videoElement() {
|
|
38668
38744
|
return this.core.activePlayback.el;
|
|
38669
38745
|
}
|
|
38746
|
+
/**
|
|
38747
|
+
* @internal
|
|
38748
|
+
*/
|
|
38670
38749
|
bindEvents() {
|
|
38671
38750
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_RENDERED, this.render);
|
|
38672
38751
|
}
|
|
38673
38752
|
isPiPSupported() {
|
|
38674
38753
|
return document.pictureInPictureEnabled && !!HTMLVideoElement.prototype.requestPictureInPicture;
|
|
38675
38754
|
}
|
|
38755
|
+
/**
|
|
38756
|
+
* @internal
|
|
38757
|
+
*/
|
|
38676
38758
|
render() {
|
|
38677
38759
|
if (!this.isPiPSupported()) {
|
|
38678
38760
|
return this;
|
|
@@ -38694,7 +38776,7 @@ class PictureInPicture extends UICorePlugin {
|
|
|
38694
38776
|
}
|
|
38695
38777
|
}
|
|
38696
38778
|
requestPictureInPicture() {
|
|
38697
|
-
trace(`${T$
|
|
38779
|
+
trace(`${T$6} requestPictureInPicture`, {
|
|
38698
38780
|
videoElement: !!this.videoElement,
|
|
38699
38781
|
});
|
|
38700
38782
|
this.videoElement.requestPictureInPicture();
|
|
@@ -38724,26 +38806,51 @@ const DEFAULT_PLAYBACK_RATES = [
|
|
|
38724
38806
|
const DEFAULT_PLAYBACK_RATE = '1.0';
|
|
38725
38807
|
// TODO
|
|
38726
38808
|
const MEDIACONTROL_PLAYBACKRATE = 'playbackRate';
|
|
38809
|
+
/**
|
|
38810
|
+
* Allows changing the playback speed of the video.
|
|
38811
|
+
* @beta
|
|
38812
|
+
*
|
|
38813
|
+
* @remarks
|
|
38814
|
+
* Depends on:
|
|
38815
|
+
*
|
|
38816
|
+
* - {@link MediaControl | media_control}
|
|
38817
|
+
*
|
|
38818
|
+
* - {@link BottomGear | bottom_gear}
|
|
38819
|
+
*
|
|
38820
|
+
* It renders a button in the gear menu, which opens a dropdown with the available playback rates.
|
|
38821
|
+
*/
|
|
38727
38822
|
class PlaybackRate extends UICorePlugin {
|
|
38728
38823
|
currentPlayback = null;
|
|
38729
38824
|
playbackRates = DEFAULT_PLAYBACK_RATES;
|
|
38730
38825
|
prevSelectedRate;
|
|
38731
38826
|
selectedRate = DEFAULT_PLAYBACK_RATE;
|
|
38827
|
+
/**
|
|
38828
|
+
* @internal
|
|
38829
|
+
*/
|
|
38732
38830
|
get name() {
|
|
38733
|
-
return '
|
|
38831
|
+
return 'playback_rate';
|
|
38734
38832
|
}
|
|
38833
|
+
/**
|
|
38834
|
+
* @internal
|
|
38835
|
+
*/
|
|
38735
38836
|
get supportedVersion() {
|
|
38736
38837
|
return { min: CLAPPR_VERSION };
|
|
38737
38838
|
}
|
|
38738
|
-
|
|
38739
|
-
|
|
38740
|
-
|
|
38839
|
+
static template = tmpl(pluginHtml$3);
|
|
38840
|
+
static buttonTemplate = tmpl(buttonHtml);
|
|
38841
|
+
static listTemplate = tmpl(listHtml);
|
|
38842
|
+
/**
|
|
38843
|
+
* @internal
|
|
38844
|
+
*/
|
|
38741
38845
|
get attributes() {
|
|
38742
38846
|
return {
|
|
38743
38847
|
'class': this.name,
|
|
38744
38848
|
'data-playback-rate-select': ''
|
|
38745
38849
|
};
|
|
38746
38850
|
}
|
|
38851
|
+
/**
|
|
38852
|
+
* @internal
|
|
38853
|
+
*/
|
|
38747
38854
|
get events() {
|
|
38748
38855
|
return {
|
|
38749
38856
|
'click .gear-sub-menu_btn': 'onRateSelect',
|
|
@@ -38751,8 +38858,12 @@ class PlaybackRate extends UICorePlugin {
|
|
|
38751
38858
|
'click .go-back': 'goBack',
|
|
38752
38859
|
};
|
|
38753
38860
|
}
|
|
38861
|
+
/**
|
|
38862
|
+
* @internal
|
|
38863
|
+
*/
|
|
38754
38864
|
bindEvents() {
|
|
38755
38865
|
this.listenTo(this.core, 'gear:rendered', this.render);
|
|
38866
|
+
// TODO this.core.getPlugin('media_control'), bottom_gear
|
|
38756
38867
|
this.listenTo(this.core.mediaControl, Events$1.MEDIACONTROL_CONTAINERCHANGED, this.reload);
|
|
38757
38868
|
this.listenTo(this.core.mediaControl, MEDIACONTROL_PLAYBACKRATE, this.updatePlaybackRate);
|
|
38758
38869
|
this.listenTo(this.core, 'core:advertisement:start', this.onStartAd);
|
|
@@ -38806,6 +38917,9 @@ class PlaybackRate extends UICorePlugin {
|
|
|
38806
38917
|
this.currentPlayback = this.core.activePlayback;
|
|
38807
38918
|
return !(this.currentPlayback?.tagName !== 'video' && this.currentPlayback?.tagName !== 'audio');
|
|
38808
38919
|
}
|
|
38920
|
+
/**
|
|
38921
|
+
* @internal
|
|
38922
|
+
*/
|
|
38809
38923
|
render() {
|
|
38810
38924
|
const container = this.core.activeContainer;
|
|
38811
38925
|
if (this.core.getPlaybackType() === Playback.LIVE && !container.isDvrEnabled()) {
|
|
@@ -38819,9 +38933,7 @@ class PlaybackRate extends UICorePlugin {
|
|
|
38819
38933
|
this.selectedRate = cfg.defaultValue || DEFAULT_PLAYBACK_RATE;
|
|
38820
38934
|
}
|
|
38821
38935
|
if (this.shouldRender()) {
|
|
38822
|
-
const
|
|
38823
|
-
// const html = t({ playbackRates: this.playbackRates, title: this.getTitle() });
|
|
38824
|
-
const button = t({
|
|
38936
|
+
const button = PlaybackRate.buttonTemplate({
|
|
38825
38937
|
title: this.getTitle(),
|
|
38826
38938
|
speedIcon,
|
|
38827
38939
|
arrowRightIcon,
|
|
@@ -38869,8 +38981,7 @@ class PlaybackRate extends UICorePlugin {
|
|
|
38869
38981
|
return false;
|
|
38870
38982
|
}
|
|
38871
38983
|
onShowMenu() {
|
|
38872
|
-
|
|
38873
|
-
this.$el.html(t({
|
|
38984
|
+
this.$el.html(PlaybackRate.listTemplate({
|
|
38874
38985
|
playbackRates: this.playbackRates,
|
|
38875
38986
|
arrowLeftIcon,
|
|
38876
38987
|
checkIcon,
|
|
@@ -38914,7 +39025,7 @@ const posterHTML = "<div class=\"play-wrapper\" data-poster></div>\n";
|
|
|
38914
39025
|
//Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
38915
39026
|
// Use of this source code is governed by a BSD-style
|
|
38916
39027
|
// license that can be found in the LICENSE file.
|
|
38917
|
-
const T$
|
|
39028
|
+
const T$5 = 'plugins.poster_custom';
|
|
38918
39029
|
/**
|
|
38919
39030
|
* Displays a poster image in the background and a big play button on top when playback is stopped
|
|
38920
39031
|
* @beta
|
|
@@ -39022,7 +39133,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39022
39133
|
super.disable();
|
|
39023
39134
|
}
|
|
39024
39135
|
onError(error) {
|
|
39025
|
-
trace(`${T$
|
|
39136
|
+
trace(`${T$5} onError`, {
|
|
39026
39137
|
enabled: this.enabled,
|
|
39027
39138
|
});
|
|
39028
39139
|
this.hasFatalError = error.level === PlayerError.Levels.FATAL;
|
|
@@ -39043,7 +39154,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39043
39154
|
this.update();
|
|
39044
39155
|
}
|
|
39045
39156
|
onStop() {
|
|
39046
|
-
trace(`${T$
|
|
39157
|
+
trace(`${T$5} onStop`, {
|
|
39047
39158
|
enabled: this.enabled,
|
|
39048
39159
|
});
|
|
39049
39160
|
this.hasStartedPlaying = false;
|
|
@@ -39051,7 +39162,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39051
39162
|
this.update();
|
|
39052
39163
|
}
|
|
39053
39164
|
updatePlayButton(show) {
|
|
39054
|
-
trace(`${T$
|
|
39165
|
+
trace(`${T$5} updatePlayButton`, {
|
|
39055
39166
|
chromeless: this.options.chromeless,
|
|
39056
39167
|
allowUserInteraction: this.options.allowUserInteraction,
|
|
39057
39168
|
});
|
|
@@ -39079,7 +39190,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39079
39190
|
this.$el.removeClass('clickable');
|
|
39080
39191
|
}
|
|
39081
39192
|
clicked() {
|
|
39082
|
-
trace(`${T$
|
|
39193
|
+
trace(`${T$5} clicked`, {
|
|
39083
39194
|
hasStartedPlaying: this.hasStartedPlaying,
|
|
39084
39195
|
chromeless: this.options.chromeless,
|
|
39085
39196
|
allowUserInteraction: this.options.allowUserInteraction,
|
|
@@ -39103,7 +39214,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39103
39214
|
return !this.container.playback.isAudioOnly;
|
|
39104
39215
|
}
|
|
39105
39216
|
update() {
|
|
39106
|
-
trace(`${T$
|
|
39217
|
+
trace(`${T$5} update`, {
|
|
39107
39218
|
shouldRender: this.shouldRender,
|
|
39108
39219
|
});
|
|
39109
39220
|
if (!this.shouldRender) {
|
|
@@ -39116,7 +39227,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39116
39227
|
this.updatePoster();
|
|
39117
39228
|
}
|
|
39118
39229
|
updatePoster() {
|
|
39119
|
-
trace(`${T$
|
|
39230
|
+
trace(`${T$5} updatePoster`, {
|
|
39120
39231
|
hasStartedPlaying: this.hasStartedPlaying,
|
|
39121
39232
|
});
|
|
39122
39233
|
if (!this.hasStartedPlaying) {
|
|
@@ -39131,7 +39242,7 @@ class Poster extends UIContainerPlugin {
|
|
|
39131
39242
|
this.$el.show();
|
|
39132
39243
|
}
|
|
39133
39244
|
hidePoster() {
|
|
39134
|
-
trace(`${T$
|
|
39245
|
+
trace(`${T$5} hidePoster`, {
|
|
39135
39246
|
shouldHideOnPlay: this.shouldHideOnPlay(),
|
|
39136
39247
|
});
|
|
39137
39248
|
if (!this.options.disableMediaControl) {
|
|
@@ -39568,7 +39679,7 @@ const spinnerHTML = "<div data-bounce1></div>\n<div data-bounce2></div>\n<div da
|
|
|
39568
39679
|
// Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
39569
39680
|
// Use of this source code is governed by a BSD-style
|
|
39570
39681
|
// license that can be found in the LICENSE file.
|
|
39571
|
-
const T$
|
|
39682
|
+
const T$4 = 'plugins.spinner';
|
|
39572
39683
|
/**
|
|
39573
39684
|
* Custom events emitted by the plugin
|
|
39574
39685
|
*/
|
|
@@ -39636,7 +39747,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
39636
39747
|
this.hide();
|
|
39637
39748
|
}
|
|
39638
39749
|
onStop() {
|
|
39639
|
-
trace(`${T$
|
|
39750
|
+
trace(`${T$4} onStop`, {
|
|
39640
39751
|
showOnError: this.options.spinner?.showOnError,
|
|
39641
39752
|
hasFatalError: this.hasFatalError,
|
|
39642
39753
|
});
|
|
@@ -39646,7 +39757,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
39646
39757
|
}
|
|
39647
39758
|
onError(e) {
|
|
39648
39759
|
this.hasFatalError = e.code === PlaybackErrorCode.MediaSourceUnavailable;
|
|
39649
|
-
trace(`${T$
|
|
39760
|
+
trace(`${T$4} onError`, {
|
|
39650
39761
|
showOnError: this.options.spinner?.showOnError,
|
|
39651
39762
|
hasFatalError: this.hasFatalError,
|
|
39652
39763
|
error: e.code,
|
|
@@ -39679,7 +39790,7 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
39679
39790
|
*/
|
|
39680
39791
|
render() {
|
|
39681
39792
|
const showOnStart = this.options.spinner?.showOnStart;
|
|
39682
|
-
trace(`${T$
|
|
39793
|
+
trace(`${T$4} render`, {
|
|
39683
39794
|
buffering: this.container.buffering});
|
|
39684
39795
|
this.$el.html(this.template());
|
|
39685
39796
|
this.el.firstElementChild?.addEventListener('animationiteration', () => {
|
|
@@ -39696,128 +39807,192 @@ class SpinnerThreeBounce extends UIContainerPlugin {
|
|
|
39696
39807
|
}
|
|
39697
39808
|
}
|
|
39698
39809
|
|
|
39699
|
-
|
|
39700
|
-
const
|
|
39701
|
-
const
|
|
39702
|
-
const
|
|
39703
|
-
|
|
39704
|
-
|
|
39810
|
+
const T$3 = 'plugins.source_controller';
|
|
39811
|
+
const INITIAL_RETRY_DELAY = 1000;
|
|
39812
|
+
const MAX_RETRY_DELAY = 5000;
|
|
39813
|
+
const RETRY_DELAY_BLUR = 500;
|
|
39814
|
+
const VERSION$1 = '0.0.1';
|
|
39815
|
+
function noSync(cb) {
|
|
39816
|
+
queueMicrotask(cb);
|
|
39817
|
+
}
|
|
39818
|
+
/**
|
|
39819
|
+
* This plugin is responsible for managing the automatic failover between sources.
|
|
39820
|
+
* @beta
|
|
39821
|
+
* @remarks
|
|
39822
|
+
* Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
|
|
39823
|
+
* on how sources ordering and selection works.
|
|
39824
|
+
*
|
|
39825
|
+
* This plugin does not expose any public methods apart from required by the Clappr plugin interface.
|
|
39826
|
+
* It is supposed to work autonomously.
|
|
39827
|
+
*
|
|
39828
|
+
* @example
|
|
39829
|
+
* ```ts
|
|
39830
|
+
* import { SourceController } from '@gcorevideo/player'
|
|
39831
|
+
*
|
|
39832
|
+
* Player.registerPlugin(SourceController)
|
|
39833
|
+
* ```
|
|
39834
|
+
*/
|
|
39835
|
+
class SourceController extends CorePlugin {
|
|
39836
|
+
/*
|
|
39837
|
+
* The Logic itself is quite simple:
|
|
39838
|
+
* * Here is the short diagram:
|
|
39839
|
+
*
|
|
39840
|
+
* sources_list:
|
|
39841
|
+
* - a.mpd | +--------------------+
|
|
39842
|
+
* - b.m3u8 |--->| init |
|
|
39843
|
+
* - ... | |--------------------|
|
|
39844
|
+
* | current_source = 0 |
|
|
39845
|
+
* +--------------------+
|
|
39846
|
+
* |
|
|
39847
|
+
* | source = a.mpd
|
|
39848
|
+
* | playback = dash.js
|
|
39849
|
+
* v
|
|
39850
|
+
* +------------------+
|
|
39851
|
+
* +-->| load source |
|
|
39852
|
+
* | +---------|--------+
|
|
39853
|
+
* | v
|
|
39854
|
+
* | +------------------+
|
|
39855
|
+
* | | play |
|
|
39856
|
+
* | +---------|--------+
|
|
39857
|
+
* | |
|
|
39858
|
+
* | v
|
|
39859
|
+
* | +-----------------------+
|
|
39860
|
+
* | | on playback_error |
|
|
39861
|
+
* | |-----------------------|
|
|
39862
|
+
* | | current_source = |
|
|
39863
|
+
* | | (current_source + 1) |
|
|
39864
|
+
* | | % len sources_list |
|
|
39865
|
+
* | | |
|
|
39866
|
+
* | | delay 1..3s |
|
|
39867
|
+
* | +---------------|-------+
|
|
39868
|
+
* | |
|
|
39869
|
+
* | source=b.m3u8 |
|
|
39870
|
+
* | playback=hls.js |
|
|
39871
|
+
* +-------------------+
|
|
39872
|
+
*
|
|
39873
|
+
*/
|
|
39874
|
+
sourcesList = [];
|
|
39875
|
+
currentSourceIndex = 0;
|
|
39876
|
+
sourcesDelay = {};
|
|
39877
|
+
active = false;
|
|
39878
|
+
sync = noSync;
|
|
39879
|
+
/**
|
|
39880
|
+
* @internal
|
|
39881
|
+
*/
|
|
39705
39882
|
get name() {
|
|
39706
|
-
return '
|
|
39883
|
+
return 'source_controller';
|
|
39707
39884
|
}
|
|
39885
|
+
/**
|
|
39886
|
+
* @internal
|
|
39887
|
+
*/
|
|
39708
39888
|
get supportedVersion() {
|
|
39709
39889
|
return { min: CLAPPR_VERSION };
|
|
39710
39890
|
}
|
|
39711
|
-
|
|
39712
|
-
|
|
39713
|
-
|
|
39714
|
-
|
|
39715
|
-
|
|
39716
|
-
|
|
39717
|
-
|
|
39718
|
-
|
|
39719
|
-
|
|
39720
|
-
|
|
39721
|
-
|
|
39891
|
+
constructor(core) {
|
|
39892
|
+
super(core);
|
|
39893
|
+
this.sourcesList = this.core.options.sources;
|
|
39894
|
+
if (this.core.options.source !== undefined) {
|
|
39895
|
+
// prevent Clappr from loading all sources simultaneously
|
|
39896
|
+
this.core.options.sources = [this.core.options.source];
|
|
39897
|
+
}
|
|
39898
|
+
else {
|
|
39899
|
+
this.core.options.sources = this.core.options.sources.slice(0, 1);
|
|
39900
|
+
}
|
|
39901
|
+
}
|
|
39722
39902
|
/**
|
|
39723
|
-
*
|
|
39903
|
+
* @internal
|
|
39724
39904
|
*/
|
|
39725
|
-
bufAccDuration = 0;
|
|
39726
|
-
constructor(container) {
|
|
39727
|
-
super(container);
|
|
39728
|
-
assert(this.options.statistics &&
|
|
39729
|
-
typeof this.options.statistics.send === 'function', 'Statistics plugin requires statistics options');
|
|
39730
|
-
}
|
|
39731
39905
|
bindEvents() {
|
|
39732
|
-
|
|
39733
|
-
this.
|
|
39734
|
-
this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
|
|
39735
|
-
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
39736
|
-
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
|
|
39737
|
-
this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdateLive);
|
|
39738
|
-
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
|
|
39739
|
-
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.stopLevelSwitch);
|
|
39740
|
-
}
|
|
39741
|
-
startLevelSwitch() {
|
|
39742
|
-
this.bufTracking = false;
|
|
39743
|
-
}
|
|
39744
|
-
stopLevelSwitch() {
|
|
39745
|
-
this.bufTracking = true;
|
|
39746
|
-
}
|
|
39747
|
-
onBuffering() {
|
|
39748
|
-
if (this.bufTracking) {
|
|
39749
|
-
this.bufLastStarted = performance.now();
|
|
39750
|
-
}
|
|
39751
|
-
}
|
|
39752
|
-
onBufferFull() {
|
|
39753
|
-
if (this.bufTracking && this.bufLastStarted) {
|
|
39754
|
-
this.bufAccDuration += performance.now() - this.bufLastStarted;
|
|
39755
|
-
this.lags++;
|
|
39756
|
-
}
|
|
39757
|
-
this.bufTracking = true;
|
|
39906
|
+
super.bindEvents();
|
|
39907
|
+
this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
|
|
39758
39908
|
}
|
|
39759
39909
|
onReady() {
|
|
39760
|
-
|
|
39761
|
-
|
|
39762
|
-
this.
|
|
39763
|
-
}
|
|
39764
|
-
}
|
|
39765
|
-
initEvent() {
|
|
39766
|
-
this.sendMessage('init');
|
|
39767
|
-
}
|
|
39768
|
-
sendMessage(state) {
|
|
39769
|
-
this.send(state, {
|
|
39770
|
-
// embed_url: this.options.referer,
|
|
39771
|
-
// user_agent: Browser.userAgent
|
|
39772
|
-
});
|
|
39773
|
-
}
|
|
39774
|
-
send(event, data = {}) {
|
|
39775
|
-
this.options.statistics.send({
|
|
39776
|
-
event,
|
|
39777
|
-
type: this.container.getPlaybackType(),
|
|
39778
|
-
...data,
|
|
39910
|
+
trace(`${T$3} onReady`, {
|
|
39911
|
+
retrying: this.active,
|
|
39912
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
39779
39913
|
});
|
|
39780
|
-
|
|
39781
|
-
|
|
39782
|
-
|
|
39783
|
-
|
|
39784
|
-
|
|
39785
|
-
};
|
|
39786
|
-
this.bufAccDuration = 0;
|
|
39787
|
-
this.lags = 0;
|
|
39788
|
-
if (this.container.getPlaybackType() === Playback.VOD) {
|
|
39789
|
-
res.timestamp = time;
|
|
39790
|
-
}
|
|
39791
|
-
this.send('heatmap', res);
|
|
39792
|
-
this.heatmapSent = true;
|
|
39793
|
-
this.heatmapLastTime = time;
|
|
39794
|
-
}
|
|
39795
|
-
onTimeUpdateLive({ current }) {
|
|
39796
|
-
// TODO check the `current` values for the live streams
|
|
39797
|
-
if (!this.timeStart) {
|
|
39798
|
-
this.timeStart = current;
|
|
39799
|
-
}
|
|
39800
|
-
try {
|
|
39801
|
-
const elapsed = current - this.timeStart;
|
|
39802
|
-
const heatmapElapsed = current - this.heatmapLastTime;
|
|
39803
|
-
// TODO check if the heatmap is only needed for the live streams
|
|
39804
|
-
if (!this.heatmapSent || heatmapElapsed >= HEATMAP_INTERVAL) {
|
|
39805
|
-
this.sendHeatmap(current);
|
|
39806
|
-
}
|
|
39807
|
-
if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
|
|
39808
|
-
this.watchSent = true;
|
|
39809
|
-
this.sendMessage('watch');
|
|
39810
|
-
}
|
|
39914
|
+
const spinner = this.core.activeContainer?.getPlugin('spinner');
|
|
39915
|
+
if (spinner) {
|
|
39916
|
+
this.sync = (cb) => {
|
|
39917
|
+
spinner.once(SpinnerEvents.SYNC, cb);
|
|
39918
|
+
};
|
|
39811
39919
|
}
|
|
39812
|
-
|
|
39920
|
+
else {
|
|
39921
|
+
this.sync = noSync;
|
|
39813
39922
|
}
|
|
39814
|
-
|
|
39815
|
-
|
|
39816
|
-
|
|
39817
|
-
|
|
39923
|
+
this.bindContainerEventListeners();
|
|
39924
|
+
if (this.active) {
|
|
39925
|
+
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
39926
|
+
spinner?.show();
|
|
39818
39927
|
}
|
|
39819
|
-
|
|
39820
|
-
|
|
39928
|
+
}
|
|
39929
|
+
bindContainerEventListeners() {
|
|
39930
|
+
this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
|
|
39931
|
+
trace(`${T$3} on PLAYBACK_ERROR`, {
|
|
39932
|
+
error: {
|
|
39933
|
+
code: error?.code,
|
|
39934
|
+
description: error?.description,
|
|
39935
|
+
level: error?.level,
|
|
39936
|
+
},
|
|
39937
|
+
retrying: this.active,
|
|
39938
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
39939
|
+
});
|
|
39940
|
+
switch (error.code) {
|
|
39941
|
+
case PlaybackErrorCode.MediaSourceUnavailable:
|
|
39942
|
+
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
39943
|
+
this.retryPlayback();
|
|
39944
|
+
break;
|
|
39945
|
+
}
|
|
39946
|
+
});
|
|
39947
|
+
this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
|
|
39948
|
+
trace(`${T$3} on PLAYBACK_PLAY`, {
|
|
39949
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
39950
|
+
retrying: this.active,
|
|
39951
|
+
});
|
|
39952
|
+
if (this.active) {
|
|
39953
|
+
this.reset();
|
|
39954
|
+
// TODO make poster reset its state on enable
|
|
39955
|
+
this.core.activeContainer?.getPlugin('poster_custom')?.enable();
|
|
39956
|
+
this.core.activeContainer?.getPlugin('spinner')?.hide();
|
|
39957
|
+
}
|
|
39958
|
+
});
|
|
39959
|
+
}
|
|
39960
|
+
reset() {
|
|
39961
|
+
this.active = false;
|
|
39962
|
+
this.sourcesDelay = {};
|
|
39963
|
+
}
|
|
39964
|
+
retryPlayback() {
|
|
39965
|
+
trace(`${T$3} retryPlayback enter`, {
|
|
39966
|
+
currentSourceIndex: this.currentSourceIndex,
|
|
39967
|
+
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
39968
|
+
});
|
|
39969
|
+
this.active = true;
|
|
39970
|
+
this.getNextMediaSource().then((nextSource) => {
|
|
39971
|
+
const rnd = RETRY_DELAY_BLUR * Math.random();
|
|
39972
|
+
this.sync(() => {
|
|
39973
|
+
this.core.load(nextSource.source, nextSource.mimeType);
|
|
39974
|
+
setTimeout(() => {
|
|
39975
|
+
// this.core.activePlayback.consent()
|
|
39976
|
+
this.core.activePlayback.play();
|
|
39977
|
+
}, rnd);
|
|
39978
|
+
});
|
|
39979
|
+
});
|
|
39980
|
+
}
|
|
39981
|
+
getNextMediaSource() {
|
|
39982
|
+
return new Promise((resolve) => {
|
|
39983
|
+
this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
|
|
39984
|
+
this.currentSourceIndex =
|
|
39985
|
+
(this.currentSourceIndex + 1) % this.sourcesList.length;
|
|
39986
|
+
const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
|
|
39987
|
+
const s = this.sourcesList[this.currentSourceIndex];
|
|
39988
|
+
setTimeout(() => resolve(s), delay);
|
|
39989
|
+
});
|
|
39990
|
+
}
|
|
39991
|
+
/**
|
|
39992
|
+
* @internal
|
|
39993
|
+
*/
|
|
39994
|
+
static get version() {
|
|
39995
|
+
return VERSION$1;
|
|
39821
39996
|
}
|
|
39822
39997
|
}
|
|
39823
39998
|
|
|
@@ -39829,7 +40004,7 @@ const comboboxHTML = "<button data-subtitles-button class='media-control-button
|
|
|
39829
40004
|
|
|
39830
40005
|
const stringHTML = "<div class=\"subtitle-string\">\n <p></p>\n</div>\n";
|
|
39831
40006
|
|
|
39832
|
-
const VERSION
|
|
40007
|
+
const VERSION = '2.19.14';
|
|
39833
40008
|
const LOCAL_STORAGE_SUBTITLES_ID = 'gplayer.plugins.subtitles.selected';
|
|
39834
40009
|
const T$2 = 'plugins.subtitles';
|
|
39835
40010
|
const NO_TRACK = { language: 'off' };
|
|
@@ -39883,7 +40058,7 @@ class Subtitles extends UICorePlugin {
|
|
|
39883
40058
|
* @internal
|
|
39884
40059
|
*/
|
|
39885
40060
|
static get version() {
|
|
39886
|
-
return VERSION
|
|
40061
|
+
return VERSION;
|
|
39887
40062
|
}
|
|
39888
40063
|
static template = tmpl(comboboxHTML);
|
|
39889
40064
|
static templateString = tmpl(stringHTML);
|
|
@@ -40190,6 +40365,182 @@ class Subtitles extends UICorePlugin {
|
|
|
40190
40365
|
}
|
|
40191
40366
|
}
|
|
40192
40367
|
|
|
40368
|
+
// An example implementation of client side performancestatistics
|
|
40369
|
+
const WATCH_CUTOFF = 5;
|
|
40370
|
+
const STALL_MEASURE_PERIOD = 10;
|
|
40371
|
+
const T$1 = 'plugins.telemetry';
|
|
40372
|
+
/**
|
|
40373
|
+
* Telemetry event type
|
|
40374
|
+
*/
|
|
40375
|
+
var TelemetryEvent;
|
|
40376
|
+
(function (TelemetryEvent) {
|
|
40377
|
+
TelemetryEvent[TelemetryEvent["Init"] = 1] = "Init";
|
|
40378
|
+
TelemetryEvent[TelemetryEvent["Start"] = 2] = "Start";
|
|
40379
|
+
TelemetryEvent[TelemetryEvent["Watch"] = 3] = "Watch";
|
|
40380
|
+
TelemetryEvent[TelemetryEvent["Stall"] = 4] = "Stall";
|
|
40381
|
+
})(TelemetryEvent || (TelemetryEvent = {}));
|
|
40382
|
+
/**
|
|
40383
|
+
* Collects and reports the performance statistics.
|
|
40384
|
+
* @beta
|
|
40385
|
+
* @remarks
|
|
40386
|
+
* This plugin is experimental and its API is likely to change.
|
|
40387
|
+
*
|
|
40388
|
+
* Configuration options {@link TelemetryPluginSettings}
|
|
40389
|
+
*
|
|
40390
|
+
* @example
|
|
40391
|
+
* ```ts
|
|
40392
|
+
* import { Statistics } from '@gcorevideo/player'
|
|
40393
|
+
*
|
|
40394
|
+
* Player.registerPlugin(Statistics)
|
|
40395
|
+
*
|
|
40396
|
+
* const player = new Player({
|
|
40397
|
+
* statistics: {
|
|
40398
|
+
* send: (data) => {
|
|
40399
|
+
* fetch('/stats', {
|
|
40400
|
+
* method: 'POST',
|
|
40401
|
+
* body: JSON.stringify(data),
|
|
40402
|
+
* headers: { 'content-type': 'application/json' },
|
|
40403
|
+
* })
|
|
40404
|
+
* },
|
|
40405
|
+
* },
|
|
40406
|
+
* ...
|
|
40407
|
+
* })
|
|
40408
|
+
* ```
|
|
40409
|
+
*/
|
|
40410
|
+
class Telemetry extends ContainerPlugin {
|
|
40411
|
+
/**
|
|
40412
|
+
* The name of the plugin.
|
|
40413
|
+
*/
|
|
40414
|
+
get name() {
|
|
40415
|
+
return 'telemetry';
|
|
40416
|
+
}
|
|
40417
|
+
/**
|
|
40418
|
+
* The supported version of the plugin.
|
|
40419
|
+
*/
|
|
40420
|
+
get supportedVersion() {
|
|
40421
|
+
return { min: CLAPPR_VERSION };
|
|
40422
|
+
}
|
|
40423
|
+
started = false;
|
|
40424
|
+
timeStart = 0;
|
|
40425
|
+
stallSent = false;
|
|
40426
|
+
stallLastTime = 0;
|
|
40427
|
+
watchSent = false;
|
|
40428
|
+
bufTracking = false;
|
|
40429
|
+
numStalls = 0;
|
|
40430
|
+
/**
|
|
40431
|
+
* The time when buffering last started.
|
|
40432
|
+
*/
|
|
40433
|
+
bufLastStarted = 0;
|
|
40434
|
+
/**
|
|
40435
|
+
* The accumulated buffering duration.
|
|
40436
|
+
*/
|
|
40437
|
+
stallAcc = 0;
|
|
40438
|
+
constructor(container) {
|
|
40439
|
+
super(container);
|
|
40440
|
+
assert(this.options.telemetry &&
|
|
40441
|
+
typeof this.options.telemetry.send === 'function', 'Telemetry plugin configuration is invalid: `send` option is required');
|
|
40442
|
+
}
|
|
40443
|
+
/**
|
|
40444
|
+
* @internal
|
|
40445
|
+
*/
|
|
40446
|
+
bindEvents() {
|
|
40447
|
+
// TODO remove this
|
|
40448
|
+
// this.listenToOnce(
|
|
40449
|
+
// this.container,
|
|
40450
|
+
// CUSTOM_EVENTS_CONTAINER_START,
|
|
40451
|
+
// this.onStart,
|
|
40452
|
+
// )
|
|
40453
|
+
this.listenToOnce(this.container, Events$1.CONTAINER_READY, this.onReady);
|
|
40454
|
+
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
40455
|
+
this.listenTo(this.container, Events$1.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
|
|
40456
|
+
this.listenTo(this.container.playback, Events$1.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
|
|
40457
|
+
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
|
|
40458
|
+
this.listenTo(this.container.playback, Events$1.PLAYBACK_LEVEL_SWITCH_END, this.endLevelSwitch);
|
|
40459
|
+
}
|
|
40460
|
+
startLevelSwitch() {
|
|
40461
|
+
this.bufTracking = false;
|
|
40462
|
+
}
|
|
40463
|
+
endLevelSwitch() {
|
|
40464
|
+
this.bufTracking = true;
|
|
40465
|
+
}
|
|
40466
|
+
onBuffering() {
|
|
40467
|
+
if (this.bufTracking) {
|
|
40468
|
+
this.bufLastStarted = performance.now();
|
|
40469
|
+
}
|
|
40470
|
+
}
|
|
40471
|
+
onBufferFull() {
|
|
40472
|
+
if (this.bufTracking && this.bufLastStarted) {
|
|
40473
|
+
this.stallAcc += performance.now() - this.bufLastStarted;
|
|
40474
|
+
this.numStalls++;
|
|
40475
|
+
}
|
|
40476
|
+
this.bufTracking = true;
|
|
40477
|
+
}
|
|
40478
|
+
onReady() {
|
|
40479
|
+
this.sendInit();
|
|
40480
|
+
trace(`${T$1} onReady`, {
|
|
40481
|
+
autoPlay: this.options.autoPlay,
|
|
40482
|
+
});
|
|
40483
|
+
if (this.options.autoPlay) {
|
|
40484
|
+
this.onStart();
|
|
40485
|
+
}
|
|
40486
|
+
else {
|
|
40487
|
+
this.listenToOnce(this.container.playback, Events$1.PLAYBACK_PLAY_INTENT, this.onStart);
|
|
40488
|
+
}
|
|
40489
|
+
}
|
|
40490
|
+
sendInit() {
|
|
40491
|
+
this.send({ event: TelemetryEvent.Init });
|
|
40492
|
+
}
|
|
40493
|
+
send(event) {
|
|
40494
|
+
this.options.telemetry.send({
|
|
40495
|
+
type: this.container.getPlaybackType(),
|
|
40496
|
+
...event,
|
|
40497
|
+
});
|
|
40498
|
+
}
|
|
40499
|
+
sendStall(time) {
|
|
40500
|
+
// TODO don't send if no stalls?
|
|
40501
|
+
const res = {
|
|
40502
|
+
event: TelemetryEvent.Stall,
|
|
40503
|
+
count: this.numStalls,
|
|
40504
|
+
time,
|
|
40505
|
+
total_ms: Math.round(this.stallAcc * 1000),
|
|
40506
|
+
};
|
|
40507
|
+
this.stallAcc = 0;
|
|
40508
|
+
this.numStalls = 0;
|
|
40509
|
+
this.send(res);
|
|
40510
|
+
this.stallSent = true;
|
|
40511
|
+
this.stallLastTime = time;
|
|
40512
|
+
}
|
|
40513
|
+
onTimeUpdate({ current }) {
|
|
40514
|
+
if (!this.timeStart) {
|
|
40515
|
+
this.timeStart = current;
|
|
40516
|
+
}
|
|
40517
|
+
try {
|
|
40518
|
+
const elapsed = current - this.timeStart;
|
|
40519
|
+
const stallElapsed = current - this.stallLastTime;
|
|
40520
|
+
if (!this.stallSent || stallElapsed >= STALL_MEASURE_PERIOD) {
|
|
40521
|
+
this.sendStall(current);
|
|
40522
|
+
}
|
|
40523
|
+
if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
|
|
40524
|
+
this.watchSent = true;
|
|
40525
|
+
this.send({
|
|
40526
|
+
event: TelemetryEvent.Watch,
|
|
40527
|
+
});
|
|
40528
|
+
}
|
|
40529
|
+
}
|
|
40530
|
+
catch (error) {
|
|
40531
|
+
}
|
|
40532
|
+
}
|
|
40533
|
+
onStart() {
|
|
40534
|
+
if (this.started) {
|
|
40535
|
+
return;
|
|
40536
|
+
}
|
|
40537
|
+
this.started = true;
|
|
40538
|
+
this.send({
|
|
40539
|
+
event: TelemetryEvent.Start,
|
|
40540
|
+
});
|
|
40541
|
+
}
|
|
40542
|
+
}
|
|
40543
|
+
|
|
40193
40544
|
var parseSrt$1 = {exports: {}};
|
|
40194
40545
|
|
|
40195
40546
|
var parseSrt = parseSrt$1.exports;
|
|
@@ -40306,7 +40657,7 @@ const parseSRT = /*@__PURE__*/getDefaultExportFromCjs(parseSrtExports);
|
|
|
40306
40657
|
|
|
40307
40658
|
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";
|
|
40308
40659
|
|
|
40309
|
-
const T
|
|
40660
|
+
const T = 'plugins.media_control_thumbnails';
|
|
40310
40661
|
class Thumbnails extends UICorePlugin {
|
|
40311
40662
|
_$spotlight = null;
|
|
40312
40663
|
_$backdrop = null;
|
|
@@ -40576,7 +40927,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
40576
40927
|
// calculate how far along the carousel should currently be slid
|
|
40577
40928
|
// depending on where the user is hovering on the progress bar
|
|
40578
40929
|
_updateCarousel() {
|
|
40579
|
-
trace(`${T
|
|
40930
|
+
trace(`${T} _updateCarousel`, {
|
|
40580
40931
|
backdropHeight: this._getOptions().backdropHeight,
|
|
40581
40932
|
});
|
|
40582
40933
|
if (!this._getOptions().backdropHeight) {
|
|
@@ -40635,7 +40986,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
40635
40986
|
}
|
|
40636
40987
|
}
|
|
40637
40988
|
_updateSpotlightThumb() {
|
|
40638
|
-
trace(`${T
|
|
40989
|
+
trace(`${T} _updateSpotlightThumb`, {
|
|
40639
40990
|
spotlightHeight: this._getOptions().spotlightHeight,
|
|
40640
40991
|
});
|
|
40641
40992
|
if (!this._getOptions().spotlightHeight) {
|
|
@@ -40680,7 +41031,7 @@ class Thumbnails extends UICorePlugin {
|
|
|
40680
41031
|
return 0;
|
|
40681
41032
|
}
|
|
40682
41033
|
_renderPlugin() {
|
|
40683
|
-
trace(`${T
|
|
41034
|
+
trace(`${T} _renderPlugin`, {
|
|
40684
41035
|
show: this._show,
|
|
40685
41036
|
thumbsLoaded: this._thumbsLoaded,
|
|
40686
41037
|
thumbs: this._thumbs.length,
|
|
@@ -40712,195 +41063,6 @@ class Thumbnails extends UICorePlugin {
|
|
|
40712
41063
|
}
|
|
40713
41064
|
}
|
|
40714
41065
|
|
|
40715
|
-
const T = 'plugins.source_controller';
|
|
40716
|
-
const INITIAL_RETRY_DELAY = 1000;
|
|
40717
|
-
const MAX_RETRY_DELAY = 5000;
|
|
40718
|
-
const RETRY_DELAY_BLUR = 500;
|
|
40719
|
-
const VERSION = '0.0.1';
|
|
40720
|
-
function noSync(cb) {
|
|
40721
|
-
queueMicrotask(cb);
|
|
40722
|
-
}
|
|
40723
|
-
/**
|
|
40724
|
-
* This plugin is responsible for managing the automatic failover between sources.
|
|
40725
|
-
* @beta
|
|
40726
|
-
* @remarks
|
|
40727
|
-
* Have a look at the {@link https://miro.com/app/board/uXjVLiN15tY=/?share_link_id=390327585787 | source failover diagram} for the details
|
|
40728
|
-
* on how sources ordering and selection works.
|
|
40729
|
-
*
|
|
40730
|
-
* This plugin does not expose any public methods apart from required by the Clappr plugin interface.
|
|
40731
|
-
* It is supposed to work autonomously.
|
|
40732
|
-
*
|
|
40733
|
-
* @example
|
|
40734
|
-
* ```ts
|
|
40735
|
-
* import { SourceController } from '@gcorevideo/player'
|
|
40736
|
-
*
|
|
40737
|
-
* Player.registerPlugin(SourceController)
|
|
40738
|
-
* ```
|
|
40739
|
-
*/
|
|
40740
|
-
class SourceController extends CorePlugin {
|
|
40741
|
-
/*
|
|
40742
|
-
* The Logic itself is quite simple:
|
|
40743
|
-
* * Here is the short diagram:
|
|
40744
|
-
*
|
|
40745
|
-
* sources_list:
|
|
40746
|
-
* - a.mpd | +--------------------+
|
|
40747
|
-
* - b.m3u8 |--->| init |
|
|
40748
|
-
* - ... | |--------------------|
|
|
40749
|
-
* | current_source = 0 |
|
|
40750
|
-
* +--------------------+
|
|
40751
|
-
* |
|
|
40752
|
-
* | source = a.mpd
|
|
40753
|
-
* | playback = dash.js
|
|
40754
|
-
* v
|
|
40755
|
-
* +------------------+
|
|
40756
|
-
* +-->| load source |
|
|
40757
|
-
* | +---------|--------+
|
|
40758
|
-
* | v
|
|
40759
|
-
* | +------------------+
|
|
40760
|
-
* | | play |
|
|
40761
|
-
* | +---------|--------+
|
|
40762
|
-
* | |
|
|
40763
|
-
* | v
|
|
40764
|
-
* | +-----------------------+
|
|
40765
|
-
* | | on playback_error |
|
|
40766
|
-
* | |-----------------------|
|
|
40767
|
-
* | | current_source = |
|
|
40768
|
-
* | | (current_source + 1) |
|
|
40769
|
-
* | | % len sources_list |
|
|
40770
|
-
* | | |
|
|
40771
|
-
* | | delay 1..3s |
|
|
40772
|
-
* | +---------------|-------+
|
|
40773
|
-
* | |
|
|
40774
|
-
* | source=b.m3u8 |
|
|
40775
|
-
* | playback=hls.js |
|
|
40776
|
-
* +-------------------+
|
|
40777
|
-
*
|
|
40778
|
-
*/
|
|
40779
|
-
sourcesList = [];
|
|
40780
|
-
currentSourceIndex = 0;
|
|
40781
|
-
sourcesDelay = {};
|
|
40782
|
-
active = false;
|
|
40783
|
-
sync = noSync;
|
|
40784
|
-
/**
|
|
40785
|
-
* @internal
|
|
40786
|
-
*/
|
|
40787
|
-
get name() {
|
|
40788
|
-
return 'source_controller';
|
|
40789
|
-
}
|
|
40790
|
-
/**
|
|
40791
|
-
* @internal
|
|
40792
|
-
*/
|
|
40793
|
-
get supportedVersion() {
|
|
40794
|
-
return { min: CLAPPR_VERSION };
|
|
40795
|
-
}
|
|
40796
|
-
constructor(core) {
|
|
40797
|
-
super(core);
|
|
40798
|
-
this.sourcesList = this.core.options.sources;
|
|
40799
|
-
if (this.core.options.source !== undefined) {
|
|
40800
|
-
// prevent Clappr from loading all sources simultaneously
|
|
40801
|
-
this.core.options.sources = [this.core.options.source];
|
|
40802
|
-
}
|
|
40803
|
-
else {
|
|
40804
|
-
this.core.options.sources = this.core.options.sources.slice(0, 1);
|
|
40805
|
-
}
|
|
40806
|
-
}
|
|
40807
|
-
/**
|
|
40808
|
-
* @internal
|
|
40809
|
-
*/
|
|
40810
|
-
bindEvents() {
|
|
40811
|
-
super.bindEvents();
|
|
40812
|
-
this.listenTo(this.core, Events$1.CORE_ACTIVE_CONTAINER_CHANGED, () => this.onReady());
|
|
40813
|
-
}
|
|
40814
|
-
onReady() {
|
|
40815
|
-
trace(`${T} onReady`, {
|
|
40816
|
-
retrying: this.active,
|
|
40817
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
40818
|
-
});
|
|
40819
|
-
const spinner = this.core.activeContainer?.getPlugin('spinner');
|
|
40820
|
-
if (spinner) {
|
|
40821
|
-
this.sync = (cb) => {
|
|
40822
|
-
spinner.once(SpinnerEvents.SYNC, cb);
|
|
40823
|
-
};
|
|
40824
|
-
}
|
|
40825
|
-
else {
|
|
40826
|
-
this.sync = noSync;
|
|
40827
|
-
}
|
|
40828
|
-
this.bindContainerEventListeners();
|
|
40829
|
-
if (this.active) {
|
|
40830
|
-
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
40831
|
-
spinner?.show();
|
|
40832
|
-
}
|
|
40833
|
-
}
|
|
40834
|
-
bindContainerEventListeners() {
|
|
40835
|
-
this.core.activePlayback.on(Events$1.PLAYBACK_ERROR, (error) => {
|
|
40836
|
-
trace(`${T} on PLAYBACK_ERROR`, {
|
|
40837
|
-
error: {
|
|
40838
|
-
code: error?.code,
|
|
40839
|
-
description: error?.description,
|
|
40840
|
-
level: error?.level,
|
|
40841
|
-
},
|
|
40842
|
-
retrying: this.active,
|
|
40843
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
40844
|
-
});
|
|
40845
|
-
switch (error.code) {
|
|
40846
|
-
case PlaybackErrorCode.MediaSourceUnavailable:
|
|
40847
|
-
this.core.activeContainer?.getPlugin('poster_custom')?.disable();
|
|
40848
|
-
this.retryPlayback();
|
|
40849
|
-
break;
|
|
40850
|
-
}
|
|
40851
|
-
});
|
|
40852
|
-
this.core.activePlayback.on(Events$1.PLAYBACK_PLAY, () => {
|
|
40853
|
-
trace(`${T} on PLAYBACK_PLAY`, {
|
|
40854
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
40855
|
-
retrying: this.active,
|
|
40856
|
-
});
|
|
40857
|
-
if (this.active) {
|
|
40858
|
-
this.reset();
|
|
40859
|
-
// TODO make poster reset its state on enable
|
|
40860
|
-
this.core.activeContainer?.getPlugin('poster_custom')?.enable();
|
|
40861
|
-
this.core.activeContainer?.getPlugin('spinner')?.hide();
|
|
40862
|
-
}
|
|
40863
|
-
});
|
|
40864
|
-
}
|
|
40865
|
-
reset() {
|
|
40866
|
-
this.active = false;
|
|
40867
|
-
this.sourcesDelay = {};
|
|
40868
|
-
}
|
|
40869
|
-
retryPlayback() {
|
|
40870
|
-
trace(`${T} retryPlayback enter`, {
|
|
40871
|
-
currentSourceIndex: this.currentSourceIndex,
|
|
40872
|
-
currentSource: this.sourcesList[this.currentSourceIndex],
|
|
40873
|
-
});
|
|
40874
|
-
this.active = true;
|
|
40875
|
-
this.getNextMediaSource().then((nextSource) => {
|
|
40876
|
-
const rnd = RETRY_DELAY_BLUR * Math.random();
|
|
40877
|
-
this.sync(() => {
|
|
40878
|
-
this.core.load(nextSource.source, nextSource.mimeType);
|
|
40879
|
-
setTimeout(() => {
|
|
40880
|
-
// this.core.activePlayback.consent()
|
|
40881
|
-
this.core.activePlayback.play();
|
|
40882
|
-
}, rnd);
|
|
40883
|
-
});
|
|
40884
|
-
});
|
|
40885
|
-
}
|
|
40886
|
-
getNextMediaSource() {
|
|
40887
|
-
return new Promise((resolve) => {
|
|
40888
|
-
this.sourcesDelay[this.currentSourceIndex] = Math.min(MAX_RETRY_DELAY, (this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY) * 2);
|
|
40889
|
-
this.currentSourceIndex =
|
|
40890
|
-
(this.currentSourceIndex + 1) % this.sourcesList.length;
|
|
40891
|
-
const delay = this.sourcesDelay[this.currentSourceIndex] || INITIAL_RETRY_DELAY;
|
|
40892
|
-
const s = this.sourcesList[this.currentSourceIndex];
|
|
40893
|
-
setTimeout(() => resolve(s), delay);
|
|
40894
|
-
});
|
|
40895
|
-
}
|
|
40896
|
-
/**
|
|
40897
|
-
* @internal
|
|
40898
|
-
*/
|
|
40899
|
-
static get version() {
|
|
40900
|
-
return VERSION;
|
|
40901
|
-
}
|
|
40902
|
-
}
|
|
40903
|
-
|
|
40904
41066
|
var VolumeFadeEvents;
|
|
40905
41067
|
(function (VolumeFadeEvents) {
|
|
40906
41068
|
VolumeFadeEvents["FADE"] = "core:volume:fade";
|
|
@@ -40913,15 +41075,22 @@ class VolumeFade extends UICorePlugin {
|
|
|
40913
41075
|
container = null;
|
|
40914
41076
|
delay = 0;
|
|
40915
41077
|
interval = null;
|
|
41078
|
+
/**
|
|
41079
|
+
* @internal
|
|
41080
|
+
*/
|
|
40916
41081
|
get name() {
|
|
40917
41082
|
return 'volume_fade';
|
|
40918
41083
|
}
|
|
41084
|
+
/**
|
|
41085
|
+
* @internal
|
|
41086
|
+
*/
|
|
40919
41087
|
bindEvents() {
|
|
41088
|
+
// TODO on container changed
|
|
40920
41089
|
this.listenTo(this.core, Events$1.CORE_READY, this.onCoreReady);
|
|
40921
41090
|
if (this.core.mediaControl) {
|
|
40922
41091
|
this.listenTo(this.core.mediaControl, 'mediacontrol:volume:user', this._onUserChangeVolume);
|
|
40923
41092
|
}
|
|
40924
|
-
this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
|
|
41093
|
+
// this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
|
|
40925
41094
|
}
|
|
40926
41095
|
unBindEvents() {
|
|
40927
41096
|
this.core.$el.off('mouseleave.volume');
|
|
@@ -40991,4 +41160,4 @@ class VolumeFade extends UICorePlugin {
|
|
|
40991
41160
|
}
|
|
40992
41161
|
}
|
|
40993
41162
|
|
|
40994
|
-
export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DisableControls, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, SeekTime, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce,
|
|
41163
|
+
export { AudioSelector, BigMuteButton, BottomGear, ClapprNerdStats, ClapprStats, ClickToPause, ClipsPlugin, ContextMenu, DisableControls, DvrControls, ErrorScreen, Favicon, GearEvents, GoogleAnalytics, Kibo, LevelSelector, Logo, MediaControl, MultiCamera, PictureInPicture, PlaybackRate, Poster, SeekTime, Share, SkipTime, SourceController, SpinnerEvents, SpinnerThreeBounce, Subtitles, Telemetry, TelemetryEvent, Thumbnails, VolumeFade, VolumeFadeEvents };
|