@gcorevideo/player 2.22.16 → 2.22.18

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 (104) hide show
  1. package/assets/clappr-nerd-stats/clappr-nerd-stats.ejs +76 -78
  2. package/assets/clappr-nerd-stats/clappr-nerd-stats.scss +10 -7
  3. package/dist/core.js +10 -14
  4. package/dist/index.css +1441 -1440
  5. package/dist/index.js +589 -522
  6. package/dist/player.d.ts +216 -159
  7. package/dist/plugins/index.css +1204 -1203
  8. package/dist/plugins/index.js +581 -506
  9. package/docs/api/player.clapprstats.exportmetrics.md +1 -1
  10. package/docs/api/player.clapprstats.md +5 -15
  11. package/docs/api/player.clapprstatssettings.md +13 -0
  12. package/docs/api/player.clips.destroy.md +18 -0
  13. package/docs/api/player.clips.disable.md +18 -0
  14. package/docs/api/player.clips.enable.md +18 -0
  15. package/docs/api/player.clips.md +170 -0
  16. package/docs/api/player.clips.render.md +18 -0
  17. package/docs/api/player.clips.supportedversion.md +16 -0
  18. package/docs/api/player.clips.version.md +14 -0
  19. package/docs/api/player.clipspluginsettings.md +2 -2
  20. package/docs/api/player.clipspluginsettings.text.md +1 -1
  21. package/docs/api/player.md +27 -18
  22. package/docs/api/player.mediacontrol.md +1 -1
  23. package/docs/api/{player.mediacontrol.getelement.md → player.mediacontrol.mount.md} +20 -7
  24. package/docs/api/player.mediacontrolleftelement.md +1 -1
  25. package/docs/api/{player.clapprnerdstats._constructor_.md → player.nerdstats._constructor_.md} +3 -3
  26. package/docs/api/{player.clapprnerdstats.md → player.nerdstats.md} +5 -5
  27. package/docs/api/player.qualitylevel.height.md +1 -1
  28. package/docs/api/player.qualitylevel.level.md +1 -1
  29. package/docs/api/player.qualitylevel.md +4 -4
  30. package/docs/api/player.qualitylevel.width.md +1 -1
  31. package/docs/api/player.timeposition.current.md +1 -1
  32. package/docs/api/player.timeposition.md +2 -2
  33. package/docs/api/player.timeposition.total.md +1 -1
  34. package/docs/api/player.timeprogress.md +6 -4
  35. package/docs/api/player.timevalue.md +1 -1
  36. package/lib/index.plugins.d.ts +2 -1
  37. package/lib/index.plugins.d.ts.map +1 -1
  38. package/lib/index.plugins.js +2 -1
  39. package/lib/playback/dash-playback/DashPlayback.d.ts +0 -1
  40. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  41. package/lib/playback/dash-playback/DashPlayback.js +9 -12
  42. package/lib/playback/hls-playback/HlsPlayback.d.ts +1 -1
  43. package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
  44. package/lib/playback/hls-playback/HlsPlayback.js +0 -1
  45. package/lib/playback.types.d.ts +24 -12
  46. package/lib/playback.types.d.ts.map +1 -1
  47. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +4 -0
  48. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  49. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +20 -23
  50. package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts +86 -0
  51. package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts.map +1 -0
  52. package/lib/plugins/clappr-nerd-stats/NerdStats.js +390 -0
  53. package/lib/plugins/clappr-nerd-stats/formatter.d.ts +5 -0
  54. package/lib/plugins/clappr-nerd-stats/formatter.d.ts.map +1 -1
  55. package/lib/plugins/clappr-nerd-stats/formatter.js +56 -24
  56. package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts +2 -2
  57. package/lib/plugins/clappr-nerd-stats/speedtest/index.d.ts.map +1 -1
  58. package/lib/plugins/clappr-nerd-stats/speedtest/types.d.ts +1 -1
  59. package/lib/plugins/clappr-nerd-stats/speedtest/types.d.ts.map +1 -1
  60. package/lib/plugins/clappr-nerd-stats/types.d.ts +3 -0
  61. package/lib/plugins/clappr-nerd-stats/types.d.ts.map +1 -1
  62. package/lib/plugins/clappr-nerd-stats/utils.d.ts +7 -0
  63. package/lib/plugins/clappr-nerd-stats/utils.d.ts.map +1 -0
  64. package/lib/plugins/clappr-nerd-stats/utils.js +67 -0
  65. package/lib/plugins/clappr-stats/ClapprStats.d.ts +27 -32
  66. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
  67. package/lib/plugins/clappr-stats/ClapprStats.js +94 -202
  68. package/lib/plugins/clappr-stats/types.d.ts +65 -25
  69. package/lib/plugins/clappr-stats/types.d.ts.map +1 -1
  70. package/lib/plugins/clappr-stats/types.js +37 -2
  71. package/lib/plugins/clappr-stats/utils.d.ts +1 -1
  72. package/lib/plugins/clappr-stats/utils.d.ts.map +1 -1
  73. package/lib/plugins/clappr-stats/utils.js +1 -3
  74. package/lib/plugins/seek-time/SeekTime.d.ts +1 -1
  75. package/lib/plugins/seek-time/SeekTime.d.ts.map +1 -1
  76. package/lib/plugins/seek-time/SeekTime.js +3 -4
  77. package/lib/testUtils.d.ts +2 -1
  78. package/lib/testUtils.d.ts.map +1 -1
  79. package/lib/testUtils.js +3 -2
  80. package/package.json +1 -1
  81. package/src/index.plugins.ts +2 -1
  82. package/src/playback/dash-playback/DashPlayback.ts +10 -15
  83. package/src/playback/hls-playback/HlsPlayback.ts +2 -4
  84. package/src/playback.types.ts +25 -11
  85. package/src/plugins/clappr-nerd-stats/NerdStats.ts +503 -0
  86. package/src/plugins/clappr-nerd-stats/formatter.ts +91 -47
  87. package/src/plugins/clappr-nerd-stats/speedtest/index.ts +2 -2
  88. package/src/plugins/clappr-nerd-stats/speedtest/types.ts +1 -1
  89. package/src/plugins/clappr-nerd-stats/types.ts +43 -3
  90. package/src/plugins/clappr-nerd-stats/utils.ts +75 -0
  91. package/src/plugins/clappr-stats/ClapprStats.ts +242 -306
  92. package/src/plugins/clappr-stats/__tests__/ClapprStats.test.ts +133 -0
  93. package/src/plugins/clappr-stats/types.ts +93 -47
  94. package/src/plugins/clappr-stats/utils.ts +4 -6
  95. package/src/plugins/error-screen/__tests__/ErrorScreen.test.ts +3 -4
  96. package/src/plugins/seek-time/SeekTime.ts +4 -5
  97. package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -0
  98. package/src/testUtils.ts +3 -2
  99. package/temp/player.api.json +311 -159
  100. package/tsconfig.tsbuildinfo +1 -1
  101. package/docs/api/player.clapprstats.setupdatemetrics.md +0 -56
  102. package/docs/api/player.clipsplugin.gettext.md +0 -58
  103. package/docs/api/player.clipsplugin.md +0 -59
  104. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +0 -435
