@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
@@ -0,0 +1,133 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
+ import { Events as CoreEvents } from '@clappr/core'
3
+ import FakeTimers from '@sinonjs/fake-timers'
4
+
5
+ import { ClapprStats } from '../ClapprStats'
6
+ import { createMockCore } from '../../../testUtils'
7
+ import { Chronograph, ClapprStatsEvents, Counter } from '../types'
8
+
9
+ describe('ClapprStats', () => {
10
+ let core: any
11
+ let stats: ClapprStats
12
+ let onReport: any
13
+ let clock: FakeTimers.InstalledClock
14
+ beforeEach(() => {
15
+ core = createMockCore()
16
+ stats = new ClapprStats(core.activeContainer)
17
+ clock = FakeTimers.install()
18
+ })
19
+ afterEach(() => {
20
+ clock.uninstall()
21
+ })
22
+ describe('time measurements', () => {
23
+ describe('startup', () => {
24
+ beforeEach(() => {
25
+ vi.spyOn(performance, 'now').mockReturnValue(100)
26
+ core.activeContainer.playback.emit(CoreEvents.PLAYBACK_PLAY_INTENT)
27
+ vi.spyOn(performance, 'now').mockReturnValue(255)
28
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
29
+ })
30
+ it('should measure', () => {
31
+ const metrics = stats.exportMetrics()
32
+ expect(metrics.chrono[Chronograph.Startup]).toBe(155)
33
+ // expect(metrics.times[Chronograph.Session]).toBe(155)
34
+ })
35
+ })
36
+ describe('watch', () => {
37
+ beforeEach(() => {
38
+ vi.spyOn(performance, 'now').mockReturnValue(100)
39
+ core.activeContainer.playback.emit(CoreEvents.PLAYBACK_PLAY_INTENT)
40
+ vi.spyOn(performance, 'now').mockReturnValue(150)
41
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
42
+ vi.spyOn(performance, 'now').mockReturnValue(3000)
43
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PAUSE)
44
+ vi.spyOn(performance, 'now').mockReturnValue(4900)
45
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
46
+ vi.spyOn(performance, 'now').mockReturnValue(5900)
47
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PAUSE)
48
+ vi.spyOn(performance, 'now').mockReturnValue(6900)
49
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
50
+ })
51
+ it('should measure cumulative play and pause durations', () => {
52
+ const metrics = stats.exportMetrics()
53
+ expect(metrics.chrono[Chronograph.Watch]).toBe(3850)
54
+ expect(metrics.chrono[Chronograph.Pause]).toBe(2900)
55
+ })
56
+ })
57
+ describe('buffering', () => {
58
+ beforeEach(() => {
59
+ vi.spyOn(performance, 'now').mockReturnValue(100)
60
+ core.activeContainer.playback.emit(CoreEvents.PLAYBACK_PLAY_INTENT)
61
+ vi.spyOn(performance, 'now').mockReturnValue(150)
62
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
63
+ vi.spyOn(performance, 'now').mockReturnValue(250)
64
+ core.activeContainer.trigger(CoreEvents.CONTAINER_STATE_BUFFERING)
65
+ vi.spyOn(performance, 'now').mockReturnValue(350)
66
+ core.activeContainer.trigger(CoreEvents.CONTAINER_STATE_BUFFERFULL)
67
+ vi.spyOn(performance, 'now').mockReturnValue(450)
68
+ core.activeContainer.trigger(CoreEvents.CONTAINER_STATE_BUFFERING)
69
+ vi.spyOn(performance, 'now').mockReturnValue(550)
70
+ core.activeContainer.trigger(CoreEvents.CONTAINER_STATE_BUFFERFULL)
71
+ })
72
+ it('should measure cumulative buffering durations', () => {
73
+ const metrics = stats.exportMetrics()
74
+ expect(metrics.chrono[Chronograph.Buffering]).toBe(200)
75
+ })
76
+ })
77
+ describe('session', () => {
78
+ beforeEach(() => {
79
+ onReport = vi.fn()
80
+ stats.on(ClapprStatsEvents.REPORT, onReport, null)
81
+ vi.spyOn(performance, 'now').mockReturnValue(100)
82
+ core.activeContainer.playback.emit(CoreEvents.PLAYBACK_PLAY_INTENT)
83
+ vi.spyOn(performance, 'now').mockReturnValue(200)
84
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
85
+ vi.spyOn(performance, 'now').mockReturnValue(60300)
86
+ core.activeContainer.trigger(CoreEvents.CONTAINER_STOP)
87
+ })
88
+ it('should measure', () => {
89
+ expect(onReport).toHaveBeenCalledWith(expect.objectContaining({
90
+ chrono: expect.objectContaining({
91
+ [Chronograph.Session]: 60200,
92
+ }),
93
+ }))
94
+ })
95
+ })
96
+ })
97
+ describe('fps measurements', () => {
98
+ beforeEach(async () => {
99
+ onReport = vi.fn()
100
+ core.activePlayback.name = 'html5_video'
101
+ stats.on(ClapprStatsEvents.REPORT, onReport, null)
102
+ vi.spyOn(performance, 'now').mockReturnValue(100)
103
+ core.activeContainer.playback.emit(CoreEvents.PLAYBACK_PLAY_INTENT)
104
+ vi.spyOn(performance, 'now').mockReturnValue(200)
105
+ vi.spyOn(performance, 'now').mockReturnValue(200)
106
+ core.activeContainer.trigger(CoreEvents.CONTAINER_PLAY)
107
+ core.activeContainer.playback.el.webkitDecodedFrameCount = 126
108
+ core.activeContainer.playback.el.webkitDroppedFrameCount = 3
109
+ vi.spyOn(performance, 'now').mockReturnValue(5225)
110
+ await clock.tickAsync(5000)
111
+ core.activeContainer.playback.el.webkitDecodedFrameCount = 275
112
+ core.activeContainer.playback.el.webkitDroppedFrameCount = 4
113
+ vi.spyOn(performance, 'now').mockReturnValue(10225)
114
+ core.activeContainer.trigger(CoreEvents.CONTAINER_STOP)
115
+ })
116
+ it('should measure fps', () => {
117
+ expect(onReport).toHaveBeenNthCalledWith(1, expect.objectContaining({
118
+ counters: expect.objectContaining({
119
+ [Counter.DecodedFrames]: 126,
120
+ [Counter.DroppedFrames]: 3,
121
+ [Counter.Fps]: expect.closeTo(25, 0),
122
+ }),
123
+ }))
124
+ expect(onReport).toHaveBeenNthCalledWith(2, expect.objectContaining({
125
+ counters: expect.objectContaining({
126
+ [Counter.DecodedFrames]: 275,
127
+ [Counter.DroppedFrames]: 4,
128
+ [Counter.Fps]: expect.closeTo(30, 0),
129
+ }),
130
+ }))
131
+ })
132
+ })
133
+ })
@@ -1,65 +1,111 @@
1
+ /**
2
+ * @beta
3
+ */
4
+ export enum Chronograph {
5
+ Startup = 'startup',
6
+ Watch = 'watch',
7
+ Pause = 'pause',
8
+ Buffering = 'buffering',
9
+ Session = 'session',
10
+ // Latency = 'latency',
11
+ }
1
12
 
