@gcorevideo/player 2.19.15 → 2.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/assets/level-selector/list.ejs +1 -1
  2. package/dist/core.js +2 -2
  3. package/dist/index.css +1634 -1634
  4. package/dist/index.js +585 -416
  5. package/dist/player.d.ts +268 -72
  6. package/dist/plugins/index.css +1567 -1567
  7. package/dist/plugins/index.js +526 -357
  8. package/docs/api/player.clapprnerdstats.md +12 -259
  9. package/docs/api/player.dvrcontrols.md +5 -1
  10. package/docs/api/player.errorscreen.attributes.md +3 -0
  11. package/docs/api/player.errorscreen.bindevents.md +3 -0
  12. package/docs/api/player.errorscreen.container.md +3 -0
  13. package/docs/api/player.errorscreen.hide.md +3 -0
  14. package/docs/api/player.errorscreen.md +27 -0
  15. package/docs/api/player.errorscreen.name.md +3 -0
  16. package/docs/api/player.errorscreen.render.md +3 -0
  17. package/docs/api/player.errorscreen.show.md +3 -0
  18. package/docs/api/player.errorscreen.supportedversion.md +3 -0
  19. package/docs/api/player.errorscreen.template.md +3 -0
  20. package/docs/api/player.errorscreen.unbindevents.md +3 -0
  21. package/docs/api/{player.playbackrate.template.md → player.initeventdata.event.md} +3 -3
  22. package/docs/api/{player.playbackrate.updateplaybackrate.md → player.initeventdata.md} +15 -11
  23. package/docs/api/player.md +88 -5
  24. package/docs/api/player.pictureinpicture.md +9 -197
  25. package/docs/api/player.playbackrate.md +10 -314
  26. package/docs/api/{player.playbackrate.onplay.md → player.stalleventdata.count.md} +5 -7
  27. package/docs/api/{player.playbackrate.name.md → player.stalleventdata.event.md} +3 -3
  28. package/docs/api/player.stalleventdata.md +112 -0
  29. package/docs/api/player.stalleventdata.time.md +13 -0
  30. package/docs/api/player.stalleventdata.total_ms.md +13 -0
  31. package/docs/api/{player.pluginsettings.md → player.starteventdata.event.md} +3 -5
  32. package/docs/api/{player.playbackrate.onrateselect.md → player.starteventdata.md} +15 -11
  33. package/docs/api/{player.statistics._constructor_.md → player.telemetry._constructor_.md} +6 -3
  34. package/docs/api/player.telemetry.md +146 -0
  35. package/docs/api/{player.volumefade.name.md → player.telemetry.name.md} +4 -2
  36. package/docs/api/{player.clapprnerdstats.supportedversion.md → player.telemetry.supportedversion.md} +4 -2
  37. package/docs/api/player.telemetryevent.md +89 -0
  38. package/docs/api/player.telemetryeventdata.md +15 -0
  39. package/docs/api/player.telemetrypluginsettings.md +57 -0
  40. package/docs/api/player.telemetrypluginsettings.send.md +13 -0
  41. package/docs/api/player.telemetryrecord.md +17 -0
  42. package/docs/api/player.volumefade.md +0 -93
  43. package/docs/api/{player.pictureinpicture.name.md → player.watcheventdata.event.md} +3 -3
  44. package/docs/api/{player.playbackrate.setselectedrate.md → player.watcheventdata.md} +15 -11
  45. package/lib/index.plugins.d.ts +2 -2
  46. package/lib/index.plugins.d.ts.map +1 -1
  47. package/lib/index.plugins.js +2 -2
  48. package/lib/playback/hls-playback/HlsPlayback.js +1 -1
  49. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +38 -5
  50. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  51. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +63 -17
  52. package/lib/plugins/dvr-controls/DvrControls.d.ts +5 -2
  53. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  54. package/lib/plugins/dvr-controls/DvrControls.js +5 -2
  55. package/lib/plugins/error-screen/ErrorScreen.d.ts +5 -0
  56. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
  57. package/lib/plugins/error-screen/ErrorScreen.js +5 -0
  58. package/lib/plugins/index.d.ts +2 -3
  59. package/lib/plugins/index.d.ts.map +1 -1
  60. package/lib/plugins/index.js +2 -3
  61. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +32 -4
  62. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
  63. package/lib/plugins/picture-in-picture/PictureInPicture.js +30 -2
  64. package/lib/plugins/playback-rate/PlaybackRate.d.ts +47 -14
  65. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  66. package/lib/plugins/playback-rate/PlaybackRate.js +38 -9
  67. package/lib/plugins/statistics/Statistics.d.ts +38 -3
  68. package/lib/plugins/statistics/Statistics.d.ts.map +1 -1
  69. package/lib/plugins/statistics/Statistics.js +51 -9
  70. package/lib/plugins/telemetry/Telemetry.d.ts +135 -0
  71. package/lib/plugins/telemetry/Telemetry.d.ts.map +1 -0
  72. package/lib/plugins/telemetry/Telemetry.js +180 -0
  73. package/lib/plugins/volume-fade/VolumeFade.d.ts +7 -1
  74. package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -1
  75. package/lib/plugins/volume-fade/VolumeFade.js +8 -1
  76. package/package.json +1 -1
  77. package/src/index.plugins.ts +2 -2
  78. package/src/playback/hls-playback/HlsPlayback.ts +1 -1
  79. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +240 -173
  80. package/src/plugins/dvr-controls/DvrControls.ts +5 -2
  81. package/src/plugins/error-screen/ErrorScreen.ts +5 -0
  82. package/src/plugins/index.ts +2 -3
  83. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +47 -26
  84. package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +18 -18
  85. package/src/plugins/picture-in-picture/PictureInPicture.ts +35 -7
  86. package/src/plugins/playback-rate/PlaybackRate.ts +53 -24
  87. package/src/plugins/telemetry/Telemetry.ts +299 -0
  88. package/src/plugins/volume-fade/VolumeFade.ts +9 -2
  89. package/temp/player.api.json +2322 -3281
  90. package/tsconfig.tsbuildinfo +1 -1
  91. package/docs/api/player.clapprnerdstats.attributes.md +0 -17
  92. package/docs/api/player.clapprnerdstats.bindevents.md +0 -18
  93. package/docs/api/player.clapprnerdstats.events.md +0 -18
  94. package/docs/api/player.clapprnerdstats.name.md +0 -14
  95. package/docs/api/player.clapprnerdstats.playerheight.md +0 -14
  96. package/docs/api/player.clapprnerdstats.playerwidth.md +0 -14
  97. package/docs/api/player.clapprnerdstats.render.md +0 -18
  98. package/docs/api/player.clapprnerdstats.statsboxelem.md +0 -14
  99. package/docs/api/player.clapprnerdstats.statsboxwidththreshold.md +0 -14
  100. package/docs/api/player.clapprnerdstats.template.md +0 -14
  101. package/docs/api/player.pictureinpicture.bindevents.md +0 -15
  102. package/docs/api/player.pictureinpicture.events.md +0 -13
  103. package/docs/api/player.pictureinpicture.exitpictureinpicture.md +0 -15
  104. package/docs/api/player.pictureinpicture.render.md +0 -15
  105. package/docs/api/player.pictureinpicture.requestpictureinpicture.md +0 -15
  106. package/docs/api/player.pictureinpicture.supportedversion.md +0 -13
  107. package/docs/api/player.pictureinpicture.togglepictureinpicture.md +0 -15
  108. package/docs/api/player.pictureinpicture.version.md +0 -11
  109. package/docs/api/player.pictureinpicture.videoelement.md +0 -11
  110. package/docs/api/player.playbackrate.attributes.md +0 -14
  111. package/docs/api/player.playbackrate.bindevents.md +0 -15
  112. package/docs/api/player.playbackrate.events.md +0 -15
  113. package/docs/api/player.playbackrate.gettitle.md +0 -15
  114. package/docs/api/player.playbackrate.goback.md +0 -15
  115. package/docs/api/player.playbackrate.highlightcurrentrate.md +0 -15
  116. package/docs/api/player.playbackrate.onfinishad.md +0 -15
  117. package/docs/api/player.playbackrate.onshowmenu.md +0 -15
  118. package/docs/api/player.playbackrate.onstartad.md +0 -15
  119. package/docs/api/player.playbackrate.onstop.md +0 -15
  120. package/docs/api/player.playbackrate.reload.md +0 -15
  121. package/docs/api/player.playbackrate.render.md +0 -15
  122. package/docs/api/player.playbackrate.supportedversion.md +0 -13
  123. package/docs/api/player.playbackrate.unbindevents.md +0 -15
  124. package/docs/api/player.statistics.bindevents.md +0 -15
  125. package/docs/api/player.statistics.md +0 -141
  126. package/docs/api/player.statistics.name.md +0 -11
  127. package/docs/api/player.statistics.supportedversion.md +0 -13
  128. package/docs/api/player.volumefade.bindevents.md +0 -18
  129. package/docs/api/player.volumefade.unbindevents.md +0 -18
  130. package/src/plugins/statistics/Statistics.ts +0 -207
  131. /package/src/plugins/{statistics → telemetry}/Statistics copy.xts +0 -0