@@ -1,24 +1,28 @@
1
1
  import { Container, ContainerPlugin } from '@clappr/core';
2
- import type { Metrics, MetricsUpdateFn } from './types.js';
2
+ import type { Metrics } from './types.js';
3
+ export type ClapprStatsSettings = {
4
+ /**
5
+ * The interval in milliseconds of periodic measurements.
6
+ * The plugin will emit a {@link ClapprStatsEvents.REPORT} event with the collected metrics at the specified interval.
7
+ */
8
+ runEach?: number;
9
+ };
3
10
  /**
4
- * `PLUGIN` that collects useful statistics about playback performance.
11
+ * `PLUGIN` that measures data about playback, which can be useful for analyzing performance and UX.
5
12
  * @beta
6
13
  * @remarks
7
14
  * This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
15
+ *
16
+ * Configuration options - {@link ClapprStatsSettings}
17
+ *
18
+ * Events - {@link ClapprStatsEvents}
8
19
  */
9
20
  export declare class ClapprStats extends ContainerPlugin {
10
- private bwMeasureCount;
11
- private intervalId;
21
+ private timerId;
12
22
  private lastDecodedFramesCount;
13
23
  private metrics;
14
- private completion;
15
- private _onReport;
16
- private runBandwidthTestEvery;
17
- private runEach;
18
24
  private timers;
19
- private updateFn;
20
- private urisToMeasureBandwidth;
21
- private uriToMeasureLatency;
25
+ private runEach;
22
26
  /**
23
27
  * @internal
24
28
  */
@@ -29,18 +33,12 @@ export declare class ClapprStats extends ContainerPlugin {
29
33
  get supportedVersion(): {
30
34
  min: string;
31
35
  };
32
- private get _playbackName();
33
- private get _playbackType();
34
- private _now;
35
- private _inc;
36
+ private get playbackName();
37
+ private get playbackType();
38
+ private now;
39
+ private inc;
36
40
  private start;
37
- private _stop;
38
- /**
39
- * Registers a callback to receive the metrics.
40
- * @param updateMetricsFn - The callback to receive the metrics
41
- */
42
- setUpdateMetrics(updateMetricsFn: MetricsUpdateFn): void;
43
- private _defaultReport;
41
+ private stop;
44
42
  constructor(container: Container);
45
43
  /**
46
44
  * @internal
@@ -52,7 +50,7 @@ export declare class ClapprStats extends ContainerPlugin {
52
50
  destroy(): void;
53
51
  /**
54
52
  * Returns the collected metrics.
55
- * @returns Currently collected metrics
53
+ * @returns Measurements collected so far
56
54
  */
57
55
  exportMetrics(): Metrics;
58
56
  private onBitrate;
@@ -68,14 +66,11 @@ export declare class ClapprStats extends ContainerPlugin {
68
66
  private onBuffering;
69
67
  private onBufferfull;
70
68
  private onProgress;
71
- private _newMetrics;
72
- private _onCompletion;
73
- private _buildReport;
74
- private _fetchFPS;
75
- private _calculateBitrates;
76
- private _calculatePercentages;
77
- private _html5FetchFPS;
78
- private _measureLatency;
79
- private _measureBandwidth;
69
+ private onCompletion;
70
+ private buildReport;
71
+ private fetchFPS;
72
+ private calcBitrates;
73
+ private calcBufferingPercentage;
74
+ private html5FetchFPS;
80
75
  }
81
76
  //# sourceMappingURL=ClapprStats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClapprStats.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-stats/ClapprStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAA6B,MAAM,cAAc,CAAC;AAMrF,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAkB3D;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,eAAe;IAC9C,OAAO,CAAC,cAAc,CAAK;IAE3B,OAAO,CAAC,UAAU,CAAwB;IAE1C,OAAO,CAAC,sBAAsB,CAAK;IAEnC,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,UAAU,CAGhB;IAEF,OAAO,CAAC,SAAS,CAA6B;IAE9C,OAAO,CAAC,qBAAqB,CAAS;IAEtC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,MAAM,CAOZ;IAEF,OAAO,CAAC,QAAQ,CAAkC;IAElD,OAAO,CAAC,sBAAsB,CAA0B;IAExD,OAAO,CAAC,mBAAmB,CAAqB;IAEhD;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,KAAK;IAKb;;;OAGG;IACH,gBAAgB,CAAC,eAAe,EAAE,eAAe;IAKjD,OAAO,CAAC,cAAc;gBAIV,SAAS,EAAE,SAAS;IAchC;;OAEG;IACM,UAAU;IAmBnB;;OAEG;IACM,OAAO;IAKhB;;;OAGG;IACH,aAAa;IAIb,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,iBAAiB;CAmD1B"}
1
+ {"version":3,"file":"ClapprStats.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-stats/ClapprStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAwB,MAAM,cAAc,CAAA;AAU/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAIzC,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;GASG;AACH,qBAAa,WAAY,SAAQ,eAAe;IAC9C,OAAO,CAAC,OAAO,CAAuB;IAEtC,OAAO,CAAC,sBAAsB,CAAI;IAElC,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,MAAM,CAMb;IAED,OAAO,CAAC,OAAO,CAAQ;IAEvB;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,CAAC,GAAG;IASX,OAAO,CAAC,GAAG;IAQX,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,IAAI;gBAKA,SAAS,EAAE,SAAS;IAKhC;;OAEG;IACM,UAAU;IAmDnB;;OAEG;IACM,OAAO;IAKhB;;;OAGG;IACH,aAAa;IAIb,OAAO,CAAC,SAAS;IAkBjB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,aAAa;CA0BtB"}
@@ -1,36 +1,29 @@
1
- import { ContainerPlugin, Events as CoreEvents, Log } from '@clappr/core';
2
- import assert from 'assert';
1
+ import { ContainerPlugin, Events as CoreEvents } from '@clappr/core';
3
2
  import { CLAPPR_VERSION } from '../../build.js';
4
- import { ClapprStatsEvents } from './types.js';
3
+ import { ClapprStatsEvents, Chronograph, Counter } from './types.js';
5
4
  import { newMetrics } from './utils.js';
6
- // TODO: fix
7
- const updateMetrics = () => { };
8
5
  /**
9
- * `PLUGIN` that collects useful statistics about playback performance.
6
+ * `PLUGIN` that measures data about playback, which can be useful for analyzing performance and UX.
10
7
  * @beta
11
8
  * @remarks
12
9
  * This plugin does not render anything and is supposed to be extended or used together with other plugins that actually render something.
10
+ *
11
+ * Configuration options - {@link ClapprStatsSettings}
12
+ *
13
+ * Events - {@link ClapprStatsEvents}
13
14
  */
14
15
  export class ClapprStats extends ContainerPlugin {
15
- bwMeasureCount = 0;
16
- intervalId = null;
16
+ timerId = null;
17
17
  lastDecodedFramesCount = 0;
18
18
  metrics = newMetrics();
19
- completion;
20
- _onReport;
21
- runBandwidthTestEvery;
22
- runEach;
23
19
  timers = {
24
- startup: 0,
25
- watch: 0,
26
- pause: 0,
27
- buffering: 0,
28
- session: 0,
29
- latency: 0,
20
+ [Chronograph.Startup]: 0,
21
+ [Chronograph.Watch]: 0,
22
+ [Chronograph.Pause]: 0,
23
+ [Chronograph.Buffering]: 0,
24
+ [Chronograph.Session]: 0,
30
25
  };
31
- updateFn = updateMetrics;
32
- urisToMeasureBandwidth;
33
- uriToMeasureLatency;
26
+ runEach;
34
27
  /**
35
28
  * @internal
36
29
  */
@@ -43,17 +36,19 @@ export class ClapprStats extends ContainerPlugin {
43
36
  get supportedVersion() {
44
37
  return { min: CLAPPR_VERSION };
45
38
  }
46
- get _playbackName() {
39
+ get playbackName() {
47
40
  return String(this.container.playback.name || '');
48
41
  }
49
- get _playbackType() {
42
+ get playbackType() {
50
43
  return this.container.getPlaybackType();
51
44
  }
52
- _now() {
53
- const hasPerformanceSupport = window.performance && typeof (window.performance.now) === 'function';
54
- return (hasPerformanceSupport) ? window.performance.now() : new Date().getTime();
45
+ now() {
46
+ const hasPerformanceSupport = window.performance && typeof window.performance.now === 'function';
47
+ return hasPerformanceSupport
48
+ ? window.performance.now()
49
+ : new Date().getTime();
55
50
  }
56
- _inc(counter) {
51
+ inc(counter) {
57
52
  this.metrics.counters[counter] += 1;
58
53
  }
59
54
  // _timerHasStarted(timer) {
@@ -61,34 +56,15 @@ export class ClapprStats extends ContainerPlugin {
61
56
  // }
62
57
  start(timer) {
63
58
  // this[`_start${timer}`] = this._now();
64
- this.timers[timer] = this._now();
59
+ this.timers[timer] = this.now();
65
60
  }
66
- _stop(timer) {
61
+ stop(timer) {
67
62
  // this._metrics.timers[timer] += this._now() - this[`_start${timer}`];
68
- this.metrics.timers[timer] += this._now() - this.timers[timer];
69
- }
70
- /**
71
- * Registers a callback to receive the metrics.
72
- * @param updateMetricsFn - The callback to receive the metrics
73
- */
74
- setUpdateMetrics(updateMetricsFn) {
75
- // TODO use events instead
76
- this.updateFn = updateMetricsFn;
77
- }
78
- _defaultReport(metrics) {
79
- this.updateFn(metrics);
63
+ this.metrics.chrono[timer] += this.now() - this.timers[timer];
80
64
  }
81
65
  constructor(container) {
82
66
  super(container);
83
67
  this.runEach = container.options.clapprStats?.runEach ?? 5000;
84
- this._onReport = container.options.clapprStats?.onReport ?? this._defaultReport;
85
- this.uriToMeasureLatency = container.options.clapprStats?.uriToMeasureLatency;
86
- this.urisToMeasureBandwidth = container.options.clapprStats?.urisToMeasureBandwidth;
87
- this.runBandwidthTestEvery = container.options.clapprStats?.runBandwidthTestEvery ?? 10;
88
- this.completion = {
89
- watch: container.options.clapprStats?.onCompletion ?? [],
90
- calls: []
91
- };
92
68
  }
93
69
  /**
94
70
  * @internal
@@ -103,10 +79,10 @@ export class ClapprStats extends ContainerPlugin {
103
79
  this.listenTo(this.container, CoreEvents.CONTAINER_PAUSE, this.onPause);
104
80
  this.listenToOnce(this.container, CoreEvents.CONTAINER_STATE_BUFFERING, this.onBuffering);
105
81
  this.listenTo(this.container, CoreEvents.CONTAINER_SEEK, this.onSeek);
106
- this.listenTo(this.container, CoreEvents.CONTAINER_ERROR, () => this._inc('error'));
107
- this.listenTo(this.container, CoreEvents.CONTAINER_FULLSCREEN, () => this._inc('fullscreen'));
82
+ this.listenTo(this.container, CoreEvents.CONTAINER_ERROR, () => this.inc(Counter.Error));
83
+ this.listenTo(this.container, CoreEvents.CONTAINER_FULLSCREEN, () => this.inc(Counter.Fullscreen));
108
84
  this.listenTo(this.container, CoreEvents.CONTAINER_PLAYBACKDVRSTATECHANGED, (dvrInUse) => {
109
- dvrInUse && this._inc('dvrUsage');
85
+ dvrInUse && this.inc(Counter.DvrUsage);
110
86
  });
111
87
  this.listenTo(this.container.playback, CoreEvents.PLAYBACK_PROGRESS, this.onProgress);
112
88
  this.listenTo(this.container.playback, CoreEvents.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
@@ -120,67 +96,63 @@ export class ClapprStats extends ContainerPlugin {
120
96
  }
121
97
  /**
122
98
  * Returns the collected metrics.
123
- * @returns Currently collected metrics
99
+ * @returns Measurements collected so far
124
100
  */
125
101
  exportMetrics() {
126
102
  return structuredClone(this.metrics);
127
103
  }
128
104
  onBitrate(newBitrate) {
129
105
  const bitrate = newBitrate.bitrate;
130
- const now = this._now();
106
+ const now = this.now();
131
107
  if (this.metrics.extra.bitratesHistory.length > 0) {
132
- const beforeLast = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
133
- beforeLast.end = now;
134
- beforeLast.time = now - beforeLast.start;
108
+ const last = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
109
+ last.end = now;
110
+ last.time = now - last.start;
135
111
  }
136
- this.metrics.extra.bitratesHistory.push({ start: this._now(), bitrate: bitrate });
137
- this._inc('changeLevel');
112
+ this.metrics.extra.bitratesHistory.push({ start: this.now(), bitrate });
113
+ this.inc(Counter.ChangeLevel);
138
114
  }
139
115
  stopReporting() {
140
- this._buildReport();
141
- if (this.intervalId !== null) {
142
- clearInterval(this.intervalId);
143
- this.intervalId = null;
116
+ this.buildReport();
117
+ if (this.timerId !== null) {
118
+ clearInterval(this.timerId);
119
+ this.timerId = null;
144
120
  }
145
- this._newMetrics();
146
- // TODO
147
- // @ts-ignore
148
- this.stopListening();
149
- this.bindEvents();
150
121
  }
151
122
  startTimers() {
152
- this.intervalId = setInterval(this._buildReport.bind(this), this.runEach);
153
- this.start('session');
154
- this.start('startup');
123
+ this.timerId = setInterval(this.buildReport.bind(this), this.runEach);
124
+ this.start(Chronograph.Session);
125
+ this.start(Chronograph.Startup);
155
126
  }
156
127
  onFirstPlaying() {
157
128
  this.listenTo(this.container, CoreEvents.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
158
- this.start('watch');
159
- this._stop('startup');
129
+ this.start(Chronograph.Watch);
130
+ this.stop(Chronograph.Startup);
160
131
  }
161
132
  playAfterPause() {
162
133
  this.listenTo(this.container, CoreEvents.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
163
- this._stop('pause');
164
- this.start('watch');
134
+ this.stop(Chronograph.Pause);
135
+ this.start(Chronograph.Watch);
165
136
  }
166
137
  onPlay() {
167
- this._inc('play');
138
+ this.inc(Counter.Play);
168
139
  }
169
140
  onPause() {
170
- this._stop('watch');
171
- this.start('pause');
172
- this._inc('pause');
141
+ this.stop(Chronograph.Watch);
142
+ this.start(Chronograph.Pause);
143
+ this.inc(Counter.Pause);
173
144
  this.listenToOnce(this.container, CoreEvents.CONTAINER_PLAY, this.playAfterPause);
174
145
  this.stopListening(this.container, CoreEvents.CONTAINER_TIMEUPDATE, this.onContainerUpdateWhilePlaying);
175
146
  }
176
147
  onSeek(e) {
177
- this._inc('seek');
148
+ this.inc(Counter.Seek);
178
149
  this.metrics.extra.watchHistory.push([e * 1000, e * 1000]);
179
150
  }
180
151
  onTimeUpdate(e) {
181
152
  const current = e.current * 1000, total = e.total * 1000, l = this.metrics.extra.watchHistory.length;
182
153
  this.metrics.extra.duration = total;
183
154
  this.metrics.extra.currentTime = current;
155
+ // TODO what if it's a live stream?
184
156
  this.metrics.extra.watchedPercentage = (current / total) * 100;
185
157
  if (l === 0) {
186
158
  this.metrics.extra.watchHistory.push([current, current]);
@@ -191,68 +163,60 @@ export class ClapprStats extends ContainerPlugin {
191
163
  if (this.metrics.extra.bitratesHistory.length > 0) {
192
164
  const lastBitrate = this.metrics.extra.bitratesHistory[this.metrics.extra.bitratesHistory.length - 1];
193
165
  if (!lastBitrate.end) {
194
- lastBitrate.time = this._now() - lastBitrate.start;
166
+ lastBitrate.time = this.now() - lastBitrate.start;
195
167
  }
196
168
  }
197
- this._onCompletion();
169
+ this.onCompletion();
198
170
  }
199
171
  onContainerUpdateWhilePlaying() {
200
172
  if (this.container.playback.isPlaying()) {
201
- this._stop('watch');
202
- this.start('watch');
173
+ this.stop(Chronograph.Watch);
174
+ this.start(Chronograph.Watch);
203
175
  }
204
176
  }
205
177
  onBuffering() {
206
- this._inc('buffering');
207
- this.start('buffering');
178
+ this.inc(Counter.Buffering);
179
+ this.start(Chronograph.Buffering);
208
180
  this.listenToOnce(this.container, CoreEvents.CONTAINER_STATE_BUFFERFULL, this.onBufferfull);
209
181
  }
210
182
  onBufferfull() {
211
- this._stop('buffering');
183
+ this.stop(Chronograph.Buffering);
212
184
  this.listenToOnce(this.container, CoreEvents.CONTAINER_STATE_BUFFERING, this.onBuffering);
213
185
  }
214
186
  onProgress(progress) {
215
187
  this.metrics.extra.buffersize = progress.current * 1000;
216
188
  }
217
- _newMetrics() {
218
- this.metrics = newMetrics();
219
- }
220
- _onCompletion() {
221
- const currentPercentage = this.metrics.extra.watchedPercentage;
222
- const allPercentages = this.completion.watch;
223
- const isCalled = this.completion.calls.indexOf(currentPercentage) !== -1;
224
- if (allPercentages.indexOf(currentPercentage) !== -1 && !isCalled) {
225
- Log.info(this.name + ' PERCENTAGE_EVENT: ' + currentPercentage);
226
- this.completion.calls.push(currentPercentage);
227
- this.trigger(ClapprStatsEvents.PERCENTAGE_EVENT, currentPercentage);
228
- }
229
- }
230
- _buildReport() {
231
- this._stop('session');
232
- this.start('session');
233
- this.metrics.extra.playbackName = this._playbackName;
234
- this.metrics.extra.playbackType = this._playbackType;
235
- this._calculateBitrates();
236
- this._calculatePercentages();
237
- this._fetchFPS();
238
- this._measureLatency();
239
- this._measureBandwidth();
240
- this._onReport(this.metrics);
241
- this.trigger(ClapprStatsEvents.REPORT_EVENT, structuredClone(this.metrics));
242
- }
243
- _fetchFPS() {
189
+ onCompletion() {
190
+ // Decide if this is needed
191
+ // const currentPercentage = this.metrics.extra.watchedPercentage;
192
+ // this.trigger(ClapprStatsEvents.PERCENTAGE, currentPercentage);
193
+ }
194
+ buildReport() {
195
+ this.stop(Chronograph.Session);
196
+ this.start(Chronograph.Session);
197
+ this.metrics.extra.playbackName = this.playbackName;
198
+ this.metrics.extra.playbackType = this.playbackType;
199
+ this.calcBitrates();
200
+ this.calcBufferingPercentage();
201
+ // TODO calc FPS properly, e.g., on TIMEUPDATE event
202
+ this.fetchFPS();
203
+ this.trigger(ClapprStatsEvents.REPORT, structuredClone(this.metrics));
204
+ }
205
+ fetchFPS() {
206
+ // TODO check if the playback and media sources support video, then use the common method
244
207
  // flashls ??? - hls.droppedFramesl hls.stream.bufferLength (seconds)
245
208
  // hls ??? (use the same?)
246
209
  const fetchFPS = {
247
- 'html5_video': this._html5FetchFPS,
248
- 'hls': this._html5FetchFPS,
249
- 'dash_shaka_playback': this._html5FetchFPS
210
+ html5_video: this.html5FetchFPS,
211
+ hls: this.html5FetchFPS,
212
+ dash: this.html5FetchFPS,
250
213
  };
251
- if (this._playbackName in fetchFPS) {
252
- fetchFPS[this._playbackName].call(this);
214
+ if (this.playbackName in fetchFPS) {
215
+ fetchFPS[this.playbackName].call(this);
253
216
  }
254
217
  }
255
- _calculateBitrates() {
218
+ // TODO sort out
219
+ calcBitrates() {
256
220
  const { bitratesHistory } = this.metrics.extra;
257
221
  if (bitratesHistory.length === 0) {
258
222
  return;
@@ -266,95 +230,23 @@ export class ClapprStats extends ContainerPlugin {
266
230
  this.metrics.extra.bitrateWeightedMean = weightedTotal / totalTime;
267
231
  this.metrics.extra.bitrateMostUsed = bitratesHistory.reduce((mostUsed, current) => (current.time || 0) > (mostUsed.time || 0) ? current : mostUsed, { time: 0, bitrate: 0, start: 0, end: 0 }).bitrate;
268
232
  }
269
- _calculatePercentages() {
233
+ calcBufferingPercentage() {
270
234
  if (this.metrics.extra.duration > 0) {
271
- this.metrics.extra.bufferingPercentage = (this.metrics.timers.buffering / this.metrics.extra.duration) * 100;
235
+ this.metrics.extra.bufferingPercentage =
236
+ (this.metrics.chrono.buffering / this.metrics.extra.duration) * 100;
272
237
  }
273
238
  }
274
- _html5FetchFPS() {
239
+ html5FetchFPS() {
275
240
  const videoTag = this.container.playback.el;
276
- const getFirstValidValue = (...args) => args.find(val => val !== undefined);
241
+ const getFirstValidValue = (...args) => args.find((val) => val !== undefined);
277
242
  const decodedFrames = getFirstValidValue(videoTag.webkitDecodedFrameCount, videoTag.mozDecodedFrames, 0);
278
- const droppedFrames = getFirstValidValue(videoTag.webkitDroppedFrameCount, videoTag.mozParsedFrames && videoTag.mozDecodedFrames ? videoTag.mozParsedFrames - videoTag.mozDecodedFrames : 0, 0);
279
- const decodedFramesLastTime = decodedFrames - (this.lastDecodedFramesCount || 0);
243
+ const droppedFrames = getFirstValidValue(videoTag.webkitDroppedFrameCount, videoTag.mozParsedFrames && videoTag.mozDecodedFrames
244
+ ? videoTag.mozParsedFrames - videoTag.mozDecodedFrames
245
+ : 0, 0);
246
+ const delta = decodedFrames - (this.lastDecodedFramesCount || 0);
280
247
  this.metrics.counters.decodedFrames = decodedFrames;
281
248
  this.metrics.counters.droppedFrames = droppedFrames;
282
- this.metrics.counters.fps = decodedFramesLastTime / (this.runEach / 1000);
249
+ this.metrics.counters.fps = delta / (this.runEach / 1000); // TODO use time delta instead of runEach
283
250
  this.lastDecodedFramesCount = decodedFrames;
284
251
  }
285
- // originally from https://www.smashingmagazine.com/2011/11/analyzing-network-characteristics-using-javascript-and-the-dom-part-1/
286
- _measureLatency() {
287
- if (this.uriToMeasureLatency) {
288
- const t = [];
289
- const n = 2;
290
- let rtt;
291
- const ld = () => {
292
- t.push(this._now());
293
- if (t.length > n) {
294
- done();
295
- }
296
- else {
297
- const img = new Image;
298
- img.onload = ld;
299
- img.src = this.uriToMeasureLatency + '?' + Math.random()
300
- + '=' + this._now();
301
- }
302
- };
303
- const done = () => {
304
- rtt = t[2] - t[1];
305
- this.metrics.timers.latency = rtt;
306
- };
307
- ld();
308
- }
309
- }
310
- // originally from https://www.smashingmagazine.com/2011/11/analyzing-network-characteristics-using-javascript-and-the-dom-part-1/
311
- _measureBandwidth() {
312
- if (this.urisToMeasureBandwidth && (this.bwMeasureCount % this.runBandwidthTestEvery === 0)) {
313
- let i = 0;
314
- const ld = (e) => {
315
- if (i > 0) {
316
- const prev = this.urisToMeasureBandwidth[i - 1];
317
- prev.end = this._now();
318
- if (prev.timer !== null) {
319
- clearTimeout(prev.timer);
320
- }
321
- }
322
- if (i >= this.urisToMeasureBandwidth.length || (i > 0 && this.urisToMeasureBandwidth[i - 1].expired)) {
323
- assert(e, 'incorrect invocation in _measureBandwidth');
324
- done(e);
325
- }
326
- else {
327
- const xhr = new XMLHttpRequest();
328
- xhr.open('GET', this.urisToMeasureBandwidth[i].url, true);
329
- xhr.responseType = 'arraybuffer';
330
- xhr.onload = xhr.onabort = ld;
331
- this.urisToMeasureBandwidth[i].start = this._now();
332
- this.urisToMeasureBandwidth[i].timer = setTimeout((j) => {
333
- this.urisToMeasureBandwidth[j].expired = true;
334
- xhr.abort();
335
- }, this.urisToMeasureBandwidth[i].timeout, i);
336
- xhr.send();
337
- }
338
- i++;
339
- };
340
- const done = (e) => {
341
- const timeSpent = (this.urisToMeasureBandwidth[i - 1].end - this.urisToMeasureBandwidth[i - 1].start) / 1000;
342
- const bandwidthBps = (e.loaded * 8) / timeSpent;
343
- this.metrics.extra.bandwidth = bandwidthBps;
344
- this.urisToMeasureBandwidth.forEach((x) => {
345
- x.start = 0;
346
- x.end = 0;
347
- x.expired = false;
348
- if (x.timer !== null) {
349
- clearTimeout(x.timer);
350
- x.timer = null;
351
- }
352
- });
353
- };
354
- ld();
355
- }
356
- this.bwMeasureCount++;
357
- }
358
252
  }
359
- // ClapprStats.REPORT_EVENT = 'clappr:stats:report';
360
- // ClapprStats.PERCENTAGE_EVENT = 'clappr:stats:percentage';
@@ -1,27 +1,70 @@
1
+ /**
2
+ * @beta
3
+ */
4
+ export declare enum Chronograph {
5
+ Startup = "startup",
6
+ Watch = "watch",
7
+ Pause = "pause",
8
+ Buffering = "buffering",
9
+ Session = "session"
10
+ }
11
+ /**
12
+ * @beta
13
+ */
14
+ export declare enum Counter {
15
+ Play = "play",
16
+ Pause = "pause",
17
+ Error = "error",
18
+ Buffering = "buffering",
19
+ DecodedFrames = "decodedFrames",
20
+ DroppedFrames = "droppedFrames",
21
+ Fps = "fps",
22
+ ChangeLevel = "changeLevel",
23
+ Seek = "seek",
24
+ Fullscreen = "fullscreen",
25
+ DvrUsage = "dvrUsage"
26
+ }
1
27
  /**
2
28
  * @beta
3
29
  */
4
30
  export type Metrics = {
31
+ /**
32
+ * Events count counters
33
+ */
5
34
  counters: {
6
- play: number;
7
- pause: number;
8
- error: number;
9
- buffering: number;
10
- decodedFrames: number;
11
- droppedFrames: number;
12
- fps: number;
13
- changeLevel: number;
14
- seek: number;
15
- fullscreen: number;
16
- dvrUsage: number;
35
+ /**
36
+ *
37
+ */
38
+ [Counter.Play]: number;
39
+ [Counter.Pause]: number;
40
+ [Counter.Error]: number;
41
+ [Counter.Buffering]: number;
42
+ [Counter.DecodedFrames]: number;
43
+ [Counter.DroppedFrames]: number;
44
+ [Counter.Fps]: number;
45
+ [Counter.ChangeLevel]: number;
46
+ [Counter.Seek]: number;
47
+ [Counter.Fullscreen]: number;
48
+ [Counter.DvrUsage]: number;
17
49
  };
18
- timers: {
19
- startup: number;
20
- watch: number;
21
- pause: number;
22
- buffering: number;
23
- session: number;
24
- latency: number;
50
+ /**
51
+ * Time measurements - accumulated duration of time-based activities
52
+ */
53
+ chrono: {
54
+ /**
55
+ * Time spent in the startup phase
56
+ */
57
+ [Chronograph.Startup]: number;
58
+ /**
59
+ * Total time spent in the watch phase
60
+ */
61
+ [Chronograph.Watch]: number;
62
+ /**
63
+ *
64
+ */
65
+ [Chronograph.Pause]: number;
66
+ [Chronograph.Buffering]: number;
67
+ [Chronograph.Session]: number;
25
68
  };
26
69
  extra: {
27
70
  playbackName: string;
@@ -37,7 +80,6 @@ export type Metrics = {
37
80
  duration: number;
38
81
  currentTime: number;
39
82
  };
40
- custom: Record<string, unknown>;
41
83
  };
42
84
  /**
43
85
  * @beta
@@ -48,15 +90,13 @@ export type BitrateTrackRecord = {
48
90
  time?: number;
49
91
  bitrate: number;
50
92
  };
51
- /**
52
- * @beta
53
- */
54
- export type MetricsUpdateFn = (metrics: Metrics) => void;
55
93
  /**
56
94
  * @beta
57
95
  */
58
96
  export declare enum ClapprStatsEvents {
59
- REPORT_EVENT = "clappr:stats:report",
60
- PERCENTAGE_EVENT = "clappr:stats:percentage"
97
+ /**
98
+ * Emitted periodically with current measurements.
99
+ */
100
+ REPORT = "clappr:stats:report"
61
101
  }
62
102
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-stats/types.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,kBAAkB,EAAE,CAAC;QACtC,mBAAmB,EAAE,MAAM,CAAC;QAC5B,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACtC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAEzD;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,YAAY,wBAAwB;IACpC,gBAAgB,4BAA4B;CAC7C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-stats/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,OAAO,YAAY;CAEpB;AAED;;GAEG;AACH,oBAAY,OAAO;IACjB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,SAAS,cAAc;IACvB,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,GAAG,QAAQ;IACX,WAAW,gBAAgB;IAC3B,IAAI,SAAS;IACb,UAAU,eAAe;IACzB,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB;;OAEG;IACH,QAAQ,EAAE;QACR;;WAEG;QACH,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;QACtB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QACvB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QACvB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;QAC3B,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;QAC/B,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;QAC/B,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;QACrB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;QAC7B,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;QACtB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;QAC5B,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAC3B,CAAA;IACD;;OAEG;IACH,MAAM,EAAE;QACN;;WAEG;QACH,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;QAC7B;;WAEG;QACH,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QAC3B;;WAEG;QACH,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;QAC3B,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;QAC/B,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAE9B,CAAA;IACD,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,eAAe,EAAE,kBAAkB,EAAE,CAAA;QACrC,mBAAmB,EAAE,MAAM,CAAA;QAC3B,eAAe,EAAE,MAAM,CAAA;QACvB,UAAU,EAAE,MAAM,CAAA;QAClB,YAAY,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;QACrC,iBAAiB,EAAE,MAAM,CAAA;QACzB,mBAAmB,EAAE,MAAM,CAAA;QAC3B,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAC3B;;OAEG;IACH,MAAM,wBAAwB;CAK/B"}