2
13
  /**
3
14
  * @beta
4
15
  */
5
- export type Metrics = {
6
- counters: {
7
- play: number;
8
- pause: number;
9
- error: number;
10
- buffering: number;
11
- decodedFrames: number;
12
- droppedFrames: number;
13
- fps: number;
14
- changeLevel: number;
15
- seek: number;
16
- fullscreen: number;
17
- dvrUsage: number;
18
- };
19
- timers: {
20
- startup: number;
21
- watch: number;
22
- pause: number;
23
- buffering: number;
24
- session: number;
25
- latency: number;
26
- };
27
- extra: {
28
- playbackName: string;
29
- playbackType: string;
30
- bitratesHistory: BitrateTrackRecord[];
31
- bitrateWeightedMean: number;
32
- bitrateMostUsed: number;
33
- buffersize: number;
34
- watchHistory: Array<[number, number]>;
35
- watchedPercentage: number;
36
- bufferingPercentage: number;
37
- bandwidth: number;
38
- duration: number;
39
- currentTime: number;
40
- };
41
- custom: Record<string, unknown>;
42
- };
16
+ export enum Counter {
17
+ Play = 'play',
18
+ Pause = 'pause',
19
+ Error = 'error',
20
+ Buffering = 'buffering',
21
+ DecodedFrames = 'decodedFrames',
22
+ DroppedFrames = 'droppedFrames',
23
+ Fps = 'fps',
24
+ ChangeLevel = 'changeLevel',
25
+ Seek = 'seek',
26
+ Fullscreen = 'fullscreen',
27
+ DvrUsage = 'dvrUsage',
28
+ }
43
29
 
