@gcorevideo/player 2.22.17 → 2.22.20

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.
Files changed (120) hide show
  1. package/assets/audio-selector/track-selector.ejs +3 -3
  2. package/assets/bottom-gear/bottomgear.ejs +3 -3
  3. package/assets/clappr-nerd-stats/clappr-nerd-stats.ejs +76 -78
  4. package/assets/clappr-nerd-stats/clappr-nerd-stats.scss +10 -7
  5. package/assets/dvr-controls/dvr_controls.scss +0 -12
  6. package/dist/core.js +5 -7
  7. package/dist/index.css +1245 -1251
  8. package/dist/index.js +425 -261
  9. package/dist/player.d.ts +121 -108
  10. package/dist/plugins/index.css +577 -583
  11. package/dist/plugins/index.js +355 -187
  12. package/docs/api/player.bitratetrackrecord.md +20 -0
  13. package/docs/api/player.clapprstats.exportmetrics.md +2 -2
  14. package/docs/api/player.clapprstats.md +0 -4
  15. package/docs/api/player.clapprstatschronograph.md +115 -0
  16. package/docs/api/player.clapprstatscounter.md +211 -0
  17. package/docs/api/player.clapprstatsevents.md +51 -0
  18. package/docs/api/player.clapprstatsmetrics.md +52 -0
  19. package/docs/api/player.clipspluginsettings.md +1 -1
  20. package/docs/api/player.md +57 -2
  21. package/docs/api/player.nerdstats.md +3 -3
  22. package/docs/api/player.playerconfig.md +1 -1
  23. package/docs/api/player.playerconfig.playbacktype.md +6 -1
  24. package/docs/api/player.timeupdate.md +6 -3
  25. package/lib/playback/dash-playback/DashPlayback.d.ts +0 -1
  26. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  27. package/lib/playback/dash-playback/DashPlayback.js +4 -5
  28. package/lib/playback/hls-playback/HlsPlayback.d.ts +1 -1
  29. package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
  30. package/lib/playback/hls-playback/HlsPlayback.js +0 -1
  31. package/lib/playback.types.d.ts +2 -3
  32. package/lib/playback.types.d.ts.map +1 -1
  33. package/lib/plugins/audio-selector/AudioSelector.d.ts +1 -1
  34. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
  35. package/lib/plugins/audio-selector/AudioSelector.js +15 -8
  36. package/lib/plugins/bottom-gear/BottomGear.d.ts +1 -1
  37. package/lib/plugins/bottom-gear/BottomGear.js +2 -2
  38. package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts +17 -14
  39. package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts.map +1 -1
  40. package/lib/plugins/clappr-nerd-stats/NerdStats.js +175 -124
  41. package/lib/plugins/clappr-nerd-stats/formatter.d.ts +5 -0
  42. package/lib/plugins/clappr-nerd-stats/formatter.d.ts.map +1 -1
  43. package/lib/plugins/clappr-nerd-stats/formatter.js +56 -24
  44. package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts +2 -2
  45. package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts.map +1 -1
  46. package/lib/plugins/clappr-nerd-stats/speedtest/types.d.ts +1 -1
  47. package/lib/plugins/clappr-nerd-stats/speedtest/types.d.ts.map +1 -1
  48. package/lib/plugins/clappr-nerd-stats/types.d.ts +3 -0
  49. package/lib/plugins/clappr-nerd-stats/types.d.ts.map +1 -1
  50. package/lib/plugins/clappr-nerd-stats/utils.d.ts +7 -0
  51. package/lib/plugins/clappr-nerd-stats/utils.d.ts.map +1 -0
  52. package/lib/plugins/clappr-nerd-stats/utils.js +67 -0
  53. package/lib/plugins/clappr-stats/ClapprStats.d.ts +5 -2
  54. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
  55. package/lib/plugins/clappr-stats/ClapprStats.js +31 -33
  56. package/lib/plugins/clappr-stats/types.d.ts +21 -22
  57. package/lib/plugins/clappr-stats/types.d.ts.map +1 -1
  58. package/lib/plugins/clappr-stats/types.js +22 -22
  59. package/lib/plugins/clappr-stats/utils.d.ts +2 -2
  60. package/lib/plugins/clappr-stats/utils.d.ts.map +1 -1
  61. package/lib/plugins/clappr-stats/utils.js +0 -1
  62. package/lib/plugins/click-to-pause/ClickToPause.js +1 -1
  63. package/lib/plugins/clips/Clips.d.ts +1 -1
  64. package/lib/plugins/dvr-controls/DvrControls.d.ts +6 -2
  65. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  66. package/lib/plugins/dvr-controls/DvrControls.js +39 -27
  67. package/lib/plugins/media-control/MediaControl.d.ts +6 -2
  68. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  69. package/lib/plugins/media-control/MediaControl.js +20 -9
  70. package/lib/plugins/picture-in-picture/PictureInPicture.js +1 -1
  71. package/lib/plugins/seek-time/SeekTime.d.ts +1 -1
  72. package/lib/plugins/seek-time/SeekTime.d.ts.map +1 -1
  73. package/lib/plugins/seek-time/SeekTime.js +3 -4
  74. package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
  75. package/lib/plugins/vast-ads/VastAds.js +1 -1
  76. package/lib/plugins/vast-ads/rollmanager.js +1 -1
  77. package/lib/testUtils.d.ts.map +1 -1
  78. package/lib/testUtils.js +7 -4
  79. package/lib/types.d.ts +1 -1
  80. package/package.json +3 -3
  81. package/src/playback/__tests__/HTML5Video.test.ts +2 -2
  82. package/src/playback/dash-playback/DashPlayback.ts +5 -7
  83. package/src/playback/hls-playback/HlsPlayback.ts +2 -4
  84. package/src/playback.types.ts +2 -3
  85. package/src/plugins/audio-selector/AudioSelector.ts +14 -7
  86. package/src/plugins/audio-selector/__tests__/AudioSelector.test.ts +8 -8
  87. package/src/plugins/audio-selector/__tests__/__snapshots__/AudioSelector.test.ts.snap +15 -15
  88. package/src/plugins/bottom-gear/BottomGear.ts +2 -2
  89. package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +8 -5
  90. package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +3 -3
  91. package/src/plugins/clappr-nerd-stats/NerdStats.ts +216 -143
  92. package/src/plugins/clappr-nerd-stats/formatter.ts +91 -47
  93. package/src/plugins/clappr-nerd-stats/speedtest/index.ts +2 -2
  94. package/src/plugins/clappr-nerd-stats/speedtest/types.ts +1 -1
  95. package/src/plugins/clappr-nerd-stats/types.ts +43 -3
  96. package/src/plugins/clappr-nerd-stats/utils.ts +75 -0
  97. package/src/plugins/clappr-stats/ClapprStats.ts +41 -40
  98. package/src/plugins/clappr-stats/__tests__/ClapprStats.test.ts +12 -12
  99. package/src/plugins/clappr-stats/types.ts +43 -44
  100. package/src/plugins/clappr-stats/utils.ts +4 -5
  101. package/src/plugins/click-to-pause/ClickToPause.ts +1 -1
  102. package/src/plugins/clips/Clips.ts +1 -1
  103. package/src/plugins/clips/__tests__/Clips.test.ts +1 -1
  104. package/src/plugins/clips/__tests__/__snapshots__/Clips.test.ts.snap +1 -1
  105. package/src/plugins/dvr-controls/DvrControls.ts +51 -37
  106. package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +84 -26
  107. package/src/plugins/dvr-controls/__tests__/__snapshots__/DvrControls.test.ts.snap +0 -12
  108. package/src/plugins/media-control/MediaControl.ts +21 -9
  109. package/src/plugins/media-control/__tests__/MediaControl.test.ts +8 -5
  110. package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +20 -20
  111. package/src/plugins/picture-in-picture/PictureInPicture.ts +1 -1
  112. package/src/plugins/seek-time/SeekTime.ts +4 -5
  113. package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
  114. package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
  115. package/src/plugins/vast-ads/VastAds.ts +1 -1
  116. package/src/plugins/vast-ads/rollmanager.ts +1 -1
  117. package/src/testUtils.ts +11 -5
  118. package/src/types.ts +1 -1
  119. package/temp/player.api.json +630 -12
  120. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import { UICorePlugin, Events, template } from '@clappr/core';
