@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.
- package/assets/level-selector/list.ejs +1 -1
- package/dist/core.js +2 -2
- package/dist/index.css +1634 -1634
- package/dist/index.js +585 -416
- package/dist/player.d.ts +268 -72
- package/dist/plugins/index.css +1567 -1567
- package/dist/plugins/index.js +526 -357
- package/docs/api/player.clapprnerdstats.md +12 -259
- package/docs/api/player.dvrcontrols.md +5 -1
- package/docs/api/player.errorscreen.attributes.md +3 -0
- package/docs/api/player.errorscreen.bindevents.md +3 -0
- package/docs/api/player.errorscreen.container.md +3 -0
- package/docs/api/player.errorscreen.hide.md +3 -0
- package/docs/api/player.errorscreen.md +27 -0
- package/docs/api/player.errorscreen.name.md +3 -0
- package/docs/api/player.errorscreen.render.md +3 -0
- package/docs/api/player.errorscreen.show.md +3 -0
- package/docs/api/player.errorscreen.supportedversion.md +3 -0
- package/docs/api/player.errorscreen.template.md +3 -0
- package/docs/api/player.errorscreen.unbindevents.md +3 -0
- package/docs/api/{player.playbackrate.template.md → player.initeventdata.event.md} +3 -3
- package/docs/api/{player.playbackrate.updateplaybackrate.md → player.initeventdata.md} +15 -11
- package/docs/api/player.md +88 -5
- package/docs/api/player.pictureinpicture.md +9 -197
- package/docs/api/player.playbackrate.md +10 -314
- package/docs/api/{player.playbackrate.onplay.md → player.stalleventdata.count.md} +5 -7
- package/docs/api/{player.playbackrate.name.md → player.stalleventdata.event.md} +3 -3
- package/docs/api/player.stalleventdata.md +112 -0
- package/docs/api/player.stalleventdata.time.md +13 -0
- package/docs/api/player.stalleventdata.total_ms.md +13 -0
- package/docs/api/{player.pluginsettings.md → player.starteventdata.event.md} +3 -5
- package/docs/api/{player.playbackrate.onrateselect.md → player.starteventdata.md} +15 -11
- package/docs/api/{player.statistics._constructor_.md → player.telemetry._constructor_.md} +6 -3
- package/docs/api/player.telemetry.md +146 -0
- package/docs/api/{player.volumefade.name.md → player.telemetry.name.md} +4 -2
- package/docs/api/{player.clapprnerdstats.supportedversion.md → player.telemetry.supportedversion.md} +4 -2
- package/docs/api/player.telemetryevent.md +89 -0
- package/docs/api/player.telemetryeventdata.md +15 -0
- package/docs/api/player.telemetrypluginsettings.md +57 -0
- package/docs/api/player.telemetrypluginsettings.send.md +13 -0
- package/docs/api/player.telemetryrecord.md +17 -0
- package/docs/api/player.volumefade.md +0 -93
- package/docs/api/{player.pictureinpicture.name.md → player.watcheventdata.event.md} +3 -3
- package/docs/api/{player.playbackrate.setselectedrate.md → player.watcheventdata.md} +15 -11
- package/lib/index.plugins.d.ts +2 -2
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +2 -2
- package/lib/playback/hls-playback/HlsPlayback.js +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +38 -5
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +63 -17
- package/lib/plugins/dvr-controls/DvrControls.d.ts +5 -2
- package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
- package/lib/plugins/dvr-controls/DvrControls.js +5 -2
- package/lib/plugins/error-screen/ErrorScreen.d.ts +5 -0
- package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
- package/lib/plugins/error-screen/ErrorScreen.js +5 -0
- package/lib/plugins/index.d.ts +2 -3
- package/lib/plugins/index.d.ts.map +1 -1
- package/lib/plugins/index.js +2 -3
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts +32 -4
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
- package/lib/plugins/picture-in-picture/PictureInPicture.js +30 -2
- package/lib/plugins/playback-rate/PlaybackRate.d.ts +47 -14
- package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
- package/lib/plugins/playback-rate/PlaybackRate.js +38 -9
- package/lib/plugins/statistics/Statistics.d.ts +38 -3
- package/lib/plugins/statistics/Statistics.d.ts.map +1 -1
- package/lib/plugins/statistics/Statistics.js +51 -9
- package/lib/plugins/telemetry/Telemetry.d.ts +135 -0
- package/lib/plugins/telemetry/Telemetry.d.ts.map +1 -0
- package/lib/plugins/telemetry/Telemetry.js +180 -0
- package/lib/plugins/volume-fade/VolumeFade.d.ts +7 -1
- package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -1
- package/lib/plugins/volume-fade/VolumeFade.js +8 -1
- package/package.json +1 -1
- package/src/index.plugins.ts +2 -2
- package/src/playback/hls-playback/HlsPlayback.ts +1 -1
- package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +240 -173
- package/src/plugins/dvr-controls/DvrControls.ts +5 -2
- package/src/plugins/error-screen/ErrorScreen.ts +5 -0
- package/src/plugins/index.ts +2 -3
- package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +47 -26
- package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +18 -18
- package/src/plugins/picture-in-picture/PictureInPicture.ts +35 -7
- package/src/plugins/playback-rate/PlaybackRate.ts +53 -24
- package/src/plugins/telemetry/Telemetry.ts +299 -0
- package/src/plugins/volume-fade/VolumeFade.ts +9 -2
- package/temp/player.api.json +2322 -3281
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.clapprnerdstats.attributes.md +0 -17
- package/docs/api/player.clapprnerdstats.bindevents.md +0 -18
- package/docs/api/player.clapprnerdstats.events.md +0 -18
- package/docs/api/player.clapprnerdstats.name.md +0 -14
- package/docs/api/player.clapprnerdstats.playerheight.md +0 -14
- package/docs/api/player.clapprnerdstats.playerwidth.md +0 -14
- package/docs/api/player.clapprnerdstats.render.md +0 -18
- package/docs/api/player.clapprnerdstats.statsboxelem.md +0 -14
- package/docs/api/player.clapprnerdstats.statsboxwidththreshold.md +0 -14
- package/docs/api/player.clapprnerdstats.template.md +0 -14
- package/docs/api/player.pictureinpicture.bindevents.md +0 -15
- package/docs/api/player.pictureinpicture.events.md +0 -13
- package/docs/api/player.pictureinpicture.exitpictureinpicture.md +0 -15
- package/docs/api/player.pictureinpicture.render.md +0 -15
- package/docs/api/player.pictureinpicture.requestpictureinpicture.md +0 -15
- package/docs/api/player.pictureinpicture.supportedversion.md +0 -13
- package/docs/api/player.pictureinpicture.togglepictureinpicture.md +0 -15
- package/docs/api/player.pictureinpicture.version.md +0 -11
- package/docs/api/player.pictureinpicture.videoelement.md +0 -11
- package/docs/api/player.playbackrate.attributes.md +0 -14
- package/docs/api/player.playbackrate.bindevents.md +0 -15
- package/docs/api/player.playbackrate.events.md +0 -15
- package/docs/api/player.playbackrate.gettitle.md +0 -15
- package/docs/api/player.playbackrate.goback.md +0 -15
- package/docs/api/player.playbackrate.highlightcurrentrate.md +0 -15
- package/docs/api/player.playbackrate.onfinishad.md +0 -15
- package/docs/api/player.playbackrate.onshowmenu.md +0 -15
- package/docs/api/player.playbackrate.onstartad.md +0 -15
- package/docs/api/player.playbackrate.onstop.md +0 -15
- package/docs/api/player.playbackrate.reload.md +0 -15
- package/docs/api/player.playbackrate.render.md +0 -15
- package/docs/api/player.playbackrate.supportedversion.md +0 -13
- package/docs/api/player.playbackrate.unbindevents.md +0 -15
- package/docs/api/player.statistics.bindevents.md +0 -15
- package/docs/api/player.statistics.md +0 -141
- package/docs/api/player.statistics.name.md +0 -11
- package/docs/api/player.statistics.supportedversion.md +0 -13
- package/docs/api/player.volumefade.bindevents.md +0 -18
- package/docs/api/player.volumefade.unbindevents.md +0 -18
- package/src/plugins/statistics/Statistics.ts +0 -207
- /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
|
}
|