44
30
  /**
45
31
  * @beta
46
32
  */
47
- export type BitrateTrackRecord = {
48
- start: number;
49
- end?: number;
50
- time?: number;
51
- bitrate: number;
33
+ export type Metrics = {
34
+ /**
35
+ * Events count counters
36
+ */
37
+ counters: {
38
+ /**
39
+ *
40
+ */
41
+ [Counter.Play]: number
42
+ [Counter.Pause]: number
43
+ [Counter.Error]: number
44
+ [Counter.Buffering]: number
45
+ [Counter.DecodedFrames]: number
46
+ [Counter.DroppedFrames]: number
47
+ [Counter.Fps]: number
48
+ [Counter.ChangeLevel]: number
49
+ [Counter.Seek]: number
50
+ [Counter.Fullscreen]: number
51
+ [Counter.DvrUsage]: number
52
+ }
53
+ /**
54
+ * Time measurements - accumulated duration of time-based activities
55
+ */
56
+ chrono: {
57
+ /**
58
+ * Time spent in the startup phase
59
+ */
60
+ [Chronograph.Startup]: number
61
+ /**
62
+ * Total time spent in the watch phase
63
+ */
64
+ [Chronograph.Watch]: number
65
+ /**
66
+ *
67
+ */
68
+ [Chronograph.Pause]: number
69
+ [Chronograph.Buffering]: number
70
+ [Chronograph.Session]: number
71
+ // [Chronograph.Latency]: number;
72
+ }
73
+ extra: {
74
+ playbackName: string
75
+ playbackType: string
76
+ bitratesHistory: BitrateTrackRecord[]
77
+ bitrateWeightedMean: number
78
+ bitrateMostUsed: number
79
+ buffersize: number
80
+ watchHistory: Array<[number, number]>
81
+ watchedPercentage: number
82
+ bufferingPercentage: number
83
+ bandwidth: number
84
+ duration: number
85
+ currentTime: number
86
+ }
52
87
  }
53
88
 
54
89
  /**
55
90
  * @beta
56
91
  */
57
- export type MetricsUpdateFn = (metrics: Metrics) => void;
92
+ export type BitrateTrackRecord = {
93
+ start: number
94
+ end?: number
95
+ time?: number
96
+ bitrate: number
97
+ }
58
98
 
59
99
  /**
60
100
  * @beta
61
101
  */
62
102
  export enum ClapprStatsEvents {
63
- REPORT_EVENT = 'clappr:stats:report',
64
- PERCENTAGE_EVENT = 'clappr:stats:percentage',
65
- }
103
+ /**
104
+ * Emitted periodically with current measurements.
105
+ */
106
+ REPORT = 'clappr:stats:report',
107
+ /**
108
+ * Emitted when the playback reaches a certain percentage of the total duration.
109
+ */
110
+ // PERCENTAGE = 'clappr:stats:percentage',
111
+ }
@@ -1,4 +1,4 @@
1
- import type { Metrics } from "./types";
1
+ import type { Metrics } from './types'
2
2
 
