@gcorevideo/player 2.28.3 → 2.28.4

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 (52) hide show
  1. package/dist/core.js +1 -1
  2. package/dist/index.css +459 -459
  3. package/dist/index.js +1 -1
  4. package/package.json +2 -2
  5. package/tsconfig.tsbuildinfo +1 -1
  6. package/coverage/clover.xml +0 -6
  7. package/coverage/coverage-final.json +0 -1
  8. package/coverage/lcov-report/base.css +0 -224
  9. package/coverage/lcov-report/block-navigation.js +0 -87
  10. package/coverage/lcov-report/favicon.png +0 -0
  11. package/coverage/lcov-report/index.html +0 -101
  12. package/coverage/lcov-report/prettify.css +0 -1
  13. package/coverage/lcov-report/prettify.js +0 -2
  14. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  15. package/coverage/lcov-report/sorter.js +0 -196
  16. package/coverage/lcov.info +0 -0
  17. package/dist/player.d.ts +0 -3369
  18. package/lib/playback/utils.d.ts +0 -2
  19. package/lib/playback/utils.d.ts.map +0 -1
  20. package/lib/playback/utils.js +0 -1
  21. package/lib/plugins/audio-selector/AudioSelector.d.ts +0 -67
  22. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +0 -1
  23. package/lib/plugins/audio-selector/AudioSelector.js +0 -172
  24. package/lib/plugins/build.d.ts +0 -2
  25. package/lib/plugins/build.d.ts.map +0 -1
  26. package/lib/plugins/build.js +0 -1
  27. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +0 -83
  28. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +0 -1
  29. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +0 -339
  30. package/lib/plugins/disable-controls/DisableControls.d.ts +0 -15
  31. package/lib/plugins/disable-controls/DisableControls.d.ts.map +0 -1
  32. package/lib/plugins/disable-controls/DisableControls.js +0 -67
  33. package/lib/plugins/index.d.ts +0 -35
  34. package/lib/plugins/index.d.ts.map +0 -1
  35. package/lib/plugins/index.js +0 -37
  36. package/lib/plugins/level-selector/LevelSelector.d.ts +0 -112
  37. package/lib/plugins/level-selector/LevelSelector.d.ts.map +0 -1
  38. package/lib/plugins/level-selector/LevelSelector.js +0 -280
  39. package/lib/plugins/statistics/Statistics.d.ts +0 -87
  40. package/lib/plugins/statistics/Statistics.d.ts.map +0 -1
  41. package/lib/plugins/statistics/Statistics.js +0 -172
  42. package/lib/plugins/subtitles/Subtitles.d.ts +0 -115
  43. package/lib/plugins/subtitles/Subtitles.d.ts.map +0 -1
  44. package/lib/plugins/subtitles/Subtitles.js +0 -345
  45. package/lib/tsdoc-metadata.json +0 -11
  46. package/lib/utils/fullscreen.d.ts +0 -3
  47. package/lib/utils/fullscreen.d.ts.map +0 -1
  48. package/lib/utils/fullscreen.js +0 -2
  49. package/release.txt +0 -395
  50. package/release_notes +0 -297
  51. package/src/plugins/telemetry/Statistics copy.js +0 -296
  52. package/temp/player.api.json +0 -10275
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/playback/utils.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};
@@ -1,67 +0,0 @@
1
- import { UICorePlugin } from '@clappr/core';
2
- import '../../../assets/audio-selector/style.scss';
3
- /**
4
- * `PLUGIN` that makes possible to switch audio tracks via the media control UI.
5
- * @beta
6
- * @remarks
7
- * The plugin is activated when there are multiple audio tracks available.
8
- * The plugin adds a button showing the current audio track and a dropdown to switch to another audio track.
9
- * Depends on:
10
- *
11
- * - {@link MediaControl}
12
- */
13
- export declare class AudioTracks extends UICorePlugin {
14
- private currentTrack;
15
- private tracks;
16
- /**
17
- * @internal
18
- */
19
- get name(): string;
20
- /**
21
- * @internal
22
- */
23
- get supportedVersion(): {
24
- min: string;
25
- };
26
- /**
27
- * @internal
28
- */
29
- static get version(): string;
30
- private static readonly template;
31
- /**
32
- * @internal
33
- */
34
- get attributes(): {
35
- class: string;
36
- };
37
- /**
38
- * @internal
39
- */
40
- get events(): {
41
- 'click [data-audiotracks-select]': string;
42
- 'click #audiotracks-button': string;
43
- };
44
- /**
45
- * @internal
46
- */
47
- bindEvents(): void;
48
- private onCoreReady;
49
- private onActiveContainerChanged;
50
- private shouldRender;
51
- /**
52
- * @internal
53
- */
54
- render(): this;
55
- private onTrackSelect;
56
- private selectAudioTrack;
57
- private hideMenu;
58
- private toggleContextMenu;
59
- private buttonElement;
60
- private buttonElementText;
61
- private trackElement;
62
- private getTitle;
63
- private startTrackSwitching;
64
- private updateText;
65
- private highlightCurrentTrack;
66
- }
67
- //# sourceMappingURL=AudioSelector.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AudioSelector.d.ts","sourceRoot":"","sources":["../../../src/plugins/audio-selector/AudioSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAY,MAAM,cAAc,CAAA;AAO7D,OAAO,2CAA2C,CAAA;AAUlD;;;;;;;;;GASG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,YAAY,CAA0B;IAE9C,OAAO,CAAC,MAAM,CAAmB;IAEjC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEvD;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;MAKlB;IAED;;OAEG;IACM,UAAU;IASnB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACM,MAAM;IAmBf,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,qBAAqB;CAe9B"}
@@ -1,172 +0,0 @@
1
- import { Events, UICorePlugin, template } from '@clappr/core';
2
- import assert from 'assert';
3
- import { CLAPPR_VERSION } from '../../build.js';
4
- import pluginHtml from '../../../assets/audio-selector/track-selector.ejs';
5
- import '../../../assets/audio-selector/style.scss';
6
- import audioArrow from '../../../assets/icons/old/quality-arrow.svg';
7
- // import { trace } from '@gcorevideo/utils'
8
- const VERSION = '2.22.4';
9
- // const T = 'plugins.audiotracks'
10
- /**
11
- * `PLUGIN` that makes possible to switch audio tracks via the media control UI.
12
- * @beta
13
- * @remarks
14
- * The plugin is activated when there are multiple audio tracks available.
15
- * The plugin adds a button showing the current audio track and a dropdown to switch to another audio track.
16
- * Depends on:
17
- *
18
- * - {@link MediaControl}
19
- */
20
- export class AudioTracks extends UICorePlugin {
21
- currentTrack = null;
22
- tracks = [];
23
- /**
24
- * @internal
25
- */
26
- get name() {
27
- return 'audio_selector'; // TODO rename to audiotracks
28
- }
29
- /**
30
- * @internal
31
- */
32
- get supportedVersion() {
33
- return { min: CLAPPR_VERSION };
34
- }
35
- /**
36
- * @internal
37
- */
38
- static get version() {
39
- return VERSION;
40
- }
41
- static template = template(pluginHtml);
42
- /**
43
- * @internal
44
- */
45
- get attributes() {
46
- return {
47
- class: 'media-control-audiotracks',
48
- };
49
- }
50
- /**
51
- * @internal
52
- */
53
- get events() {
54
- return {
55
- 'click [data-audiotracks-select]': 'onTrackSelect',
56
- 'click #audiotracks-button': 'toggleContextMenu',
57
- };
58
- }
59
- /**
60
- * @internal
61
- */
62
- bindEvents() {
63
- this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
64
- this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
65
- }
66
- onCoreReady() {
67
- const mediaControl = this.core.getPlugin('media_control');
68
- assert(mediaControl, 'media_control plugin is required');
69
- this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, () => {
70
- mediaControl.mount('audiotracks', this.$el);
71
- });
72
- this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, this.hideMenu);
73
- }
74
- onActiveContainerChanged() {
75
- this.currentTrack = null;
76
- this.listenTo(this.core.activeContainer, Events.CONTAINER_AUDIO_AVAILABLE, (tracks) => {
77
- this.currentTrack =
78
- tracks.find((track) => track.kind === 'main') ?? null; // TODO test
79
- this.tracks = tracks;
80
- this.render();
81
- });
82
- this.listenTo(this.core.activeContainer, Events.CONTAINER_AUDIO_CHANGED, (track) => {
83
- this.currentTrack = track;
84
- this.highlightCurrentTrack();
85
- this.buttonElement().removeClass('changing');
86
- this.updateText();
87
- });
88
- }
89
- shouldRender() {
90
- // Render is called from the parent class constructor so tracks aren't available
91
- // Only care if we have at least 2 to choose from
92
- return this.tracks?.length > 1;
93
- }
94
- /**
95
- * @internal
96
- */
97
- render() {
98
- if (!this.shouldRender()) {
99
- return this;
100
- }
101
- this.$el.html(AudioTracks.template({
102
- tracks: this.tracks,
103
- title: this.getTitle(),
104
- icon: audioArrow,
105
- current: this.currentTrack?.id,
106
- }));
107
- this.updateText();
108
- this.highlightCurrentTrack();
109
- return this;
110
- }
111
- onTrackSelect(event) {
112
- const id = event.currentTarget?.dataset?.audiotracksSelect;
113
- if (id) {
114
- this.selectAudioTrack(id);
115
- }
116
- this.hideMenu();
117
- event.stopPropagation();
118
- return false;
119
- }
120
- selectAudioTrack(id) {
121
- this.startTrackSwitching();
122
- this.core.activeContainer.switchAudioTrack(id);
123
- this.updateText();
124
- }
125
- hideMenu() {
126
- this.$el.find('#audiotracks-select').addClass('hidden');
127
- }
128
- toggleContextMenu() {
129
- this.$el.find('#audiotracks-select').toggleClass('hidden'); // TODO use plain CSS display: none
130
- const open = !this.$el.find('#audiotracks-select').hasClass('hidden'); // TODO hold state
131
- this.$el.find('#audiotracks-button').attr('aria-expanded', open);
132
- }
133
- buttonElement() {
134
- return this.$('button');
135
- }
136
- buttonElementText() {
137
- return this.$('button .audio-text');
138
- }
139
- trackElement(id) {
140
- return this.$('#audiotracks-select a' +
141
- (id !== undefined ? `[data-audiotracks-select="${id}"]` : '')).parent();
142
- }
143
- getTitle() {
144
- if (!this.currentTrack) {
145
- return '';
146
- }
147
- return this.currentTrack.label || this.currentTrack.language;
148
- }
149
- startTrackSwitching() {
150
- this.buttonElement().addClass('changing');
151
- }
152
- updateText() {
153
- if (!this.currentTrack) {
154
- return;
155
- }
156
- this.buttonElementText().text(this.currentTrack.label);
157
- }
158
- highlightCurrentTrack() {
159
- this.trackElement().removeClass('current');
160
- this.trackElement()
161
- .find('a')
162
- .removeClass('gcore-skin-active')
163
- .attr('aria-checked', 'false');
164
- if (this.currentTrack) {
165
- this.trackElement(this.currentTrack.id)
166
- .addClass('current')
167
- .find('a')
168
- .addClass('gcore-skin-active')
169
- .attr('aria-checked', 'true');
170
- }
171
- }
172
- }
@@ -1,2 +0,0 @@
1
- export declare const CLAPPR_VERSION: string;
2
- //# sourceMappingURL=build.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/plugins/build.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,EAAE,MAAiB,CAAC"}
@@ -1 +0,0 @@
1
- export const CLAPPR_VERSION = '0.11.3';
@@ -1,83 +0,0 @@
1
- import { UICorePlugin, Core } from '@clappr/core';
2
- import '../../../assets/clappr-nerd-stats/clappr-nerd-stats.scss';
3
- /**
4
- * `PLUGIN` that displays useful network-related statistics.
5
- * @beta
6
- *
7
- * @remarks
8
- * Depends on:
9
- *
10
- * - {@link BottomGear}
11
- *
12
- * - {@link ClapprStats}
13
- *
14
- * The plugin is rendered as an item in the gear menu.
15
- *
16
- * When clicked, it shows an overlay window with the information about the network speed, latency, etc,
17
- * and recommended quality level.
18
- */
19
- export declare class ClapprNerdStats extends UICorePlugin {
20
- private container;
21
- private customMetrics;
22
- private metrics;
23
- private showing;
24
- private shortcut;
25
- private iconPosition;
26
- private static readonly buttonTemplate;
27
- /**
28
- * @internal
29
- */
30
- get name(): string;
31
- /**
32
- * @internal
33
- */
34
- get supportedVersion(): {
35
- min: string;
36
- };
37
- private static readonly template;
38
- /**
39
- * @internal
40
- */
41
- get attributes(): {
42
- 'data-clappr-nerd-stats': string;
43
- class: string;
44
- };
45
- /**
46
- * @internal
47
- */
48
- get events(): {
49
- 'click [data-show-stats-button]': string;
50
- 'click [data-close-button]': string;
51
- 'click [data-refresh-button]': string;
52
- };
53
- private get statsBoxElem();
54
- private get statsBoxWidthThreshold();
55
- private get playerWidth();
56
- private get playerHeight();
57
- constructor(core: Core);
58
- /**
59
- * @internal
60
- */
61
- bindEvents(): void;
62
- private onCoreReady;
63
- /**
64
- * @internal
65
- */
66
- destroy(): import("@clappr/core").UIObject;
67
- private toggle;
68
- private show;
69
- private hide;
70
- private onPlayerResize;
71
- private addGeneralMetrics;
72
- private addCustomMetrics;
73
- private updateMetrics;
74
- private setStatsBoxSize;
75
- /**
76
- * @internal
77
- */
78
- render(): this;
79
- private addToBottomGear;
80
- private clearCustomMetrics;
81
- private refreshSpeedTest;
82
- }
83
- //# sourceMappingURL=ClapprNerdStats.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClapprNerdStats.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/ClapprNerdStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,IAAI,EAAa,MAAM,cAAc,CAAA;AAuB9E,OAAO,0DAA0D,CAAA;AA8FjE;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,SAAS,CAAyB;IAE1C,OAAO,CAAC,aAAa,CAIpB;IAED,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,YAAY,CAAc;IAElC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAuB;IAE7D;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEvD;;OAEG;IACH,IAAa,UAAU;;;MAKtB;IAED;;OAEG;IACH,IAAa,MAAM;;;;MAMlB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,sBAAsB,GAEjC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,YAAY,GAEvB;gBAEW,IAAI,EAAE,IAAI;IAgBtB;;OAEG;IACM,UAAU;IAInB,OAAO,CAAC,WAAW;IAoBnB;;OAEG;IACM,OAAO;IAKhB,OAAO,CAAC,MAAM,CAMb;IAED,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACM,MAAM;IASf,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;CAWzB"}
@@ -1,339 +0,0 @@
1
- import { UICorePlugin, Events, template } from '@clappr/core';
2
- import { reportError, trace } from '@gcorevideo/utils';
3
- import Mousetrap from 'mousetrap';
4
- import assert from 'assert';
5
- import { CLAPPR_VERSION } from '../../build.js';
6
- import { ClapprStatsEvents, } from '../clappr-stats/types.js';
7
- import { newMetrics as newBaseMetrics } from '../clappr-stats/utils.js';
8
- import Formatter from './formatter.js';
9
- import { clearSpeedTestResults, configureSpeedTest, drawSpeedTestResults, initSpeedTest, startSpeedtest, stopSpeedtest, } from './speedtest/index.js';
10
- import '../../../assets/clappr-nerd-stats/clappr-nerd-stats.scss';
11
- import pluginHtml from '../../../assets/clappr-nerd-stats/clappr-nerd-stats.ejs';
12
- import buttonHtml from '../../../assets/clappr-nerd-stats/button.ejs';
13
- import statsIcon from '../../../assets/icons/new/stats.svg';
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);
81
- };
82
- const T = 'plugins.nerd_stats';
83
- /**
84
- * `PLUGIN` that displays useful network-related statistics.
85
- * @beta
86
- *
87
- * @remarks
88
- * Depends on:
89
- *
90
- * - {@link BottomGear}
91
- *
92
- * - {@link ClapprStats}
93
- *
94
- * The plugin is rendered as an item in the gear menu.
95
- *
96
- * When clicked, it shows an overlay window with the information about the network speed, latency, etc,
97
- * and recommended quality level.
98
- */
99
- export class ClapprNerdStats extends UICorePlugin {
100
- container = null;
101
- customMetrics = {
102
- connectionSpeed: 0,
103
- ping: 0,
104
- jitter: 0,
105
- };
106
- metrics = newMetrics();
107
- showing = false;
108
- shortcut;
109
- iconPosition;
110
- static buttonTemplate = template(buttonHtml);
111
- /**
112
- * @internal
113
- */
114
- get name() {
115
- return 'nerd_stats';
116
- }
117
- /**
118
- * @internal
119
- */
120
- get supportedVersion() {
121
- return { min: CLAPPR_VERSION };
122
- }
123
- static template = template(pluginHtml);
124
- /**
125
- * @internal
126
- */
127
- get attributes() {
128
- return {
129
- 'data-clappr-nerd-stats': '',
130
- class: 'clappr-nerd-stats',
131
- };
132
- }
133
- /**
134
- * @internal
135
- */
136
- get events() {
137
- return {
138
- 'click [data-show-stats-button]': 'showOrHide',
139
- 'click [data-close-button]': 'hide',
140
- 'click [data-refresh-button]': 'refreshSpeedTest',
141
- };
142
- }
143
- get statsBoxElem() {
144
- return '.clappr-nerd-stats[data-clappr-nerd-stats] .stats-box';
145
- }
146
- get statsBoxWidthThreshold() {
147
- return 720;
148
- }
149
- get playerWidth() {
150
- return this.core.$el.width();
151
- }
152
- get playerHeight() {
153
- return this.core.$el.height();
154
- }
155
- constructor(core) {
156
- super(core);
157
- this.shortcut = core.options.clapprNerdStats?.shortcut ?? [
158
- 'command+shift+s',
159
- 'ctrl+shift+s',
160
- ];
161
- this.iconPosition =
162
- core.options.clapprNerdStats?.iconPosition ?? 'bottom-right';
163
- this.customMetrics = {
164
- connectionSpeed: 0,
165
- ping: 0,
166
- jitter: 0,
167
- };
168
- configureSpeedTest(core.options.clapprNerdStats?.speedTestServers ?? []);
169
- }
170
- /**
171
- * @internal
172
- */
173
- bindEvents() {
174
- this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
175
- }
176
- onCoreReady() {
177
- const bottomGear = this.core.getPlugin('bottom_gear');
178
- assert(bottomGear, 'bottom_gear plugin is required');
179
- this.listenTo(bottomGear, GearEvents.RENDERED, this.addToBottomGear);
180
- this.container = this.core.activeContainer;
181
- const clapprStats = this.container?.getPlugin('clappr_stats');
182
- assert(clapprStats, 'clappr-stats not available. Please, include it as a plugin of your Clappr instance.\n' +
183
- '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
- this.listenTo(clapprStats, ClapprStatsEvents.REPORT, this.updateMetrics);
187
- this.updateMetrics(clapprStats.exportMetrics());
188
- this.render();
189
- }
190
- /**
191
- * @internal
192
- */
193
- destroy() {
194
- Mousetrap.unbind(this.shortcut);
195
- return super.destroy();
196
- }
197
- toggle = () => {
198
- if (this.showing) {
199
- this.hide();
200
- }
201
- else {
202
- this.show();
203
- }
204
- };
205
- show() {
206
- this.core.$el.find(this.statsBoxElem).show();
207
- this.showing = true;
208
- this.refreshSpeedTest();
209
- initSpeedTest(this.customMetrics)
210
- .then(() => {
211
- startSpeedtest();
212
- })
213
- .catch((e) => {
214
- reportError(e);
215
- this.disable();
216
- });
217
- }
218
- hide() {
219
- this.core.$el.find(this.statsBoxElem).hide();
220
- this.showing = false;
221
- stopSpeedtest();
222
- }
223
- onPlayerResize() {
224
- this.setStatsBoxSize();
225
- }
226
- addGeneralMetrics() {
227
- this.metrics.general = {
228
- displayResolution: this.playerWidth + 'x' + this.playerHeight,
229
- volume: this.container?.volume,
230
- };
231
- }
232
- addCustomMetrics() {
233
- this.metrics.custom = this.customMetrics;
234
- const videoQualityNames = [
235
- 'SD (480p)',
236
- 'HD (720p)',
237
- 'Full HD (1080p)',
238
- '2K (1440p)',
239
- '4K (2160p)',
240
- ];
241
- const { connectionSpeed, ping } = this.customMetrics;
242
- if (!connectionSpeed || !ping) {
243
- const calculatingText = 'Calculating... Please wait.';
244
- this.metrics.custom.vodQuality = calculatingText;
245
- this.metrics.custom.liveQuality = calculatingText;
246
- return;
247
- }
248
- const downloadQuality = getDownloadQuality(connectionSpeed);
249
- const pingQuality = getPingQuality(ping);
250
- const liveQuality = Math.min(downloadQuality, pingQuality);
251
- const prefix = 'Optimal for ';
252
- this.metrics.custom.vodQuality =
253
- prefix + videoQualityNames[downloadQuality - 1];
254
- this.metrics.custom.liveQuality =
255
- prefix + videoQualityNames[liveQuality - 1];
256
- }
257
- updateMetrics(metrics) {
258
- 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(ClapprNerdStats.template({
263
- metrics: Formatter.format(this.metrics),
264
- iconPosition: this.iconPosition,
265
- }));
266
- this.setStatsBoxSize();
267
- 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) {
271
- this.hide();
272
- }
273
- }
274
- setStatsBoxSize() {
275
- if (this.playerWidth >= this.statsBoxWidthThreshold) {
276
- this.$el.find(this.statsBoxElem).addClass('wide');
277
- this.$el.find(this.statsBoxElem).removeClass('narrow');
278
- }
279
- else {
280
- this.$el.find(this.statsBoxElem).removeClass('wide');
281
- this.$el.find(this.statsBoxElem).addClass('narrow');
282
- }
283
- }
284
- /**
285
- * @internal
286
- */
287
- render() {
288
- trace(`${T} render`);
289
- // TODO append to the container
290
- this.core.$el.append(this.$el[0]);
291
- this.hide();
292
- return this;
293
- }
294
- addToBottomGear() {
295
- trace(`${T} addToBottomGear`);
296
- const gear = this.core.getPlugin('bottom_gear');
297
- gear
298
- .addItem('nerd_stats')
299
- .html(ClapprNerdStats.buttonTemplate({
300
- icon: statsIcon,
301
- i18n: this.core.i18n,
302
- }))
303
- .on('click', (e) => {
304
- e.stopPropagation();
305
- this.toggle();
306
- });
307
- }
308
- clearCustomMetrics() {
309
- const clapprStats = this.container?.getPlugin('clappr_stats');
310
- this.customMetrics.connectionSpeed = 0;
311
- this.customMetrics.ping = 0;
312
- this.customMetrics.jitter = 0;
313
- if (clapprStats) {
314
- this.updateMetrics(clapprStats.exportMetrics());
315
- }
316
- }
317
- refreshSpeedTest() {
318
- stopSpeedtest();
319
- setTimeout(() => {
320
- this.clearCustomMetrics();
321
- clearSpeedTestResults();
322
- drawSpeedTestResults();
323
- }, 200);
324
- setTimeout(() => {
325
- startSpeedtest();
326
- }, 800);
327
- }
328
- }
329
- function newMetrics() {
330
- return {
331
- ...newBaseMetrics(),
332
- general: {},
333
- custom: {
334
- connectionSpeed: 0,
335
- ping: 0,
336
- jitter: 0,
337
- },
338
- };
339
- }