@@ -0,0 +1,299 @@
1
+ // An example implementation of client side performancestatistics
2
+ import { Container, ContainerPlugin, Events } from '@clappr/core'
3
+ import { reportError, trace } from '@gcorevideo/utils'
4
+ import assert from 'assert'
5
+
6
+ import type { TimePosition, TimeValue } from '../../playback.types.js'
7
+ import type { PlaybackType } from '../../types.js'
8
+
9
+ import { CLAPPR_VERSION } from '../../build.js'
10
+
11
+ const WATCH_CUTOFF = 5
12
+
13
+ const STALL_MEASURE_PERIOD = 10
14
+
15
+ const T = 'plugins.telemetry'
16
+
17
+ /**
18
+ * Telemetry event data
19
+ */
20
+ export type TelemetryEventData = StallEventData | InitEventData | StartEventData | WatchEventData
21
+
22
+ /**
23
+ * Playback stall event data
24
+ */
25
+ export interface StallEventData {
26
+ event: TelemetryEvent.Stall
27
+ /**
28
+ * Accumulated buffering duration over the measurement interval, ms
29
+ */
30
+ total_ms: number
31
+ /**
32
+ * Number of stalls
33
+ */
34
+ count: number
35
+ /**
36
+ * Playback time when the stall is reported at the end of a stall measurement interval, s
37
+ */
38
+ time: number
39
+ }
40
+
41
+ export interface InitEventData {
42
+ event: TelemetryEvent.Init
43
+ }
44
+
45
+ export interface StartEventData {
46
+ event: TelemetryEvent.Start
47
+ }
48
+
49
+ export interface WatchEventData {
50
+ event: TelemetryEvent.Watch
51
+ }
52
+
53
+ /**
54
+ * Telemetry record
55
+ */
56
+ export type TelemetryRecord = {
57
+ type: PlaybackType
58
+ } & TelemetryEventData;
59
+
60
+ /**
61
+ * Callback to send the telemetry record to the storage.
62
+ * @param data - The telemetry record to send.
63
+ */
64
+ type TelemetrySendFn = (data: TelemetryRecord) => void
65
+
66
+ /**
67
+ * Plugin settings
68
+ */
69
+ export interface TelemetryPluginSettings {
70
+ /**
71
+ * Sends the statistics record to the storage.
72
+ * The actual delivery is presumably async and batched.
73
+ */
74
+ send: TelemetrySendFn
75
+ }
76
+
77
+ /**
78
+ * Telemetry event type
79
+ */
80
+ export enum TelemetryEvent {
81
+ Init = 1,
82
+ Start,
83
+ Watch,
84
+ Stall,
85
+ }
86
+
87
+ /**
88
+ * Collects and reports the performance statistics.
89
+ * @beta
90
+ * @remarks
91
+ * This plugin is experimental and its API is likely to change.
92
+ *
93
+ * Configuration options {@link TelemetryPluginSettings}
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * import { Statistics } from '@gcorevideo/player'
98
+ *
99
+ * Player.registerPlugin(Statistics)
100
+ *
101
+ * const player = new Player({
102
+ * statistics: {
103
+ * send: (data) => {
104
+ * fetch('/stats', {
105
+ * method: 'POST',
106
+ * body: JSON.stringify(data),
107
+ * headers: { 'content-type': 'application/json' },
108
+ * })
109
+ * },
110
+ * },
111
+ * ...
112
+ * })
113
+ * ```
114
+ */
115
+ export class Telemetry extends ContainerPlugin {
116
+ /**
117
+ * The name of the plugin.
118
+ */
119
+ get name() {
120
+ return 'telemetry'
121
+ }
122
+
123
+ /**
124
+ * The supported version of the plugin.
125
+ */
126
+ get supportedVersion() {
127
+ return { min: CLAPPR_VERSION }
128
+ }
129
+
130
+ private started = false
131
+
132
+ private timeStart = 0
133
+
134
+ private stallSent = false
135
+
136
+ private stallLastTime = 0
137
+
138
+ private watchSent = false
139
+
140
+ private bufTracking = false
141
+
142
+ private numStalls = 0
143
+
144
+ /**
145
+ * The time when buffering last started.
146
+ */
147
+ private bufLastStarted = 0
148
+
149
+ /**
150
+ * The accumulated buffering duration.
151
+ */
152
+ private stallAcc = 0
153
+
154
+ constructor(container: Container) {
155
+ super(container)
156
+
157
+ assert(
158
+ this.options.telemetry &&
159
+ typeof this.options.telemetry.send === 'function',
160
+ 'Telemetry plugin configuration is invalid: `send` option is required',
161
+ )
162
+ }
163
+
164
+ /**
165
+ * @internal
166
+ */
167
+ override bindEvents() {
168
+ // TODO remove this
169
+ // this.listenToOnce(
170
+ // this.container,
171
+ // CUSTOM_EVENTS_CONTAINER_START,
172
+ // this.onStart,
173
+ // )
174
+
175
+ this.listenToOnce(this.container, Events.CONTAINER_READY, this.onReady)
176
+ this.listenTo(
177
+ this.container,
178
+ Events.CONTAINER_STATE_BUFFERING,
179
+ this.onBuffering,
180
+ )
181
+ this.listenTo(
182
+ this.container,
183
+ Events.CONTAINER_STATE_BUFFERFULL,
184
+ this.onBufferFull,
185
+ )
186
+ this.listenTo(
187
+ this.container.playback,
188
+ Events.PLAYBACK_TIMEUPDATE,
189
+ this.onTimeUpdate,
190
+ )
191
+ this.listenTo(
192
+ this.container.playback,
193
+ Events.PLAYBACK_LEVEL_SWITCH_START,
194
+ this.startLevelSwitch,
195
+ )
196
+ this.listenTo(
197
+ this.container.playback,
198
+ Events.PLAYBACK_LEVEL_SWITCH_END,
199
+ this.endLevelSwitch,
200
+ )
201
+ }
202
+
203
+ private startLevelSwitch() {
204
+ this.bufTracking = false
205
+ }
206
+
207
+ private endLevelSwitch() {
208
+ this.bufTracking = true
209
+ }
210
+
211
+ private onBuffering() {
212
+ if (this.bufTracking) {
213
+ this.bufLastStarted = performance.now()
214
+ }
215
+ }
216
+
217
+ private onBufferFull() {
218
+ if (this.bufTracking && this.bufLastStarted) {
219
+ this.stallAcc += performance.now() - this.bufLastStarted
220
+ this.numStalls++
221
+ }
222
+ this.bufTracking = true
223
+ }
224
+
225
+ private onReady() {
226
+ this.sendInit()
227
+ trace(`${T} onReady`, {
228
+ autoPlay: this.options.autoPlay,
229
+ })
230
+ if (this.options.autoPlay) {
231
+ this.onStart()
232
+ } else {
233
+ this.listenToOnce(
234
+ this.container.playback,
235
+ Events.PLAYBACK_PLAY_INTENT,
236
+ this.onStart,
237
+ )
238
+ }
239
+ }
240
+
241
+ private sendInit() {
242
+ this.send({event: TelemetryEvent.Init})
243
+ }
244
+
245
+ private send(event: TelemetryEventData) {
246
+ (this.options.telemetry as TelemetryPluginSettings).send({
247
+ type: this.container.getPlaybackType(),
248
+ ...event,
249
+ })
250
+ }
251
+
252
+ private sendStall(time: TimeValue) {
253
+ // TODO don't send if no stalls?
254
+ const res: TelemetryEventData = {
255
+ event: TelemetryEvent.Stall,
256
+ count: this.numStalls,
257
+ time,
258
+ total_ms: Math.round(this.stallAcc * 1000),
259
+ }
260
+ this.stallAcc = 0
261
+ this.numStalls = 0
262
+ this.send(res)
263
+ this.stallSent = true
264
+ this.stallLastTime = time
265
+ }
266
+
267
+ private onTimeUpdate({ current }: TimePosition) {
268
+ if (!this.timeStart) {
269
+ this.timeStart = current
270
+ }
271
+ try {
272
+ const elapsed = current - this.timeStart
273
+ const stallElapsed = current - this.stallLastTime
274
+
275
+ if (!this.stallSent || stallElapsed >= STALL_MEASURE_PERIOD) {
276
+ this.sendStall(current)
277
+ }
278
+
279
+ if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
280
+ this.watchSent = true
281
+ this.send({
282
+ event: TelemetryEvent.Watch,
283
+ })
284
+ }
285
+ } catch (error) {
286
+ reportError(error)
287
+ }
288
+ }
289
+
290
+ private onStart() {
291
+ if (this.started) {
292
+ return
293
+ }
294
+ this.started = true
295
+ this.send({
296
+ event: TelemetryEvent.Start,
297
+ })
298
+ }
299
+ }
@@ -19,19 +19,26 @@ export class VolumeFade extends UICorePlugin {
19
19
 
20
20
  private interval: TimerId | null = null;
21
21
 
22
+ /**
23
+ * @internal
24
+ */
22
25
  get name() {
23
26
  return 'volume_fade';
24
27
  }
25
28
 
29
+ /**
30
+ * @internal
31
+ */
26
32
  override bindEvents() {
33
+ // TODO on container changed
27
34
  this.listenTo(this.core, Events.CORE_READY, this.onCoreReady);
28
35
  if (this.core.mediaControl) {
29
36
  this.listenTo(this.core.mediaControl, 'mediacontrol:volume:user', this._onUserChangeVolume);
30
37
  }
31
- this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
38
+ // this.listenTo(this.core, 'core:volume:config', this._onVolumeConfig);
32
39
  }
33
40
 
34
- unBindEvents() {
41
+ private unBindEvents() {
35
42
  this.core.$el.off('mouseleave.volume');
36
43
  this.core.$el.off('mouseenter.volume');
37
44
  }