3
3
  export function newMetrics(): Metrics {
4
4
  return {
@@ -15,13 +15,12 @@ export function newMetrics(): Metrics {
15
15
  fullscreen: 0,
16
16
  dvrUsage: 0,
17
17
  },
18
- timers: {
18
+ chrono: {
19
19
  startup: 0,
20
20
  watch: 0,
21
21
  pause: 0,
22
22
  buffering: 0,
23
23
  session: 0,
24
- latency: 0,
25
24
  },
26
25
  extra: {
27
26
  playbackName: '',
@@ -37,6 +36,5 @@ export function newMetrics(): Metrics {
37
36
  duration: 0,
38
37
  currentTime: 0,
39
38
  },
40
- custom: {},
41
- };
42
- }
39
+ }
40
+ }
@@ -1,4 +1,4 @@
1
- import { createMockContainer, createMockCore, createMockPlayback } from '../../../testUtils'
1
+ import { createMockCore } from '../../../testUtils'
2
2
  import { ErrorScreen } from '../ErrorScreen'
3
3
  import { beforeEach, describe, expect, it, vi } from 'vitest'
4
4
 
@@ -9,9 +9,8 @@ describe('ErrorScreen', () => {
9
9
  let errorScreen: ErrorScreen
10
10
  beforeEach(() => {
11
11
  core = createMockCore()
12
- container = createMockContainer()
13
- playback = createMockPlayback()
14
- container.playback = playback
12
+ container = core.activeContainer
13
+ playback = container.playback
15
14
  core.activeContainer = container
16
15
  })
17
16
  describe('on error', () => {
@@ -3,7 +3,7 @@
3
3
  // license that can be found at https://github.com/clappr/clappr-plugins/blob/master/LICENSE
4
4
 
5
5
  import { Events, Playback, UICorePlugin, Utils, template } from '@clappr/core';
6
- import { TimeUpdate } from '../../playback.types.js';
6
+ import { TimePosition } from '../../playback.types.js';
7
7
 
8
8
  import { CLAPPR_VERSION } from '../../build.js';
9
9
 
@@ -79,7 +79,7 @@ export class SeekTime extends UICorePlugin {
79
79
  this.listenTo(this.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED, this.onContainerChanged);
80
80
  if (this.mediaControlContainer) {
81
81
  this.listenTo(this.mediaControlContainer, Events.CONTAINER_PLAYBACKDVRSTATECHANGED, this.update);
82
- this.listenTo(this.mediaControlContainer, Events.CONTAINER_TIMEUPDATE, this.updateDuration);
82
+ this.listenTo(this.mediaControlContainer, Events.CONTAINER_TIMEUPDATE, this.onTimeUpdate);
83
83
  }
84
84
  }
85
85
 
@@ -89,9 +89,8 @@ export class SeekTime extends UICorePlugin {
89
89
  this.bindEvents();
90
90
  }
91
91
 
92
- private updateDuration(timeProgress: TimeUpdate) {
93
- this.duration = timeProgress.total;
94
- // this.firstFragDateTime = timeProgress.firstFragDateTime;
92
+ private onTimeUpdate({ total }: TimePosition) {
93
+ this.duration = total;
95
94
  this.update();
96
95
  }
97
96
 
@@ -1,4 +1,5 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+
2
3
  import { ClosedCaptions } from '../ClosedCaptions.js'
3
4
  import { createMockCore, createMockMediaControl } from '../../../testUtils.js';
4
5
 
package/src/testUtils.ts CHANGED
@@ -84,7 +84,7 @@ export class _MockPlayback extends Events {
84
84
 
85
85
  export function createMockCore(
86
86
  options: Record<string, unknown> = {},
87
- container: any = createMockContainer(),
87
+ container: any = createMockContainer(options),
88
88
  ) {
89
89
  const el = document.createElement('div')
90
90
  const emitter = new Events()
@@ -157,12 +157,13 @@ export function createMockPlayback(name = 'mock') {
157
157
  })
158
158
  }
159
159
 
160
- export function createMockContainer(playback: any = createMockPlayback()) {
160
+ export function createMockContainer(options: Record<string, unknown> = {}, playback: any = createMockPlayback()) {
161
161
  const el = playback.el
162
162
  const emitter = new Events()
163
163
  return Object.assign(emitter, {
164
164
  el,
165
165
  playback,
166
+ options,
166
167
  $el: $(el),
167
168
  getDuration: vi.fn().mockReturnValue(0),
168
169
  getPlugin: vi.fn(),