1
+ import { UICorePlugin, Events, template, Playback, } from '@clappr/core';
2
2
  import { reportError, trace } from '@gcorevideo/utils';
3
3
  import Mousetrap from 'mousetrap';
4
4
  import assert from 'assert';
@@ -12,85 +12,25 @@ import pluginHtml from '../../../assets/clappr-nerd-stats/clappr-nerd-stats.ejs'
12
12
  import buttonHtml from '../../../assets/clappr-nerd-stats/button.ejs';
13
13
  import statsIcon from '../../../assets/icons/new/stats.svg';
14
14
  import { GearEvents } from '../bottom-gear/BottomGear.js';
15
- const qualityClasses = [
16
- 'speedtest-quality-value-1',
17
- 'speedtest-quality-value-2',
18
- 'speedtest-quality-value-3',
19
- 'speedtest-quality-value-4',
20
- 'speedtest-quality-value-5',
21
- ];
22
- const getDownloadQuality = (speedValue) => {
23
- if (speedValue < 3) {
24
- return 1;
25
- }
26
- else if (speedValue < 7) {
27
- return 2;
28
- }
29
- else if (speedValue < 13) {
30
- return 3;
31
- }
32
- else if (speedValue < 25) {
33
- return 4;
34
- }
35
- else {
36
- return 5;
37
- }
38
- };
39
- const getPingQuality = (pingValue) => {
40
- if (pingValue < 20) {
41
- return 5;
42
- }
43
- else if (pingValue < 50) {
44
- return 4;
45
- }
46
- else if (pingValue < 100) {
47
- return 3;
48
- }
49
- else if (pingValue < 150) {
50
- return 2;
51
- }
52
- else {
53
- return 1;
54
- }
55
- };
56
- const generateQualityHtml = (quality) => {
57
- const html = [];
58
- const qualityClassName = qualityClasses[quality - 1];
59
- for (let i = 0; i < qualityClasses.length; i++) {
60
- if (i < quality) {
61
- html.push(`<div class="speedtest-quality-content-item ${qualityClassName}"></div>`);
62
- }
63
- else {
64
- html.push('<div class="speedtest-quality-content-item"></div>');
65
- }
66
- }
67
- return html.join('');
68
- };
69
- const drawSummary = (customMetrics, vodContainer, liveContainer) => {
70
- const { connectionSpeed, ping } = customMetrics;
71
- if (!connectionSpeed || !ping) {
72
- return;
73
- }
74
- const downloadQuality = getDownloadQuality(connectionSpeed);
75
- const pingQuality = getPingQuality(ping);
76
- const liveQuality = Math.min(downloadQuality, pingQuality);
77
- const vodHtml = generateQualityHtml(downloadQuality);
78
- const liveHtml = generateQualityHtml(liveQuality);
79
- vodContainer.html(vodHtml);
80
- liveContainer.html(liveHtml);
15
+ import { drawSummary, getPingQuality } from './utils.js';
16
+ import { getDownloadQuality } from './utils.js';
17
+ const PLAYBACK_NAMES = {
18
+ dash: 'DASH.js',
19
+ hls: 'HLS.js',
20
+ html5_video: 'Native',
81
21
  };
82
22
  const T = 'plugins.nerd_stats';
83
23
  /**
84
- * `PLUGIN` that displays useful network-related statistics.
24
+ * `PLUGIN` that displays useful statistics regarding the playback as well as the network quality estimation.
85
25
  * @beta
86
26
  *
87
27
  * @remarks
88
28
  * Depends on:
89
29
  *
90
- * - {@link BottomGear}
91
- *
92
- * - {@link ClapprStats}
30
+ * - {@link BottomGear} - where the button is attached
93
31
  *
32
+ * - {@link ClapprStats} - to get the metrics from
33
+ *
94
34
  * The plugin is rendered as an item in the gear menu.
95
35
  *
96
36
  * When clicked, it shows an overlay window with the information about the network speed, latency, etc,
@@ -98,13 +38,13 @@ const T = 'plugins.nerd_stats';
98
38
  */
99
39
  export class NerdStats extends UICorePlugin {
100
40
  container = null;
101
- customMetrics = {
41
+ speedtestMetrics = {
102
42
  connectionSpeed: 0,
103
43
  ping: 0,
104
44
  jitter: 0,
105
45
  };
106
46
  metrics = newMetrics();
107
- showing = false;
47
+ open = false;
108
48
  shortcut;
109
49
  iconPosition;
110
50
  static buttonTemplate = template(buttonHtml);
@@ -126,7 +66,6 @@ export class NerdStats extends UICorePlugin {
126
66
  */
127
67
  get attributes() {
128
68
  return {
129
- 'data-clappr-nerd-stats': '',
130
69
  class: 'clappr-nerd-stats',
131
70
  };
132
71
  }
@@ -135,13 +74,17 @@ export class NerdStats extends UICorePlugin {
135
74
  */
136
75
  get events() {
137
76
  return {
138
- 'click [data-show-stats-button]': 'showOrHide',
139
- 'click [data-close-button]': 'hide',
140
- 'click [data-refresh-button]': 'refreshSpeedTest',
77
+ click: 'clicked',
78
+ 'click #nerd-stats-close': 'hide',
79
+ 'click #nerd-stats-refresh': 'refreshSpeedTest',
141
80
  };
142
81
  }
82
+ clicked(e) {
83
+ e.stopPropagation();
84
+ e.preventDefault();
85
+ }
143
86
  get statsBoxElem() {
144
- return '.clappr-nerd-stats[data-clappr-nerd-stats] .stats-box';
87
+ return this.$el.find('#nerd-stats-box');
145
88
  }
146
89
  get statsBoxWidthThreshold() {
147
90
  return 720;
@@ -160,7 +103,7 @@ export class NerdStats extends UICorePlugin {
160
103
  ];
161
104
  this.iconPosition =
162
105
  core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
163
- this.customMetrics = {
106
+ this.speedtestMetrics = {
164
107
  connectionSpeed: 0,
165
108
  ping: 0,
166
109
  jitter: 0,
@@ -172,20 +115,38 @@ export class NerdStats extends UICorePlugin {
172
115
  */
173
116
  bindEvents() {
174
117
  this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
118
+ this.listenTo(this.core, Events.CORE_RESIZE, this.onPlayerResize);
119
+ this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
175
120
  }
176
121
  onCoreReady() {
177
122
  const bottomGear = this.core.getPlugin('bottom_gear');
178
123
  assert(bottomGear, 'bottom_gear plugin is required');
179
- this.listenTo(bottomGear, GearEvents.RENDERED, this.addToBottomGear);
124
+ this.listenTo(bottomGear, GearEvents.RENDERED, this.attach);
125
+ Mousetrap.bind(this.shortcut, this.toggle);
126
+ this.updateResolution();
127
+ }
128
+ onActiveContainerChanged() {
180
129
  this.container = this.core.activeContainer;
181
130
  const clapprStats = this.container?.getPlugin('clappr_stats');
182
131
  assert(clapprStats, 'clappr-stats not available. Please, include it as a plugin of your Clappr instance.\n' +
183
132
  'For more info, visit: https://github.com/clappr/clappr-stats.');
184
- Mousetrap.bind(this.shortcut, this.toggle);
185
- this.listenTo(this.core, Events.CORE_RESIZE, this.onPlayerResize);
186
133
  this.listenTo(clapprStats, ClapprStatsEvents.REPORT, this.updateMetrics);
134
+ this.listenTo(this.core.activeContainer, Events.CONTAINER_VOLUME, () => {
135
+ this.metrics.general.volume = this.container?.volume ?? 0;
136
+ this.$el
137
+ .find('#nerd-stats-volume')
138
+ .text(Formatter.formatVolume(this.metrics.general.volume));
139
+ });
140
+ this.listenTo(this.core.activePlayback, Events.PLAYBACK_LOADEDMETADATA, () => {
141
+ this.$el
142
+ .find('#nerd-stats-playback-type')
143
+ .text(this.formatPlaybackName(this.core.activePlayback.getPlaybackType()));
144
+ });
187
145
  this.updateMetrics(clapprStats.exportMetrics());
188
- this.render();
146
+ this.$el
147
+ .find('#nerd-stats-playback-name')
148
+ .text(PLAYBACK_NAMES[this.core.activePlayback.name] ?? '-');
149
+ this.core.activeContainer.$el.append(this.$el);
189
150
  }
190
151
  /**
191
152
  * @internal
@@ -195,7 +156,7 @@ export class NerdStats extends UICorePlugin {
195
156
  return super.destroy();
196
157
  }
197
158
  toggle = () => {
198
- if (this.showing) {
159
+ if (this.open) {
199
160
  this.hide();
200
161
  }
201
162
  else {
@@ -203,10 +164,11 @@ export class NerdStats extends UICorePlugin {
203
164
  }
204
165
  };
205
166
  show() {
206
- this.core.$el.find(this.statsBoxElem).show();
207
- this.showing = true;
167
+ this.$el.show();
168
+ this.statsBoxElem.scrollTop(this.statsBoxElem.scrollTop());
169
+ this.open = true;
208
170
  this.refreshSpeedTest();
209
- initSpeedTest(this.customMetrics)
171
+ initSpeedTest(this.speedtestMetrics)
210
172
  .then(() => {
211
173
  startSpeedtest();
212
174
  })
@@ -216,21 +178,28 @@ export class NerdStats extends UICorePlugin {
216
178
  });
217
179
  }
218
180
  hide() {
219
- this.core.$el.find(this.statsBoxElem).hide();
220
- this.showing = false;
181
+ this.$el.hide();
182
+ this.open = false;
221
183
  stopSpeedtest();
222
184
  }
223
185
  onPlayerResize() {
224
186
  this.setStatsBoxSize();
187
+ this.updateResolution();
225
188
  }
226
- addGeneralMetrics() {
227
- this.metrics.general = {
228
- displayResolution: this.playerWidth + 'x' + this.playerHeight,
229
- volume: this.container?.volume,
189
+ updateResolution() {
190
+ this.metrics.general.resolution = {
191
+ width: this.playerWidth,
192
+ height: this.playerHeight,
230
193
  };
231
- }
232
- addCustomMetrics() {
233
- this.metrics.custom = this.customMetrics;
194
+ this.$el
195
+ .find('#nerd-stats-resolution-width')
196
+ .text(this.metrics.general.resolution.width);
197
+ this.$el
198
+ .find('#nerd-stats-resolution-height')
199
+ .text(this.metrics.general.resolution.height);
200
+ }
201
+ estimateQuality() {
202
+ trace(`${T} estimateQuality`);
234
203
  const videoQualityNames = [
235
204
  'SD (480p)',
236
205
  'HD (720p)',
@@ -238,9 +207,9 @@ export class NerdStats extends UICorePlugin {
238
207
  '2K (1440p)',
239
208
  '4K (2160p)',
240
209
  ];
241
- const { connectionSpeed, ping } = this.customMetrics;
210
+ const { connectionSpeed, ping } = this.speedtestMetrics;
242
211
  if (!connectionSpeed || !ping) {
243
- const calculatingText = 'Calculating... Please wait.';
212
+ const calculatingText = this.core.i18n.t('stats.calculating');
244
213
  this.metrics.custom.vodQuality = calculatingText;
245
214
  this.metrics.custom.liveQuality = calculatingText;
246
215
  return;
@@ -255,44 +224,109 @@ export class NerdStats extends UICorePlugin {
255
224
  prefix + videoQualityNames[liveQuality - 1];
256
225
  }
257
226
  updateMetrics(metrics) {
227
+ trace(`${T} updateMetrics`, { custom: this.speedtestMetrics });
258
228
  Object.assign(this.metrics, metrics);
259
- this.addGeneralMetrics();
260
- this.addCustomMetrics();
261
- const scrollTop = this.core.$el.find(this.statsBoxElem).scrollTop();
262
- this.$el.html(NerdStats.template({
263
- metrics: Formatter.format(this.metrics),
264
- iconPosition: this.iconPosition,
265
- }));
229
+ this.updateEstimatedQuality();
230
+ this.$el
231
+ .find('#nerd-stats-current-time')
232
+ .text(Formatter.formatTime(this.metrics.extra.currentTime));
233
+ this.$el
234
+ .find('#nerd-stats-video-duration')
235
+ .text(Formatter.formatTime(this.metrics.extra.duration));
236
+ this.$el
237
+ .find('#nerd-stats-buffer-size')
238
+ .text(Formatter.formatTime(this.metrics.extra.buffersize));
239
+ this.$el
240
+ .find('#nerd-stats-bitrate-weighted-mean')
241
+ .text(Formatter.formatBitrate(this.metrics.extra.bitrateWeightedMean));
242
+ this.$el
243
+ .find('#nerd-stats-bitrate-most-used')
244
+ .text(Formatter.formatBitrate(this.metrics.extra.bitrateMostUsed));
245
+ this.$el
246
+ .find('#nerd-stats-watched-percentage')
247
+ .text(Formatter.formatPercentage(this.metrics.extra.watchedPercentage));
248
+ this.$el
249
+ .find('#nerd-stats-buffering-percentage')
250
+ .text(Formatter.formatPercentage(this.metrics.extra.bufferingPercentage));
251
+ this.$el
252
+ .find('#nerd-stats-startup-time')
253
+ .text(Formatter.formatTime(this.metrics.chrono.startup));
254
+ this.$el
255
+ .find('#nerd-stats-watch-time')
256
+ .text(Formatter.formatTime(this.metrics.chrono.watch));
257
+ this.$el
258
+ .find('#nerd-stats-pause-time')
259
+ .text(Formatter.formatTime(this.metrics.chrono.pause));
260
+ this.$el
261
+ .find('#nerd-stats-buffering-time')
262
+ .text(Formatter.formatTime(this.metrics.chrono.buffering));
263
+ this.$el
264
+ .find('#nerd-stats-session-time')
265
+ .text(Formatter.formatTime(this.metrics.chrono.session));
266
+ this.$el.find('#nerd-stats-plays').text(this.metrics.counters.play);
267
+ this.$el.find('#nerd-stats-pauses').text(this.metrics.counters.pause);
268
+ this.$el.find('#nerd-stats-errors').text(this.metrics.counters.error);
269
+ this.$el
270
+ .find('#nerd-stats-bufferings')
271
+ .text(this.metrics.counters.buffering);
272
+ this.$el
273
+ .find('#nerd-stats-decoded-frames')
274
+ .text(this.metrics.counters.decodedFrames);
275
+ this.$el
276
+ .find('#nerd-stats-dropped-frames')
277
+ .text(this.metrics.counters.droppedFrames);
278
+ this.$el
279
+ .find('#nerd-stats-bitrate-changes')
280
+ .text(this.metrics.counters.changeLevel);
281
+ this.$el.find('#nerd-stats-seeks').text(this.metrics.counters.seek);
282
+ this.$el
283
+ .find('#nerd-stats-fullscreen')
284
+ .text(this.metrics.counters.fullscreen);
285
+ this.$el.find('#nerd-stats-dvr-usage').text(this.metrics.counters.dvrUsage);
286
+ this.$el
287
+ .find('#nerd-stats-fps')
288
+ .text(Formatter.formatFps(this.metrics.counters.fps));
266
289
  this.setStatsBoxSize();
267
290
  drawSpeedTestResults();
268
- drawSummary(this.metrics?.custom, this.$el.find('.speedtest-quality-content[data-streaming-type="vod"]'), this.$el.find('.speedtest-quality-content[data-streaming-type="live"]'));
269
- this.core.$el.find(this.statsBoxElem).scrollTop(scrollTop);
270
- if (!this.showing) {
291
+ drawSummary(this.speedtestMetrics, this.$el.find('#nerd-stats-quality-vod'), this.$el.find('#nerd-stats-quality-live'));
292
+ if (!this.open) {
271
293
  this.hide();
272
294
  }
273
295
  }
296
+ updateEstimatedQuality() {
297
+ this.estimateQuality();
298
+ this.$el
299
+ .find('#nerd-stats-quality-vod-text')
300
+ .html(this.metrics.custom.vodQuality);
301
+ this.$el
302
+ .find('#nerd-stats-quality-live-text')
303
+ .html(this.metrics.custom.liveQuality);
304
+ }
274
305
  setStatsBoxSize() {
275
306
  if (this.playerWidth >= this.statsBoxWidthThreshold) {
276
- this.$el.find(this.statsBoxElem).addClass('wide');
277
- this.$el.find(this.statsBoxElem).removeClass('narrow');
307
+ this.statsBoxElem.addClass('wide');
308
+ this.statsBoxElem.removeClass('narrow');
278
309
  }
279
310
  else {
280
- this.$el.find(this.statsBoxElem).removeClass('wide');
281
- this.$el.find(this.statsBoxElem).addClass('narrow');
311
+ this.statsBoxElem.removeClass('wide');
312
+ this.statsBoxElem.addClass('narrow');
282
313
  }
283
314
  }
284
315
  /**
285
316
  * @internal
286
317
  */
287
318
  render() {
288
- trace(`${T} render`);
289
- // TODO append to the container
290
- this.core.$el.append(this.$el[0]);
291
- this.hide();
319
+ this.$el
320
+ .html(NerdStats.template({
321
+ metrics: Formatter.format(this.metrics ?? newMetrics()),
322
+ iconPosition: this.iconPosition,
323
+ i18n: this.core.i18n,
324
+ }))
325
+ .hide();
292
326
  return this;
293
327
  }
294
- addToBottomGear() {
295
- trace(`${T} addToBottomGear`);
328
+ attach() {
329
+ trace(`${T} attach`);
296
330
  const gear = this.core.getPlugin('bottom_gear');
297
331
  gear
298
332
  .addItem('nerd_stats')
@@ -305,11 +339,11 @@ export class NerdStats extends UICorePlugin {
305
339
  this.toggle();
306
340
  });
307
341
  }
308
- clearCustomMetrics() {
342
+ clearSpeedtestMetrics() {
309
343
  const clapprStats = this.container?.getPlugin('clappr_stats');
310
- this.customMetrics.connectionSpeed = 0;
311
- this.customMetrics.ping = 0;
312
- this.customMetrics.jitter = 0;
344
+ this.speedtestMetrics.connectionSpeed = 0;
345
+ this.speedtestMetrics.ping = 0;
346
+ this.speedtestMetrics.jitter = 0;
313
347
  if (clapprStats) {
314
348
  this.updateMetrics(clapprStats.exportMetrics());
315
349
  }
@@ -317,7 +351,7 @@ export class NerdStats extends UICorePlugin {
317
351
  refreshSpeedTest() {
318
352
  stopSpeedtest();
319
353
  setTimeout(() => {
320
- this.clearCustomMetrics();
354
+ this.clearSpeedtestMetrics();
321
355
  clearSpeedTestResults();
322
356
  drawSpeedTestResults();
323
357
  }, 200);
@@ -325,11 +359,28 @@ export class NerdStats extends UICorePlugin {
325
359
  startSpeedtest();
326
360
  }, 800);
327
361
  }
362
+ formatPlaybackName(playbackType) {
363
+ switch (playbackType) {
364
+ case Playback.VOD:
365
+ return this.core.i18n.t('vod');
366
+ case Playback.LIVE:
367
+ return this.core.i18n.t('live');
368
+ default:
369
+ return '-';
370
+ }
371
+ }
328
372
  }
329
373
  function newMetrics() {
330
374
  return {
331
375
  ...newBaseMetrics(),
332
- general: {},
376
+ general: {
377
+ displayResolution: '',
378
+ resolution: {
379
+ width: 0,
380
+ height: 0,
381
+ },
382
+ volume: 0,
383
+ },
333
384
  custom: {
334
385
  connectionSpeed: 0,
335
386
  ping: 0,
@@ -3,6 +3,11 @@ type MetricsValue = number | string;
3
3
  type Metrics = Partial<Record<MetricsKind, Partial<Record<MetricsType, MetricsValue>>>>;
4
4
  export default class Formatter {
5
5
  static format(metrics: Metrics): Metrics;
6
+ static formatVolume(volume: number): string;
7
+ static formatTime(time: number): string;
8
+ static formatFps(fps: number): string;
9
+ static formatPercentage(percentage: number): string;
10
+ static formatBitrate(bitrate: number): string;
6
11
  }
7
12
  export {};
8
13
  //# sourceMappingURL=formatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/formatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAyExD,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AACpC,KAAK,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAExF,MAAM,CAAC,OAAO,OAAO,SAAS;IAC5B,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;CA8BzC"}
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/formatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAsFnE,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,CAAA;AACnC,KAAK,OAAO,GAAG,OAAO,CACpB,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAChE,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,SAAS;IAC5B,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAkCxC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI3C,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAMvC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAIrC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAMnD,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAK9C"}
@@ -3,63 +3,72 @@ const timeScale = new humanFormat.Scale({
3
3
  ms: 1,
4
4
  sec: 1000,
5
5
  min: 60000,
6
- hours: 3600000
6
+ hours: 3600000,
7
7
  });
8
8
  const percentScale = new humanFormat.Scale({
9
- '%': 1
9
+ '%': 1,
10
10
  });
11
+ const metricTemplates = {
12
+ fps: {
13
+ scale: 'SI',
14
+ decimals: 0,
15
+ },
16
+ volume: {
17
+ scale: percentScale,
18
+ },
19
+ };
11
20
  const formattingTemplate = {
12
21
  general: {
13
22
  volume: {
14
- scale: percentScale
15
- }
23
+ scale: percentScale,
24
+ },
16
25
  },
17
26
  timers: {
18
27
  startup: {
19
- scale: timeScale
28
+ scale: timeScale,
20
29
  },
21
30
  watch: {
22
- scale: timeScale
31
+ scale: timeScale,
23
32
  },
24
33
  pause: {
25
- scale: timeScale
34
+ scale: timeScale,
26
35
  },
27
36
  buffering: {
28
- scale: timeScale
37
+ scale: timeScale,
29
38
  },
30
39
  session: {
31
- scale: timeScale
40
+ scale: timeScale,
32
41
  },
33
42
  latency: {
34
- scale: timeScale
35
- }
43
+ scale: timeScale,
44
+ },
36
45
  },
37
46
  extra: {
38
47
  buffersize: {
39
- scale: timeScale
48
+ scale: timeScale,
40
49
  },
41
50
  duration: {
42
- scale: timeScale
51
+ scale: timeScale,
43
52
  },
44
53
  currentTime: {
45
- scale: timeScale
54
+ scale: timeScale,
46
55
  },
47
56
  bitrateWeightedMean: {
48
- unit: 'bps'
57
+ unit: 'bps',
49
58
  },
50
59
  bitrateMostUsed: {
51
- unit: 'bps'
60
+ unit: 'bps',
52
61
  },
53
62
  bandwidth: {
54
- unit: 'bps'
63
+ unit: 'bps',
55
64
  },
56
65
  watchedPercentage: {
57
- scale: percentScale
66
+ scale: percentScale,
58
67
  },
59
68
  bufferingPercentage: {
60
- scale: percentScale
61
- }
62
- }
69
+ scale: percentScale,
70
+ },
71
+ },
63
72
  };
64
73
  export default class Formatter {
65
74
  static format(metrics) {
@@ -69,8 +78,10 @@ export default class Formatter {
69
78
  formattedMetrics[type] = fmt;
70
79
  const typeTemplate = formattingTemplate[type];
71
80
  Object.entries(mm).forEach(([name, value]) => {
72
- // const value = mm[name];
73
- if (typeTemplate && typeTemplate[name] && (typeof value === 'number') && !isNaN(value)) {
81
+ if (typeTemplate &&
82
+ typeTemplate[name] &&
83
+ typeof value === 'number' &&
84
+ !isNaN(value)) {
74
85
  // @ts-ignore
75
86
  const templateScale = typeTemplate[name].scale || 'SI';
76
87
  // @ts-ignore
@@ -78,7 +89,7 @@ export default class Formatter {
78
89
  fmt[name] = humanFormat(value, {
79
90
  scale: templateScale,
80
91
  unit: templateUnit,
81
- decimals: 2
92
+ decimals: 2,
82
93
  });
83
94
  }
84
95
  else {
@@ -88,4 +99,25 @@ export default class Formatter {
88
99
  });
89
100
  return formattedMetrics;
90
101
  }
102
+ static formatVolume(volume) {
103
+ return humanFormat(volume, metricTemplates.volume);
104
+ }
105
+ static formatTime(time) {
106
+ return humanFormat(time, {
107
+ scale: timeScale,
108
+ });
109
+ }
110
+ static formatFps(fps) {
111
+ return humanFormat(fps, metricTemplates.fps);
112
+ }
113
+ static formatPercentage(percentage) {
114
+ return humanFormat(percentage, {
115
+ scale: percentScale,
116
+ });
117
+ }
118
+ static formatBitrate(bitrate) {
119
+ return humanFormat(bitrate, {
120
+ unit: 'bps',
121
+ });
122
+ }
91
123
  }
@@ -1,7 +1,7 @@
1
1
  import { type Server } from './Speedtest.js';
2
- import { CustomMetrics } from './types.js';
2
+ import { SpeedtestMetrics } from './types.js';
3
3
  export declare function drawSpeedTestResults(): void;
4
- export declare const initSpeedTest: (customMetrics: CustomMetrics) => Promise<void>;
4
+ export declare const initSpeedTest: (customMetrics: SpeedtestMetrics) => Promise<void>;
5
5
  export declare const stopSpeedtest: () => void;
6
6
  export declare const startSpeedtest: () => void;
7
7
  export declare const clearSpeedTestResults: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/clappr-nerd-stats/speedtest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAkC,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqC3C,wBAAgB,oBAAoB,SAmBnC;AAID,eAAO,MAAM,aAAa,kBAAmB,aAAa,KAAG,OAAO,CAAC,IAAI,CA+ExE,CAAC;AAEF,eAAO,MAAM,aAAa,YAIzB,CAAC;AAEF,eAAO,MAAM,cAAc,YAI1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,YAEjC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAGnD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/clappr-nerd-stats/speedtest/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAkC,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAqC9C,wBAAgB,oBAAoB,SAmBnC;AAID,eAAO,MAAM,aAAa,kBAAmB,gBAAgB,KAAG,OAAO,CAAC,IAAI,CA+E3E,CAAC;AAEF,eAAO,MAAM,aAAa,YAIzB,CAAC;AAEF,eAAO,MAAM,cAAc,YAI1B,CAAC;AAEF,eAAO,MAAM,qBAAqB,YAEjC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAGnD"}
@@ -1,4 +1,4 @@
1
- export type CustomMetrics = {
1
+ export type SpeedtestMetrics = {
2
2
  ping: number;
3
3
  jitter: number;
4
4
  connectionSpeed: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/plugins/clappr-nerd-stats/speedtest/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/plugins/clappr-nerd-stats/speedtest/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB,CAAA"}
@@ -1,4 +1,7 @@
1
1
  export type MetricsKind = 'general' | 'timers' | 'extra';
2
+ export type MetricType = 'general' | 'timers' | 'extra';
2
3
  export type MetricsType = 'volume' | 'startup' | 'watch' | 'pause' | 'buffering' | 'session' | 'latency' | 'buffersize' | 'duration' | 'currentTime' | 'bitrateWeightedMean' | 'bitrateMostUsed' | 'bandwidth' | 'watchedPercentage' | 'bufferingPercentage';
4
+ export type MetricName = 'volume' | 'startup' | 'watch' | 'pause' | 'buffering' | 'session' | 'latency' | 'buffersize' | 'duration' | 'currentTime' | 'bitrateWeightedMean' | 'bitrateMostUsed' | 'bandwidth' | 'watchedPercentage' | 'bufferingPercentage' | 'fps';
5
+ export type MetricKind = 'volume' | 'time' | 'precisetime' | 'percentage' | 'bitrate' | 'bandwidth';
3
6
  export type MetricsValue = number;
4
7
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AACzD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,qBAAqB,GAAG,iBAAiB,GAAG,WAAW,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAC7P,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AACxD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AACvD,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,WAAW,GACX,SAAS,GACT,SAAS,GACT,YAAY,GACZ,UAAU,GACV,aAAa,GACb,qBAAqB,GACrB,iBAAiB,GACjB,WAAW,GACX,mBAAmB,GACnB,qBAAqB,CAAA;AACzB,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,OAAO,GACP,WAAW,GACX,SAAS,GACT,SAAS,GACT,YAAY,GACZ,UAAU,GACV,aAAa,GACb,qBAAqB,GACrB,iBAAiB,GACjB,WAAW,GACX,mBAAmB,GACnB,qBAAqB,GACrB,KAAK,CAAA;AACT,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,MAAM,GACN,aAAa,GACb,YAAY,GACZ,SAAS,GACT,WAAW,CAAA;AACf,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { ZeptoResult } from "../../types";
2
+ import { SpeedtestMetrics } from "./speedtest/types";
3
+ export declare const getDownloadQuality: (speedValue: number) => number;
4
+ export declare const getPingQuality: (pingValue: number) => number;
5
+ export declare const generateQualityHtml: (quality: number) => string;
6
+ export declare const drawSummary: (customMetrics: SpeedtestMetrics, vodContainer: ZeptoResult, liveContainer: ZeptoResult) => void;
7
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAUpD,eAAO,MAAM,kBAAkB,eAAgB,MAAM,KAAG,MAYvD,CAAA;AAED,eAAO,MAAM,cAAc,cAAe,MAAM,KAAG,MAYlD,CAAA;AAED,eAAO,MAAM,mBAAmB,YAAa,MAAM,KAAG,MAerD,CAAA;AAED,eAAO,MAAM,WAAW,kBACP,gBAAgB,gBACjB,WAAW,iBACV,WAAW,SAe3B,CAAA"}