@gcorevideo/player 2.19.14 → 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 +2 -2
- package/dist/core.js +2 -2
- package/dist/index.css +780 -780
- package/dist/index.js +1720 -1473
- package/dist/player.d.ts +425 -94
- package/dist/plugins/index.css +1466 -1466
- package/dist/plugins/index.js +1501 -1252
- package/docs/api/player.bottomgear.getelement.md +56 -0
- package/docs/api/player.bottomgear.md +51 -0
- package/docs/api/player.bottomgear.setcontent.md +56 -0
- 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.gearevents.md +49 -0
- package/docs/api/{player.sourcecontroller.name.md → player.gearitemelement.md} +5 -3
- 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.levelselector.md +9 -1
- package/docs/api/player.md +124 -4
- package/docs/api/{player.clapprnerdstats.render.md → player.mediacontrol.getrightpanel.md} +8 -4
- package/docs/api/player.mediacontrol.md +14 -0
- package/docs/api/player.mediacontrolelement.md +1 -1
- package/docs/api/player.pictureinpicture.md +9 -197
- package/docs/api/player.playbackrate.md +10 -314
- package/docs/api/player.sourcecontroller.md +0 -90
- package/docs/api/player.spinnerevents.md +49 -0
- package/docs/api/player.spinnerthreebounce._constructor_.md +3 -0
- package/docs/api/player.spinnerthreebounce.hide.md +5 -0
- package/docs/api/player.spinnerthreebounce.md +14 -95
- package/docs/api/player.spinnerthreebounce.show.md +6 -37
- 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.subtitles.hide.md +5 -0
- package/docs/api/player.subtitles.md +23 -275
- package/docs/api/player.subtitles.show.md +5 -0
- 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.sourcecontroller.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/bottom-gear/BottomGear.d.ts +20 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +28 -7
- 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 +67 -21
- 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/level-selector/LevelSelector.d.ts +10 -3
- package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
- package/lib/plugins/level-selector/LevelSelector.js +20 -19
- package/lib/plugins/media-control/MediaControl.d.ts +6 -2
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +40 -39
- 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/source-controller/SourceController.d.ts +9 -0
- package/lib/plugins/source-controller/SourceController.d.ts.map +1 -1
- package/lib/plugins/source-controller/SourceController.js +11 -1
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts +35 -1
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.d.ts.map +1 -1
- package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +46 -23
- 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/subtitles/Subtitles.d.ts +65 -16
- package/lib/plugins/subtitles/Subtitles.d.ts.map +1 -1
- package/lib/plugins/subtitles/Subtitles.js +131 -109
- 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/bottom-gear/BottomGear.ts +26 -4
- 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/LevelSelector.ts +22 -19
- 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/media-control/MediaControl.ts +43 -41
- package/src/plugins/picture-in-picture/PictureInPicture.ts +35 -7
- package/src/plugins/playback-rate/PlaybackRate.ts +53 -24
- package/src/plugins/source-controller/SourceController.ts +11 -1
- package/src/plugins/source-controller/__tests__/SourceController.test.ts +1 -1
- package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +46 -22
- package/src/plugins/subtitles/Subtitles.ts +146 -155
- package/src/plugins/telemetry/Telemetry.ts +299 -0
- package/src/plugins/volume-fade/VolumeFade.ts +9 -2
- package/temp/player.api.json +3384 -4872
- 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.statsboxelem.md +0 -14
- package/docs/api/player.clapprnerdstats.statsboxwidththreshold.md +0 -14
- package/docs/api/player.clapprnerdstats.supportedversion.md +0 -16
- 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.sourcecontroller.version.md +0 -14
- package/docs/api/player.spinnerthreebounce.attributes.md +0 -14
- package/docs/api/player.spinnerthreebounce.name.md +0 -11
- package/docs/api/player.spinnerthreebounce.render.md +0 -15
- package/docs/api/player.spinnerthreebounce.supportedversion.md +0 -13
- 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.subtitles.attributes.md +0 -14
- package/docs/api/player.subtitles.bindevents.md +0 -15
- package/docs/api/player.subtitles.buttonelement.md +0 -15
- package/docs/api/player.subtitles.events.md +0 -14
- package/docs/api/player.subtitles.levelelement.md +0 -51
- package/docs/api/player.subtitles.name.md +0 -11
- package/docs/api/player.subtitles.preselectedlanguage.md +0 -11
- package/docs/api/player.subtitles.reload.md +0 -15
- package/docs/api/player.subtitles.render.md +0 -15
- package/docs/api/player.subtitles.selectsubtitles.md +0 -15
- package/docs/api/player.subtitles.startlevelswitch.md +0 -15
- package/docs/api/player.subtitles.stoplevelswitch.md +0 -15
- package/docs/api/player.subtitles.supportedversion.md +0 -13
- package/docs/api/player.subtitles.template.md +0 -11
- package/docs/api/player.subtitles.templatestring.md +0 -11
- package/docs/api/player.subtitles.unbindevents.md +0 -15
- package/docs/api/player.subtitles.version.md +0 -11
- 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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Events, UICorePlugin, Browser, template, $, } from '@clappr/core';
|
|
2
|
-
import { reportError } from '@gcorevideo/utils';
|
|
2
|
+
import { reportError, trace } from '@gcorevideo/utils';
|
|
3
3
|
import assert from 'assert';
|
|
4
4
|
import { CLAPPR_VERSION } from '../../build.js';
|
|
5
5
|
import '../../../assets/subtitles/style.scss';
|
|
@@ -8,88 +8,102 @@ import subtitlesOnIcon from '../../../assets/icons/new/subtitles-on.svg';
|
|
|
8
8
|
import comboboxHTML from '../../../assets/subtitles/combobox.ejs';
|
|
9
9
|
import stringHTML from '../../../assets/subtitles/string.ejs';
|
|
10
10
|
import { isFullscreen } from '../utils.js';
|
|
11
|
-
const VERSION = '
|
|
12
|
-
const LOCAL_STORAGE_SUBTITLES_ID = '
|
|
13
|
-
const T = 'plugins.
|
|
11
|
+
const VERSION = '2.19.14';
|
|
12
|
+
const LOCAL_STORAGE_SUBTITLES_ID = 'gplayer.plugins.subtitles.selected';
|
|
13
|
+
const T = 'plugins.subtitles';
|
|
14
14
|
const NO_TRACK = { language: 'off' };
|
|
15
|
+
/**
|
|
16
|
+
* A {@link MediaControl | media control} plugin that provides a UI to select the subtitles when available.
|
|
17
|
+
* @beta
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Depends on:
|
|
21
|
+
*
|
|
22
|
+
* - {@link MediaControl}
|
|
23
|
+
*
|
|
24
|
+
* Configuration options:
|
|
25
|
+
*
|
|
26
|
+
* - subtitles.language - The language of the subtitles to select by default.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { Subtitles } from '@gcorevideo/player'
|
|
31
|
+
*
|
|
32
|
+
* Player.registerPlugin(Subtitles)
|
|
33
|
+
*
|
|
34
|
+
* new Player({
|
|
35
|
+
* ...
|
|
36
|
+
* subtitles: {
|
|
37
|
+
* language: 'en',
|
|
38
|
+
* },
|
|
39
|
+
* })
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
15
42
|
export class Subtitles extends UICorePlugin {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
currentPlayback;
|
|
43
|
+
currentLevel = null;
|
|
44
|
+
isPreselectedApplied = false;
|
|
19
45
|
isShowing = false;
|
|
20
|
-
|
|
21
|
-
|
|
46
|
+
track = { ...NO_TRACK };
|
|
47
|
+
tracks = null;
|
|
48
|
+
$string = null;
|
|
49
|
+
/**
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
22
52
|
get name() {
|
|
23
|
-
return '
|
|
53
|
+
return 'subtitles';
|
|
24
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
25
58
|
get supportedVersion() {
|
|
26
59
|
return { min: CLAPPR_VERSION };
|
|
27
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
28
64
|
static get version() {
|
|
29
65
|
return VERSION;
|
|
30
66
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
67
|
+
static template = template(comboboxHTML);
|
|
68
|
+
static templateString = template(stringHTML);
|
|
69
|
+
/**
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
37
72
|
get attributes() {
|
|
38
73
|
return {
|
|
39
74
|
class: this.name,
|
|
40
75
|
'data-subtitles': '',
|
|
41
76
|
};
|
|
42
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
43
81
|
get events() {
|
|
44
82
|
return {
|
|
45
83
|
'click [data-subtitles-select]': 'onLevelSelect',
|
|
46
84
|
'click [data-subtitles-button]': 'onShowLevelSelectMenu',
|
|
47
85
|
};
|
|
48
86
|
}
|
|
49
|
-
isPreselectedApplied = false;
|
|
50
|
-
track = { ...NO_TRACK };
|
|
51
87
|
get preselectedLanguage() {
|
|
52
88
|
return this.core.options.subtitles?.language ?? 'off';
|
|
53
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
54
93
|
bindEvents() {
|
|
94
|
+
const mediaControl = this.core.getPlugin('media_control');
|
|
95
|
+
assert(mediaControl, 'media_control plugin is required');
|
|
55
96
|
this.listenTo(this.core, Events.CORE_RESIZE, this.playerResize);
|
|
56
|
-
this.
|
|
57
|
-
this.listenTo(
|
|
58
|
-
this.listenTo(
|
|
59
|
-
this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_HIDE, this.hideSelectLevelMenu);
|
|
60
|
-
}
|
|
61
|
-
unBindEvents() {
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
this.stopListening(this.core, Events.CORE_READY);
|
|
64
|
-
// @ts-ignore
|
|
65
|
-
this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED);
|
|
66
|
-
// @ts-ignore
|
|
67
|
-
this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_RENDERED);
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_HIDE);
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
this.stopListening(this.core.mediaControl, Events.MEDIACONTROL_SHOW);
|
|
72
|
-
if (this.currentContainer) {
|
|
73
|
-
// @ts-ignore
|
|
74
|
-
this.stopListening(this.currentContainer, Events.CONTAINER_FULLSCREEN);
|
|
75
|
-
// @ts-ignore
|
|
76
|
-
this.stopListening(this.currentContainer, 'container:advertisement:start', this.onStartAd);
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
this.stopListening(this.currentContainer, 'container:advertisement:finish', this.onFinishAd);
|
|
79
|
-
}
|
|
97
|
+
this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, this.bindPlaybackEvents);
|
|
98
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.render);
|
|
99
|
+
this.listenTo(mediaControl, Events.MEDIACONTROL_HIDE, this.hideSelectLevelMenu);
|
|
80
100
|
}
|
|
81
101
|
bindPlaybackEvents() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
this.currentPlayback = this.core.activePlayback;
|
|
87
|
-
this.currentContainer = this.core.activeContainer;
|
|
88
|
-
this.listenTo(this.currentContainer, Events.CONTAINER_FULLSCREEN, this.playerResize);
|
|
89
|
-
this.listenToOnce(this.currentPlayback, Events.PLAYBACK_PLAY, this.getTracks);
|
|
90
|
-
this.listenTo(this.currentContainer, 'container:advertisement:start', this.onStartAd);
|
|
102
|
+
this.listenTo(this.core.activeContainer, Events.CONTAINER_FULLSCREEN, this.playerResize);
|
|
103
|
+
this.listenToOnce(this.core.activePlayback, Events.PLAYBACK_PLAY, this.getTracks);
|
|
104
|
+
this.listenTo(this.core.activeContainer, 'container:advertisement:start', this.onStartAd);
|
|
91
105
|
// fix for iOS
|
|
92
|
-
const video = this.
|
|
106
|
+
const video = this.core.activePlayback.el;
|
|
93
107
|
assert(video, 'video element is required');
|
|
94
108
|
video.addEventListener('webkitbeginfullscreen', () => {
|
|
95
109
|
if (Browser.isiOS) {
|
|
@@ -103,10 +117,13 @@ export class Subtitles extends UICorePlugin {
|
|
|
103
117
|
});
|
|
104
118
|
}
|
|
105
119
|
getTracks() {
|
|
106
|
-
if (this.
|
|
120
|
+
if (this.core.activePlayback) {
|
|
107
121
|
try {
|
|
108
|
-
const tracks = this.
|
|
109
|
-
|
|
122
|
+
const tracks = this.core.activePlayback.el
|
|
123
|
+
.textTracks;
|
|
124
|
+
if (tracks.length > 0) {
|
|
125
|
+
this.setTracks(tracks);
|
|
126
|
+
}
|
|
110
127
|
}
|
|
111
128
|
catch (error) {
|
|
112
129
|
reportError(error);
|
|
@@ -114,23 +131,18 @@ export class Subtitles extends UICorePlugin {
|
|
|
114
131
|
}
|
|
115
132
|
}
|
|
116
133
|
onStartAd() {
|
|
117
|
-
if (this.isShowing && this.
|
|
134
|
+
if (this.isShowing && this.core.activeContainer) {
|
|
118
135
|
this.hide();
|
|
119
|
-
this.listenTo(this.
|
|
136
|
+
this.listenTo(this.core.activeContainer, 'container:advertisement:finish', this.onFinishAd);
|
|
120
137
|
}
|
|
121
138
|
}
|
|
122
139
|
onFinishAd() {
|
|
123
140
|
this.show();
|
|
124
|
-
this.stopListening(this.
|
|
125
|
-
}
|
|
126
|
-
reload() {
|
|
127
|
-
this.unBindEvents();
|
|
128
|
-
this.bindEvents();
|
|
129
|
-
this.bindPlaybackEvents();
|
|
141
|
+
this.stopListening(this.core.activeContainer, 'container:advertisement:finish', this.onFinishAd);
|
|
130
142
|
}
|
|
131
143
|
playerResize() {
|
|
132
|
-
const shouldShow = this.
|
|
133
|
-
isFullscreen(this.
|
|
144
|
+
const shouldShow = this.core.activeContainer &&
|
|
145
|
+
isFullscreen(this.core.activeContainer.el) &&
|
|
134
146
|
this.currentLevel &&
|
|
135
147
|
this.currentLevel.mode &&
|
|
136
148
|
Browser.isiOS &&
|
|
@@ -145,6 +157,9 @@ export class Subtitles extends UICorePlugin {
|
|
|
145
157
|
reportError(error);
|
|
146
158
|
}
|
|
147
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Hides the subtitles menu and the subtitles.
|
|
162
|
+
*/
|
|
148
163
|
hide() {
|
|
149
164
|
this.isShowing = false;
|
|
150
165
|
this.renderIcon();
|
|
@@ -155,11 +170,14 @@ export class Subtitles extends UICorePlugin {
|
|
|
155
170
|
}
|
|
156
171
|
}
|
|
157
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Shows the subtitles menu and the subtitles.
|
|
175
|
+
*/
|
|
158
176
|
show() {
|
|
159
177
|
this.isShowing = true;
|
|
160
178
|
this.renderIcon();
|
|
161
|
-
if (this.
|
|
162
|
-
isFullscreen(this.
|
|
179
|
+
if (this.core.activeContainer &&
|
|
180
|
+
isFullscreen(this.core.activeContainer.el) &&
|
|
163
181
|
this.currentLevel &&
|
|
164
182
|
this.currentLevel.mode &&
|
|
165
183
|
Browser.isiOS) {
|
|
@@ -171,59 +189,61 @@ export class Subtitles extends UICorePlugin {
|
|
|
171
189
|
}
|
|
172
190
|
}
|
|
173
191
|
shouldRender() {
|
|
174
|
-
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
if (!this.currentPlayback) {
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
// Only care if we have at least 2 to choose from
|
|
181
|
-
const hasLevels = !!(this.tracks && this.tracks.length > 0);
|
|
182
|
-
return hasLevels;
|
|
192
|
+
return !!(this.tracks && this.tracks.length > 0);
|
|
183
193
|
}
|
|
184
194
|
resizeFont() {
|
|
185
|
-
if (!this.
|
|
195
|
+
if (!this.core.activeContainer) {
|
|
186
196
|
return;
|
|
187
197
|
}
|
|
188
198
|
if (!this.$string) {
|
|
189
199
|
return;
|
|
190
200
|
}
|
|
191
|
-
const skinWidth = this.
|
|
201
|
+
const skinWidth = this.core.activeContainer.$el.width();
|
|
192
202
|
this.$string.find('p').css('font-size', skinWidth * 0.03);
|
|
193
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* @internal
|
|
206
|
+
*/
|
|
194
207
|
render() {
|
|
195
|
-
if (this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
if (!this.core.activeContainer) {
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
if (!this.shouldRender()) {
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
trace(`${T} render`, {
|
|
215
|
+
tracks: this.tracks?.length,
|
|
216
|
+
track: this.track?.language,
|
|
217
|
+
});
|
|
218
|
+
const mediaControl = this.core.getPlugin('media_control');
|
|
219
|
+
assert(mediaControl, 'media_control plugin is required');
|
|
220
|
+
this.$el.html(Subtitles.template({ tracks: this.tracks }));
|
|
221
|
+
this.core.activeContainer.$el.find('.subtitle-string').remove();
|
|
222
|
+
this.$string = $(Subtitles.templateString());
|
|
223
|
+
this.resizeFont();
|
|
224
|
+
this.core.activeContainer.$el.append(this.$string[0]);
|
|
225
|
+
const ss = mediaControl.getElement('subtitlesSelector');
|
|
226
|
+
if (ss && ss.length > 0) {
|
|
227
|
+
ss.append(this.el);
|
|
211
228
|
}
|
|
212
|
-
|
|
213
|
-
.
|
|
214
|
-
this.renderIcon();
|
|
229
|
+
else {
|
|
230
|
+
mediaControl.getRightPanel().append(this.el);
|
|
215
231
|
}
|
|
232
|
+
this.updateCurrentLevel(this.track);
|
|
233
|
+
this.highlightCurrentSubtitles();
|
|
234
|
+
this.applyPreselectedSubtitles();
|
|
235
|
+
this.renderIcon();
|
|
216
236
|
return this;
|
|
217
237
|
}
|
|
218
|
-
|
|
238
|
+
setTracks(tracks) {
|
|
219
239
|
this.tracks = tracks;
|
|
220
240
|
this.render();
|
|
221
241
|
}
|
|
222
242
|
findLevelBy(id) {
|
|
223
243
|
if (this.tracks) {
|
|
224
|
-
for (
|
|
225
|
-
if (
|
|
226
|
-
return
|
|
244
|
+
for (const track of this.tracks) {
|
|
245
|
+
if (track.language === id) {
|
|
246
|
+
return track; // TODO TrackInfo?
|
|
227
247
|
}
|
|
228
248
|
}
|
|
229
249
|
}
|
|
@@ -254,21 +274,21 @@ export class Subtitles extends UICorePlugin {
|
|
|
254
274
|
}
|
|
255
275
|
}
|
|
256
276
|
onShowLevelSelectMenu() {
|
|
277
|
+
trace(`${T} onShowLevelSelectMenu`);
|
|
257
278
|
this.toggleContextMenu();
|
|
258
279
|
}
|
|
259
280
|
hideSelectLevelMenu() {
|
|
260
281
|
;
|
|
261
|
-
this.$('
|
|
282
|
+
this.$('[data-subtitles] ul').hide();
|
|
262
283
|
}
|
|
263
284
|
toggleContextMenu() {
|
|
264
|
-
;
|
|
265
|
-
this.$('.subtitles ul').toggle();
|
|
285
|
+
this.$('[data-subtitles] ul').toggle();
|
|
266
286
|
}
|
|
267
287
|
buttonElement() {
|
|
268
|
-
return this.$('
|
|
288
|
+
return this.$('[data-subtitles] button');
|
|
269
289
|
}
|
|
270
290
|
levelElement(id) {
|
|
271
|
-
return this.$('
|
|
291
|
+
return this.$('[data-subtitles] ul a' + (id ? '[data-subtitles-select="' + id + '"]' : '')).parent();
|
|
272
292
|
}
|
|
273
293
|
startLevelSwitch() {
|
|
274
294
|
this.buttonElement().addClass('changing');
|
|
@@ -285,7 +305,7 @@ export class Subtitles extends UICorePlugin {
|
|
|
285
305
|
const track = this.tracks[i];
|
|
286
306
|
if (track.language === this.currentLevel.language) {
|
|
287
307
|
track.mode = 'showing';
|
|
288
|
-
const currentTime = this.
|
|
308
|
+
const currentTime = this.core.activePlayback?.getCurrentTime() ?? 0;
|
|
289
309
|
const cues = track.cues;
|
|
290
310
|
let subtitleText = '';
|
|
291
311
|
if (cues && cues.length) {
|
|
@@ -347,8 +367,10 @@ export class Subtitles extends UICorePlugin {
|
|
|
347
367
|
}
|
|
348
368
|
renderIcon() {
|
|
349
369
|
const icon = this.isShowing ? subtitlesOnIcon : subtitlesOffIcon;
|
|
350
|
-
this.core
|
|
351
|
-
.
|
|
370
|
+
this.core
|
|
371
|
+
.getPlugin('media_control')
|
|
372
|
+
.getElement('subtitlesSelector')
|
|
373
|
+
?.find('span.subtitle-text')
|
|
352
374
|
.html(icon);
|
|
353
375
|
}
|
|
354
376
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Container, ContainerPlugin } from '@clappr/core';
|
|
2
|
+
import type { PlaybackType } from '../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Telemetry event data
|
|
5
|
+
*/
|
|
6
|
+
export type TelemetryEventData = StallEventData | InitEventData | StartEventData | WatchEventData;
|
|
7
|
+
/**
|
|
8
|
+
* Playback stall event data
|
|
9
|
+
*/
|
|
10
|
+
export interface StallEventData {
|
|
11
|
+
event: TelemetryEvent.Stall;
|
|
12
|
+
/**
|
|
13
|
+
* Accumulated buffering duration over the measurement interval, ms
|
|
14
|
+
*/
|
|
15
|
+
total_ms: number;
|
|
16
|
+
/**
|
|
17
|
+
* Number of stalls
|
|
18
|
+
*/
|
|
19
|
+
count: number;
|
|
20
|
+
/**
|
|
21
|
+
* Playback time when the stall is reported at the end of a stall measurement interval, s
|
|
22
|
+
*/
|
|
23
|
+
time: number;
|
|
24
|
+
}
|
|
25
|
+
export interface InitEventData {
|
|
26
|
+
event: TelemetryEvent.Init;
|
|
27
|
+
}
|
|
28
|
+
export interface StartEventData {
|
|
29
|
+
event: TelemetryEvent.Start;
|
|
30
|
+
}
|
|
31
|
+
export interface WatchEventData {
|
|
32
|
+
event: TelemetryEvent.Watch;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Telemetry record
|
|
36
|
+
*/
|
|
37
|
+
export type TelemetryRecord = {
|
|
38
|
+
type: PlaybackType;
|
|
39
|
+
} & TelemetryEventData;
|
|
40
|
+
/**
|
|
41
|
+
* Callback to send the telemetry record to the storage.
|
|
42
|
+
* @param data - The telemetry record to send.
|
|
43
|
+
*/
|
|
44
|
+
type TelemetrySendFn = (data: TelemetryRecord) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Plugin settings
|
|
47
|
+
*/
|
|
48
|
+
export interface TelemetryPluginSettings {
|
|
49
|
+
/**
|
|
50
|
+
* Sends the statistics record to the storage.
|
|
51
|
+
* The actual delivery is presumably async and batched.
|
|
52
|
+
*/
|
|
53
|
+
send: TelemetrySendFn;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Telemetry event type
|
|
57
|
+
*/
|
|
58
|
+
export declare enum TelemetryEvent {
|
|
59
|
+
Init = 1,
|
|
60
|
+
Start = 2,
|
|
61
|
+
Watch = 3,
|
|
62
|
+
Stall = 4
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Collects and reports the performance statistics.
|
|
66
|
+
* @beta
|
|
67
|
+
* @remarks
|
|
68
|
+
* This plugin is experimental and its API is likely to change.
|
|
69
|
+
*
|
|
70
|
+
* Configuration options {@link TelemetryPluginSettings}
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { Statistics } from '@gcorevideo/player'
|
|
75
|
+
*
|
|
76
|
+
* Player.registerPlugin(Statistics)
|
|
77
|
+
*
|
|
78
|
+
* const player = new Player({
|
|
79
|
+
* statistics: {
|
|
80
|
+
* send: (data) => {
|
|
81
|
+
* fetch('/stats', {
|
|
82
|
+
* method: 'POST',
|
|
83
|
+
* body: JSON.stringify(data),
|
|
84
|
+
* headers: { 'content-type': 'application/json' },
|
|
85
|
+
* })
|
|
86
|
+
* },
|
|
87
|
+
* },
|
|
88
|
+
* ...
|
|
89
|
+
* })
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare class Telemetry extends ContainerPlugin {
|
|
93
|
+
/**
|
|
94
|
+
* The name of the plugin.
|
|
95
|
+
*/
|
|
96
|
+
get name(): string;
|
|
97
|
+
/**
|
|
98
|
+
* The supported version of the plugin.
|
|
99
|
+
*/
|
|
100
|
+
get supportedVersion(): {
|
|
101
|
+
min: string;
|
|
102
|
+
};
|
|
103
|
+
private started;
|
|
104
|
+
private timeStart;
|
|
105
|
+
private stallSent;
|
|
106
|
+
private stallLastTime;
|
|
107
|
+
private watchSent;
|
|
108
|
+
private bufTracking;
|
|
109
|
+
private numStalls;
|
|
110
|
+
/**
|
|
111
|
+
* The time when buffering last started.
|
|
112
|
+
*/
|
|
113
|
+
private bufLastStarted;
|
|
114
|
+
/**
|
|
115
|
+
* The accumulated buffering duration.
|
|
116
|
+
*/
|
|
117
|
+
private stallAcc;
|
|
118
|
+
constructor(container: Container);
|
|
119
|
+
/**
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
bindEvents(): void;
|
|
123
|
+
private startLevelSwitch;
|
|
124
|
+
private endLevelSwitch;
|
|
125
|
+
private onBuffering;
|
|
126
|
+
private onBufferFull;
|
|
127
|
+
private onReady;
|
|
128
|
+
private sendInit;
|
|
129
|
+
private send;
|
|
130
|
+
private sendStall;
|
|
131
|
+
private onTimeUpdate;
|
|
132
|
+
private onStart;
|
|
133
|
+
}
|
|
134
|
+
export {};
|
|
135
|
+
//# sourceMappingURL=Telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Telemetry.d.ts","sourceRoot":"","sources":["../../../src/plugins/telemetry/Telemetry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAU,MAAM,cAAc,CAAA;AAKjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAUlD;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,CAAA;AAEjG;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAA;IAC3B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,cAAc,CAAC,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAA;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,YAAY,CAAA;CACnB,GAAG,kBAAkB,CAAC;AAEvB;;;GAGG;AACH,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;AAEtD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,IAAI,EAAE,eAAe,CAAA;CACtB;AAED;;GAEG;AACH,oBAAY,cAAc;IACxB,IAAI,IAAI;IACR,KAAK,IAAA;IACL,KAAK,IAAA;IACL,KAAK,IAAA;CACN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,SAAU,SAAQ,eAAe;IAC5C;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,SAAS,CAAI;IAErB,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,WAAW,CAAQ;IAE3B,OAAO,CAAC,SAAS,CAAI;IAErB;;OAEG;IACH,OAAO,CAAC,cAAc,CAAI;IAE1B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAI;gBAER,SAAS,EAAE,SAAS;IAUhC;;OAEG;IACM,UAAU;IAoCnB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,OAAO;CAShB"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// An example implementation of client side performancestatistics
|
|
2
|
+
import { ContainerPlugin, Events } from '@clappr/core';
|
|
3
|
+
import { reportError, trace } from '@gcorevideo/utils';
|
|
4
|
+
import assert from 'assert';
|
|
5
|
+
import { CLAPPR_VERSION } from '../../build.js';
|
|
6
|
+
const WATCH_CUTOFF = 5;
|
|
7
|
+
const STALL_MEASURE_PERIOD = 10;
|
|
8
|
+
const T = 'plugins.telemetry';
|
|
9
|
+
/**
|
|
10
|
+
* Telemetry event type
|
|
11
|
+
*/
|
|
12
|
+
export var TelemetryEvent;
|
|
13
|
+
(function (TelemetryEvent) {
|
|
14
|
+
TelemetryEvent[TelemetryEvent["Init"] = 1] = "Init";
|
|
15
|
+
TelemetryEvent[TelemetryEvent["Start"] = 2] = "Start";
|
|
16
|
+
TelemetryEvent[TelemetryEvent["Watch"] = 3] = "Watch";
|
|
17
|
+
TelemetryEvent[TelemetryEvent["Stall"] = 4] = "Stall";
|
|
18
|
+
})(TelemetryEvent || (TelemetryEvent = {}));
|
|
19
|
+
/**
|
|
20
|
+
* Collects and reports the performance statistics.
|
|
21
|
+
* @beta
|
|
22
|
+
* @remarks
|
|
23
|
+
* This plugin is experimental and its API is likely to change.
|
|
24
|
+
*
|
|
25
|
+
* Configuration options {@link TelemetryPluginSettings}
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { Statistics } from '@gcorevideo/player'
|
|
30
|
+
*
|
|
31
|
+
* Player.registerPlugin(Statistics)
|
|
32
|
+
*
|
|
33
|
+
* const player = new Player({
|
|
34
|
+
* statistics: {
|
|
35
|
+
* send: (data) => {
|
|
36
|
+
* fetch('/stats', {
|
|
37
|
+
* method: 'POST',
|
|
38
|
+
* body: JSON.stringify(data),
|
|
39
|
+
* headers: { 'content-type': 'application/json' },
|
|
40
|
+
* })
|
|
41
|
+
* },
|
|
42
|
+
* },
|
|
43
|
+
* ...
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export class Telemetry extends ContainerPlugin {
|
|
48
|
+
/**
|
|
49
|
+
* The name of the plugin.
|
|
50
|
+
*/
|
|
51
|
+
get name() {
|
|
52
|
+
return 'telemetry';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The supported version of the plugin.
|
|
56
|
+
*/
|
|
57
|
+
get supportedVersion() {
|
|
58
|
+
return { min: CLAPPR_VERSION };
|
|
59
|
+
}
|
|
60
|
+
started = false;
|
|
61
|
+
timeStart = 0;
|
|
62
|
+
stallSent = false;
|
|
63
|
+
stallLastTime = 0;
|
|
64
|
+
watchSent = false;
|
|
65
|
+
bufTracking = false;
|
|
66
|
+
numStalls = 0;
|
|
67
|
+
/**
|
|
68
|
+
* The time when buffering last started.
|
|
69
|
+
*/
|
|
70
|
+
bufLastStarted = 0;
|
|
71
|
+
/**
|
|
72
|
+
* The accumulated buffering duration.
|
|
73
|
+
*/
|
|
74
|
+
stallAcc = 0;
|
|
75
|
+
constructor(container) {
|
|
76
|
+
super(container);
|
|
77
|
+
assert(this.options.telemetry &&
|
|
78
|
+
typeof this.options.telemetry.send === 'function', 'Telemetry plugin configuration is invalid: `send` option is required');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
bindEvents() {
|
|
84
|
+
// TODO remove this
|
|
85
|
+
// this.listenToOnce(
|
|
86
|
+
// this.container,
|
|
87
|
+
// CUSTOM_EVENTS_CONTAINER_START,
|
|
88
|
+
// this.onStart,
|
|
89
|
+
// )
|
|
90
|
+
this.listenToOnce(this.container, Events.CONTAINER_READY, this.onReady);
|
|
91
|
+
this.listenTo(this.container, Events.CONTAINER_STATE_BUFFERING, this.onBuffering);
|
|
92
|
+
this.listenTo(this.container, Events.CONTAINER_STATE_BUFFERFULL, this.onBufferFull);
|
|
93
|
+
this.listenTo(this.container.playback, Events.PLAYBACK_TIMEUPDATE, this.onTimeUpdate);
|
|
94
|
+
this.listenTo(this.container.playback, Events.PLAYBACK_LEVEL_SWITCH_START, this.startLevelSwitch);
|
|
95
|
+
this.listenTo(this.container.playback, Events.PLAYBACK_LEVEL_SWITCH_END, this.endLevelSwitch);
|
|
96
|
+
}
|
|
97
|
+
startLevelSwitch() {
|
|
98
|
+
this.bufTracking = false;
|
|
99
|
+
}
|
|
100
|
+
endLevelSwitch() {
|
|
101
|
+
this.bufTracking = true;
|
|
102
|
+
}
|
|
103
|
+
onBuffering() {
|
|
104
|
+
if (this.bufTracking) {
|
|
105
|
+
this.bufLastStarted = performance.now();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
onBufferFull() {
|
|
109
|
+
if (this.bufTracking && this.bufLastStarted) {
|
|
110
|
+
this.stallAcc += performance.now() - this.bufLastStarted;
|
|
111
|
+
this.numStalls++;
|
|
112
|
+
}
|
|
113
|
+
this.bufTracking = true;
|
|
114
|
+
}
|
|
115
|
+
onReady() {
|
|
116
|
+
this.sendInit();
|
|
117
|
+
trace(`${T} onReady`, {
|
|
118
|
+
autoPlay: this.options.autoPlay,
|
|
119
|
+
});
|
|
120
|
+
if (this.options.autoPlay) {
|
|
121
|
+
this.onStart();
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
this.listenToOnce(this.container.playback, Events.PLAYBACK_PLAY_INTENT, this.onStart);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
sendInit() {
|
|
128
|
+
this.send({ event: TelemetryEvent.Init });
|
|
129
|
+
}
|
|
130
|
+
send(event) {
|
|
131
|
+
this.options.telemetry.send({
|
|
132
|
+
type: this.container.getPlaybackType(),
|
|
133
|
+
...event,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
sendStall(time) {
|
|
137
|
+
// TODO don't send if no stalls?
|
|
138
|
+
const res = {
|
|
139
|
+
event: TelemetryEvent.Stall,
|
|
140
|
+
count: this.numStalls,
|
|
141
|
+
time,
|
|
142
|
+
total_ms: Math.round(this.stallAcc * 1000),
|
|
143
|
+
};
|
|
144
|
+
this.stallAcc = 0;
|
|
145
|
+
this.numStalls = 0;
|
|
146
|
+
this.send(res);
|
|
147
|
+
this.stallSent = true;
|
|
148
|
+
this.stallLastTime = time;
|
|
149
|
+
}
|
|
150
|
+
onTimeUpdate({ current }) {
|
|
151
|
+
if (!this.timeStart) {
|
|
152
|
+
this.timeStart = current;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const elapsed = current - this.timeStart;
|
|
156
|
+
const stallElapsed = current - this.stallLastTime;
|
|
157
|
+
if (!this.stallSent || stallElapsed >= STALL_MEASURE_PERIOD) {
|
|
158
|
+
this.sendStall(current);
|
|
159
|
+
}
|
|
160
|
+
if (!this.watchSent && elapsed >= WATCH_CUTOFF) {
|
|
161
|
+
this.watchSent = true;
|
|
162
|
+
this.send({
|
|
163
|
+
event: TelemetryEvent.Watch,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
reportError(error);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
onStart() {
|
|
172
|
+
if (this.started) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
this.started = true;
|
|
176
|
+
this.send({
|
|
177
|
+
event: TelemetryEvent.Start,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|