@gcorevideo/player 2.19.11 → 2.19.13

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 (167) hide show
  1. package/dist/core.js +16 -11
  2. package/dist/index.css +684 -684
  3. package/dist/index.js +301 -151
  4. package/dist/player.d.ts +208 -45
  5. package/dist/plugins/index.css +941 -941
  6. package/dist/plugins/index.js +3227 -3080
  7. package/docs/api/player.bottomgear.md +3 -289
  8. package/docs/api/player.dvrcontrols._constructor_.md +3 -0
  9. package/docs/api/player.dvrcontrols.md +10 -201
  10. package/docs/api/player.levelselector.md +8 -140
  11. package/docs/api/player.md +8 -4
  12. package/docs/api/player.mediacontrol.disable.md +2 -0
  13. package/docs/api/player.mediacontrol.disabledcontrolbutton.md +1 -1
  14. package/docs/api/player.mediacontrol.enable.md +2 -0
  15. package/docs/api/player.mediacontrol.enablecontrolbutton.md +1 -1
  16. package/docs/api/player.mediacontrol.getelement.md +19 -1
  17. package/docs/api/player.mediacontrol.md +17 -281
  18. package/docs/api/player.mediacontrol.volume.md +2 -2
  19. package/docs/api/player.mediacontrolelement.md +2 -1
  20. package/docs/api/player.poster.disable.md +5 -0
  21. package/docs/api/player.poster.enable.md +5 -0
  22. package/docs/api/player.poster.md +25 -183
  23. package/lib/Player.d.ts +1 -0
  24. package/lib/Player.d.ts.map +1 -1
  25. package/lib/Player.js +15 -10
  26. package/lib/plugins/audio-selector/AudioSelector.js +2 -2
  27. package/lib/plugins/big-mute-button/BigMuteButton.d.ts.map +1 -1
  28. package/lib/plugins/big-mute-button/BigMuteButton.js +2 -1
  29. package/lib/plugins/bottom-gear/BottomGear.d.ts +28 -7
  30. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  31. package/lib/plugins/bottom-gear/BottomGear.js +44 -31
  32. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  33. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +3 -2
  34. package/lib/plugins/clappr-stats/ClapprStats.js +1 -1
  35. package/lib/plugins/click-to-pause/ClickToPause.js +1 -1
  36. package/lib/plugins/clips/Clips.js +2 -2
  37. package/lib/plugins/context-menu/ContextMenu.js +1 -1
  38. package/lib/plugins/disable-controls/DisableControls.js +1 -1
  39. package/lib/plugins/dvr-controls/DvrControls.d.ts +30 -4
  40. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  41. package/lib/plugins/dvr-controls/DvrControls.js +39 -11
  42. package/lib/plugins/error-screen/ErrorScreen.d.ts.map +1 -1
  43. package/lib/plugins/error-screen/ErrorScreen.js +2 -1
  44. package/lib/plugins/favicon/Favicon.js +1 -1
  45. package/lib/plugins/google-analytics/GoogleAnalytics.js +1 -1
  46. package/lib/plugins/level-selector/LevelSelector.d.ts +25 -6
  47. package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
  48. package/lib/plugins/level-selector/LevelSelector.js +33 -12
  49. package/lib/plugins/logo/Logo.js +1 -1
  50. package/lib/plugins/media-control/MediaControl.d.ts +66 -22
  51. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  52. package/lib/plugins/media-control/MediaControl.js +71 -34
  53. package/lib/plugins/multi-camera/MultiCamera.js +3 -3
  54. package/lib/plugins/picture-in-picture/PictureInPicture.js +3 -3
  55. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  56. package/lib/plugins/playback-rate/PlaybackRate.js +3 -3
  57. package/lib/plugins/poster/Poster.d.ts +57 -3
  58. package/lib/plugins/poster/Poster.d.ts.map +1 -1
  59. package/lib/plugins/poster/Poster.js +57 -9
  60. package/lib/plugins/seek-time/SeekTime.js +2 -2
  61. package/lib/plugins/share/Share.js +2 -2
  62. package/lib/plugins/skip-time/SkipTime.js +1 -1
  63. package/lib/plugins/source-controller/SourceController.d.ts.map +1 -1
  64. package/lib/plugins/source-controller/SourceController.js +1 -2
  65. package/lib/plugins/spinner-three-bounce/SpinnerThreeBounce.js +1 -1
  66. package/lib/plugins/statistics/Statistics.js +1 -1
  67. package/lib/plugins/subtitles/Subtitles.js +3 -3
  68. package/lib/plugins/thumbnails/Thumbnails.js +3 -3
  69. package/lib/plugins/types.d.ts +1 -7
  70. package/lib/plugins/types.d.ts.map +1 -1
  71. package/lib/plugins/vast-ads/VastAds.d.ts +1 -0
  72. package/lib/plugins/vast-ads/VastAds.d.ts.map +1 -1
  73. package/lib/plugins/vast-ads/VastAds.js +6 -3
  74. package/package.json +2 -1
  75. package/src/Player.ts +15 -9
  76. package/src/__tests__/Player.test.ts +15 -76
  77. package/src/plugins/audio-selector/AudioSelector.ts +2 -2
  78. package/src/plugins/big-mute-button/BigMuteButton.ts +2 -1
  79. package/src/plugins/bottom-gear/BottomGear.ts +50 -39
  80. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +3 -2
  81. package/src/plugins/clappr-stats/ClapprStats.ts +1 -1
  82. package/src/plugins/click-to-pause/ClickToPause.ts +1 -1
  83. package/src/plugins/clips/Clips.ts +2 -2
  84. package/src/plugins/context-menu/ContextMenu.ts +1 -1
  85. package/src/plugins/disable-controls/DisableControls.ts +1 -1
  86. package/src/plugins/dvr-controls/DvrControls.ts +42 -14
  87. package/src/plugins/error-screen/ErrorScreen.ts +2 -1
  88. package/src/plugins/favicon/Favicon.ts +1 -1
  89. package/src/plugins/google-analytics/GoogleAnalytics.ts +1 -1
  90. package/src/plugins/level-selector/LevelSelector.ts +34 -14
  91. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +22 -2
  92. package/src/plugins/logo/Logo.ts +1 -1
  93. package/src/plugins/media-control/MediaControl.ts +82 -44
  94. package/src/plugins/multi-camera/MultiCamera.ts +3 -3
  95. package/src/plugins/picture-in-picture/PictureInPicture.ts +3 -3
  96. package/src/plugins/playback-rate/PlaybackRate.ts +3 -4
  97. package/src/plugins/poster/Poster.ts +59 -12
  98. package/src/plugins/seek-time/SeekTime.ts +2 -2
  99. package/src/plugins/share/Share.ts +2 -2
  100. package/src/plugins/skip-time/SkipTime.ts +1 -1
  101. package/src/plugins/source-controller/SourceController.ts +1 -2
  102. package/src/plugins/source-controller/__tests__/SourceController.test.ts +5 -0
  103. package/src/plugins/spinner-three-bounce/SpinnerThreeBounce.ts +1 -1
  104. package/src/plugins/statistics/Statistics.ts +1 -1
  105. package/src/plugins/subtitles/Subtitles.ts +3 -3
  106. package/src/plugins/thumbnails/Thumbnails.ts +3 -3
  107. package/src/plugins/types.ts +1 -0
  108. package/src/plugins/vast-ads/VastAds.ts +6 -6
  109. package/temp/player.api.json +3300 -5029
  110. package/tsconfig.tsbuildinfo +1 -1
  111. package/docs/api/player.bottomgear.attributes.md +0 -17
  112. package/docs/api/player.bottomgear.bindevents.md +0 -18
  113. package/docs/api/player.bottomgear.container.md +0 -14
  114. package/docs/api/player.bottomgear.events.md +0 -16
  115. package/docs/api/player.bottomgear.hide.md +0 -18
  116. package/docs/api/player.bottomgear.name.md +0 -14
  117. package/docs/api/player.bottomgear.refresh.md +0 -18
  118. package/docs/api/player.bottomgear.reload.md +0 -18
  119. package/docs/api/player.bottomgear.render.md +0 -18
  120. package/docs/api/player.bottomgear.supportedversion.md +0 -16
  121. package/docs/api/player.bottomgear.template.md +0 -14
  122. package/docs/api/player.bottomgear.togglegearmenu.md +0 -18
  123. package/docs/api/player.bottomgear.unbindevents.md +0 -18
  124. package/docs/api/player.bottomgear.version.md +0 -14
  125. package/docs/api/player.dvrcontrols.attributes.md +0 -14
  126. package/docs/api/player.dvrcontrols.bindevents.md +0 -15
  127. package/docs/api/player.dvrcontrols.click.md +0 -15
  128. package/docs/api/player.dvrcontrols.events.md +0 -13
  129. package/docs/api/player.dvrcontrols.name.md +0 -11
  130. package/docs/api/player.dvrcontrols.render.md +0 -15
  131. package/docs/api/player.dvrcontrols.settingsupdate.md +0 -15
  132. package/docs/api/player.dvrcontrols.shouldrender.md +0 -15
  133. package/docs/api/player.dvrcontrols.supportedversion.md +0 -13
  134. package/docs/api/player.dvrcontrols.template.md +0 -11
  135. package/docs/api/player.levelselector.attributes.md +0 -17
  136. package/docs/api/player.levelselector.bindevents.md +0 -18
  137. package/docs/api/player.levelselector.name.md +0 -14
  138. package/docs/api/player.levelselector.render.md +0 -18
  139. package/docs/api/player.levelselector.supportedversion.md +0 -16
  140. package/docs/api/player.levelselector.version.md +0 -14
  141. package/docs/api/player.mediacontrol.attributes.md +0 -17
  142. package/docs/api/player.mediacontrol.bindcontainerevents.md +0 -18
  143. package/docs/api/player.mediacontrol.bindevents.md +0 -18
  144. package/docs/api/player.mediacontrol.container.md +0 -14
  145. package/docs/api/player.mediacontrol.destroy.md +0 -18
  146. package/docs/api/player.mediacontrol.disabled.md +0 -14
  147. package/docs/api/player.mediacontrol.events.md +0 -40
  148. package/docs/api/player.mediacontrol.getexternalinterface.md +0 -21
  149. package/docs/api/player.mediacontrol.name.md +0 -14
  150. package/docs/api/player.mediacontrol.pause.md +0 -20
  151. package/docs/api/player.mediacontrol.play.md +0 -20
  152. package/docs/api/player.mediacontrol.playback.md +0 -14
  153. package/docs/api/player.mediacontrol.render.md +0 -18
  154. package/docs/api/player.mediacontrol.setmuted.md +0 -52
  155. package/docs/api/player.mediacontrol.stop.md +0 -20
  156. package/docs/api/player.mediacontrol.supportedversion.md +0 -16
  157. package/docs/api/player.poster.attributes.md +0 -14
  158. package/docs/api/player.poster.bindevents.md +0 -15
  159. package/docs/api/player.poster.destroy.md +0 -15
  160. package/docs/api/player.poster.events.md +0 -13
  161. package/docs/api/player.poster.name.md +0 -11
  162. package/docs/api/player.poster.render.md +0 -15
  163. package/docs/api/player.poster.shouldrender.md +0 -11
  164. package/docs/api/player.poster.showonvideoend.md +0 -11
  165. package/docs/api/player.poster.supportedversion.md +0 -13
  166. package/docs/api/player.poster.template.md +0 -11
  167. package/src/plugins/build.ts +0 -1
@@ -1,29 +1,48 @@
1
1
  import { Core, Events, Playback, UICorePlugin, template } from '@clappr/core';
2
+ import assert from 'assert';
2
3
 
3
- import { CLAPPR_VERSION } from '../build.js';
4
+ import { CLAPPR_VERSION } from '../../build.js';
4
5
 
5
6
  import dvrHTML from '../../../assets/dvr-controls/index.ejs';
6
7
  import '../../../assets/dvr-controls/dvr_controls.scss';
7
8
 
9
+ /**
10
+ * Adds the DVR controls to the media control UI
11
+ * @beta
12
+ *
13
+ * @remarks
14
+ * The plugin is rendered in the {@link MediaControl | media control} UI.
15
+ * It renders the live stream indicator and the DVR seek bar if DVR is enabled.
16
+ */
8
17
  export class DvrControls extends UICorePlugin {
9
- get template() {
10
- return template(dvrHTML);
11
- }
18
+ private static readonly template = template(dvrHTML);
12
19
 
20
+ /**
21
+ * @internal
22
+ */
13
23
  get name() {
14
- return 'dvr_controls';
24
+ return 'media_control_dvr';
15
25
  }
16
26
 
27
+ /**
28
+ * @internal
29
+ */
17
30
  get supportedVersion() {
18
31
  return { min: CLAPPR_VERSION };
19
32
  }
20
33
 
34
+ /**
35
+ * @internal
36
+ */
21
37
  override get events() {
22
38
  return {
23
39
  'click .live-button': 'click'
24
40
  };
25
41
  }
26
42
 
43
+ /**
44
+ * @internal
45
+ */
27
46
  override get attributes() {
28
47
  return {
29
48
  'class': 'dvr-controls',
@@ -36,6 +55,9 @@ export class DvrControls extends UICorePlugin {
36
55
  this.settingsUpdate();
37
56
  }
38
57
 
58
+ /**
59
+ * @internal
60
+ */
39
61
  override bindEvents() {
40
62
  this.bindCoreEvents();
41
63
  this.bindContainerEvents();
@@ -86,9 +108,9 @@ export class DvrControls extends UICorePlugin {
86
108
  }
87
109
  }
88
110
 
89
- click() {
90
- const mediaControl = this.core.mediaControl;
91
- const container = mediaControl.container;
111
+ private click() {
112
+ const mediaControl = this.core.getPlugin('media_control');
113
+ const container = this.core.activeContainer;
92
114
 
93
115
  if (!container.isPlaying()) {
94
116
  container.play();
@@ -99,9 +121,9 @@ export class DvrControls extends UICorePlugin {
99
121
  }
100
122
  }
101
123
 
102
- settingsUpdate() {
124
+ private settingsUpdate() {
103
125
  // @ts-ignore
104
- this.stopListening();
126
+ this.stopListening(); // TODO sort out
105
127
  this.core.mediaControl.$el.removeClass('live');
106
128
  if (this.shouldRender()) {
107
129
  this.render();
@@ -110,20 +132,26 @@ export class DvrControls extends UICorePlugin {
110
132
  this.bindEvents();
111
133
  }
112
134
 
113
- shouldRender() {
135
+ private shouldRender() {
114
136
  const useDvrControls = this.core.options.useDvrControls === undefined || !!this.core.options.useDvrControls;
115
137
 
116
138
  return useDvrControls && this.core.getPlaybackType() === Playback.LIVE;
117
139
  }
118
140
 
141
+ /**
142
+ * @internal
143
+ */
119
144
  override render() {
120
- this.$el.html(this.template({
145
+ this.$el.html(DvrControls.template({
121
146
  live: this.core.i18n.t('live'),
122
147
  backToLive: this.core.i18n.t('back_to_live')
123
148
  }));
124
149
  if (this.shouldRender()) {
125
- this.core.mediaControl.$el.addClass('live');
126
- this.core.mediaControl.$('.media-control-left-panel[data-media-control]').append(this.$el);
150
+ const mediaControl = this.core.mediaControl;
151
+ assert(mediaControl, 'media_control plugin is required');
152
+ // TODO don't tap into the $el directly
153
+ mediaControl.$el.addClass('live');
154
+ mediaControl.$('.media-control-left-panel[data-media-control]').append(this.$el);
127
155
  }
128
156
 
129
157
  return this;
@@ -1,7 +1,7 @@
1
1
  import { UICorePlugin, Events, template, PlayerError } from '@clappr/core';
2
2
  import { trace } from '@gcorevideo/utils';
3
3
 
4
- import { CLAPPR_VERSION } from '../build.js';
4
+ import { CLAPPR_VERSION } from '../../build.js';
5
5
  import type { TimerId, ZeptoResult } from '../../utils/types.js';
6
6
 
7
7
  import reloadIcon from '../../../assets/icons/old/reload.svg';
@@ -217,6 +217,7 @@ export class ErrorScreen extends UICorePlugin {
217
217
  if (err) {
218
218
  this.err = err;
219
219
  }
220
+ // TODO use container.disableMediaControl() instead
220
221
  this.core.mediaControl.disable();
221
222
  this.render();
222
223
  this.$el.show();
@@ -1,6 +1,6 @@
1
1
  import { CorePlugin, Events, $, Core, Container } from '@clappr/core';
2
2
 
3
- import { CLAPPR_VERSION } from '../build.js';
3
+ import { CLAPPR_VERSION } from '../../build.js';
4
4
  import { ZeptoResult } from '../../utils/types.js';
5
5
 
6
6
  import playIcon from '../../../assets/icons/new/play.svg';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { Container, ContainerPlugin, Events } from '@clappr/core';
6
6
 
7
- import { CLAPPR_VERSION } from '../build.js';
7
+ import { CLAPPR_VERSION } from '../../build.js';
8
8
 
9
9
  declare const _gaq: {
10
10
  push(args: string[]): void;
@@ -2,8 +2,9 @@ import { Events, template, UICorePlugin } from '@clappr/core'
2
2
  import { reportError, trace } from '@gcorevideo/utils'
3
3
 
4
4
  import { type QualityLevel } from '../../playback.types.js'
5
- import { CLAPPR_VERSION } from '../build.js'
5
+ import { CLAPPR_VERSION } from '../../build.js'
6
6
  import { ZeptoResult } from '../../utils/types.js'
7
+ import { TemplateFunction } from '../types.js'
7
8
 
8
9
  import buttonHtml from '../../../assets/level-selector/button.ejs'
9
10
  import listHtml from '../../../assets/level-selector/list.ejs'
@@ -14,32 +15,31 @@ import checkIcon from '../../../assets/icons/new/check.svg'
14
15
  import '../../../assets/level-selector/style.scss'
15
16
 
16
17
 
17
- const T = 'plugins.level_selector'
18
+ const T = 'plugins.media_control_level_selector'
18
19
  const VERSION = '2.19.4'
19
20
 
20
- type TemplateFunction = (data: Record<string, unknown>) => string
21
-
22
21
  /**
23
- * Allows to control the quality level of the playback.
22
+ * A {@link MediaControl | media control} plugin that provides a UI to control the quality level of the playback.
24
23
  * @beta
25
24
  *
26
25
  * @remarks
27
- * The plugin is rendered as a button in the gear menu.
26
+ * The plugin is rendered as a button in the {@link BottomGear | gear menu}.
28
27
  * When clicked, it shows a list of quality levels to choose from.
29
28
  *
30
29
  * Configuration options:
31
30
  *
32
- * - `labels`: The labels to show in the level selector. [vertical resolution]: string
31
+ * - `labels`: The labels to show in the level selector. [video resolution]: string
32
+ *
33
33
  * - `restrictResolution`: The maximum resolution to allow in the level selector.
34
34
  *
35
35
  * @example
36
36
  * ```ts
37
- * {
37
+ * new Player({
38
38
  * levelSelector: {
39
39
  * restrictResolution: 360,
40
- * labels: { 360: '360p', 720: '720p' },
40
+ * labels: { 360: 'SD', 720: 'HD' },
41
41
  * },
42
- * }
42
+ * })
43
43
  * ```
44
44
  */
45
45
  export class LevelSelector extends UICorePlugin {
@@ -57,18 +57,30 @@ export class LevelSelector extends UICorePlugin {
57
57
 
58
58
  private listTemplate: TemplateFunction | null = null
59
59
 
60
+ /**
61
+ * @internal
62
+ */
60
63
  get name() {
61
- return 'level_selector'
64
+ return 'media_control_level_selector'
62
65
  }
63
66
 
67
+ /**
68
+ * @internal
69
+ */
64
70
  get supportedVersion() {
65
71
  return { min: CLAPPR_VERSION }
66
72
  }
67
73
 
74
+ /**
75
+ * @internal
76
+ */
68
77
  static get version() {
69
78
  return VERSION
70
79
  }
71
80
 
81
+ /**
82
+ * @internal
83
+ */
72
84
  override get attributes() {
73
85
  return {
74
86
  class: this.name,
@@ -88,6 +100,9 @@ export class LevelSelector extends UICorePlugin {
88
100
  }
89
101
  }
90
102
 
103
+ /**
104
+ * @internal
105
+ */
91
106
  override bindEvents() {
92
107
  this.listenTo(this.core, Events.CORE_ACTIVE_CONTAINER_CHANGED, () => this.bindPlaybackEvents())
93
108
  this.listenTo(this.core, 'gear:rendered', this.render)
@@ -164,6 +179,9 @@ export class LevelSelector extends UICorePlugin {
164
179
  return !!(this.levels && this.levels.length > 1)
165
180
  }
166
181
 
182
+ /**
183
+ * @internal
184
+ */
167
185
  override render() {
168
186
  if (!this.shouldRender()) {
169
187
  return this
@@ -186,9 +204,10 @@ export class LevelSelector extends UICorePlugin {
186
204
  hdIcon,
187
205
  })
188
206
  this.$el.html(html)
189
- this.core.mediaControl.$el
207
+ const mediaControl = this.core.getPlugin('media_control')
208
+ mediaControl.getElement('bottomGear')
190
209
  ?.find('.gear-options-list [data-quality]')
191
- .html(this.el)
210
+ ?.html(this.el)
192
211
  }
193
212
  }
194
213
 
@@ -205,7 +224,8 @@ export class LevelSelector extends UICorePlugin {
205
224
  removeAuto: this.removeAuto,
206
225
  })
207
226
  this.$el.html(html)
208
- this.core.mediaControl.$el?.find('.gear-wrapper').html(this.el)
227
+ const mediaControl = this.core.getPlugin('media_control')
228
+ mediaControl.getElement('bottomGear')?.find('.gear-wrapper').html(this.el)
209
229
  }
210
230
 
211
231
  private get maxLevel() {
@@ -43,6 +43,7 @@ describe('LevelSelector', () => {
43
43
  beforeEach(() => {
44
44
  const activeContainer = createContainer()
45
45
  activePlayback = createPlayback()
46
+ let mediaControl: UICorePlugin | null = null
46
47
  core = Object.assign(new EventLite(), {
47
48
  activeContainer,
48
49
  activePlayback,
@@ -52,8 +53,14 @@ describe('LevelSelector', () => {
52
53
  labels: { 360: '360p', 720: 'HD' },
53
54
  },
54
55
  },
56
+ getPlugin: vi.fn().mockImplementation((name: string) => {
57
+ if (name === 'media_control') {
58
+ return mediaControl
59
+ }
60
+ return null
61
+ }),
55
62
  })
56
- core.mediaControl = new UICorePlugin(core)
63
+ mediaControl = createMediaControl(core)
57
64
  levelSelector = new LevelSelector(core)
58
65
  })
59
66
  describe('initially', () => {
@@ -110,6 +117,7 @@ describe('LevelSelector', () => {
110
117
  beforeEach(() => {
111
118
  const activeContainer = createContainer()
112
119
  activePlayback = createPlayback()
120
+ let mediaControl: UICorePlugin | null = null
113
121
  core = Object.assign(new EventLite(), {
114
122
  activeContainer,
115
123
  activePlayback,
@@ -119,8 +127,14 @@ describe('LevelSelector', () => {
119
127
  labels: { 360: '360p', 720: '720p' },
120
128
  },
121
129
  },
130
+ getPlugin: vi.fn().mockImplementation((name: string) => {
131
+ if (name === 'media_control') {
132
+ return mediaControl
133
+ }
134
+ return null
135
+ }),
122
136
  })
123
- core.mediaControl = new UICorePlugin(core)
137
+ mediaControl = createMediaControl(core)
124
138
  levelSelector = new LevelSelector(core)
125
139
  })
126
140
  describe('basically', () => {
@@ -218,3 +232,9 @@ expect.extend({
218
232
  }
219
233
  }
220
234
  })
235
+
236
+ function createMediaControl(core: any) {
237
+ const mediaControl = new UICorePlugin(core)
238
+ mediaControl.getElement = vi.fn().mockReturnValue(null)
239
+ return mediaControl
240
+ }
@@ -1,6 +1,6 @@
1
1
  import { UIContainerPlugin, Events, template as t, Container } from '@clappr/core';
2
2
 
3
- import { CLAPPR_VERSION } from '../build.js';
3
+ import { CLAPPR_VERSION } from '../../build.js';
4
4
  import { calculateSize } from './utils/index.js';
5
5
  import { ZeptoResult } from '../../utils/types.js';
6
6
 
@@ -13,12 +13,12 @@ import {
13
13
  $,
14
14
  Core,
15
15
  } from '@clappr/core'
16
- import { reportError } from '@gcorevideo/utils';
16
+ import { reportError } from '@gcorevideo/utils'
17
17
  import { type TimeProgress } from '../../playback.types.js'
18
18
 
19
19
  import { Kibo } from '../kibo/index.js'
20
20
 
21
- import { CLAPPR_VERSION } from '../build.js'
21
+ import { CLAPPR_VERSION } from '../../build.js'
22
22
  import { ZeptoResult } from '../../utils/types.js'
23
23
  import { getPageX, isFullscreen } from '../utils.js'
24
24
 
@@ -35,9 +35,15 @@ import fullscreenOffIcon from '../../../assets/icons/new/fullscreen-off.svg'
35
35
  import fullscreenOnIcon from '../../../assets/icons/new/fullscreen-on.svg'
36
36
 
37
37
  /**
38
+ * Media control elements, mount points for additional plugins
38
39
  * @beta
39
40
  */
40
- export type MediaControlElement = 'clipText' | 'pip' | 'seekBarContainer'
41
+ export type MediaControlElement =
42
+ | 'bottomGear'
43
+ | 'clipText'
44
+ | 'pip'
45
+ | 'playbackRate'
46
+ | 'seekBarContainer'
41
47
 
42
48
  const T = 'plugins.media_control'
43
49
 
@@ -67,11 +73,17 @@ type DisabledClickable = {
67
73
  }
68
74
 
69
75
  /**
70
- * The MediaControl is responsible for displaying the Player controls.
76
+ * The MediaControl provides a foundation for developing custom media controls UI.
71
77
  * @beta
72
78
  * @remarks
73
- * This plugin provides a foundation for developing a media controls UI via additional plugins.
74
79
  * The methods exposed are to be used by the other plugins that extend the media control UI.
80
+ * The plugin registration should be arranged so that MediaControl is initialized before every other plugin that depends on it.
81
+ * @example
82
+ * ```ts
83
+ * Player.registerPlugin(MediaControl) // <--- This must go first
84
+ * Player.registerPlugin(LevelSelector) // a media control plugin
85
+ * Player.registerPlugin(NerdStats) // another media control plugin
86
+ * ```
75
87
  */
76
88
  export class MediaControl extends UICorePlugin {
77
89
  private advertisementPlaying = false
@@ -112,8 +124,6 @@ export class MediaControl extends UICorePlugin {
112
124
 
113
125
  private settings: Record<string, unknown> = {}
114
126
 
115
- private svgMask: ZeptoResult | null = null
116
-
117
127
  private userDisabled = false
118
128
 
119
129
  private userKeepVisible = false
@@ -170,29 +180,46 @@ export class MediaControl extends UICorePlugin {
170
180
 
171
181
  private static readonly template = template(mediaControlHTML)
172
182
 
183
+ /**
184
+ * @internal
185
+ */
173
186
  get name() {
174
187
  return 'media_control'
175
188
  }
176
189
 
190
+ /**
191
+ * @internal
192
+ */
177
193
  get supportedVersion() {
178
194
  return { min: CLAPPR_VERSION }
179
195
  }
180
196
 
181
- get disabled() {
197
+ private get disabled() {
182
198
  const playbackIsNOOP =
183
199
  this.container && this.container.getPlaybackType() === Playback.NO_OP
184
200
 
185
201
  return this.userDisabled || playbackIsNOOP
186
202
  }
187
203
 
204
+ /**
205
+ * @internal
206
+ * @deprecated
207
+ */
188
208
  get container() {
189
209
  return this.core && this.core.activeContainer
190
210
  }
191
211
 
212
+ /**
213
+ * @internal
214
+ * @deprecated
215
+ */
192
216
  get playback() {
193
217
  return this.core && this.core.activePlayback
194
218
  }
195
219
 
220
+ /**
221
+ * @internal
222
+ */
196
223
  override get attributes() {
197
224
  return {
198
225
  class: 'media-control-skin-1',
@@ -200,6 +227,9 @@ export class MediaControl extends UICorePlugin {
200
227
  }
201
228
  }
202
229
 
230
+ /**
231
+ * @internal
232
+ */
203
233
  override get events() {
204
234
  return {
205
235
  'click [data-play]': 'play',
@@ -231,11 +261,11 @@ export class MediaControl extends UICorePlugin {
231
261
  }
232
262
 
233
263
  /**
234
- * Current volume
264
+ * Current volume [0..100]
235
265
  */
236
- get volume() {
237
- return this.container && this.container.isReady
238
- ? this.container.volume
266
+ get volume(): number {
267
+ return this.core.activeContainer.isReady
268
+ ? this.core.activeContainer.volume
239
269
  : this.intendedVolume
240
270
  }
241
271
 
@@ -256,7 +286,7 @@ export class MediaControl extends UICorePlugin {
256
286
 
257
287
  this.userDisabled = false
258
288
  if (
259
- (this.container && this.container.mediaControlDisabled) ||
289
+ this.core.activeContainer.mediaControlDisabled ||
260
290
  this.options.chromeless
261
291
  ) {
262
292
  this.disable()
@@ -269,6 +299,9 @@ export class MediaControl extends UICorePlugin {
269
299
  $(document).bind('touchmove', this.updateDrag)
270
300
  }
271
301
 
302
+ /**
303
+ * @internal
304
+ */
272
305
  override getExternalInterface() {
273
306
  return {
274
307
  setVolume: this.setVolume,
@@ -276,6 +309,9 @@ export class MediaControl extends UICorePlugin {
276
309
  }
277
310
  }
278
311
 
312
+ /**
313
+ * @internal
314
+ */
279
315
  override bindEvents() {
280
316
  // @ts-ignore
281
317
  this.stopListening()
@@ -318,7 +354,7 @@ export class MediaControl extends UICorePlugin {
318
354
  // }
319
355
  }
320
356
 
321
- bindContainerEvents() {
357
+ private bindContainerEvents() {
322
358
  if (!this.container) {
323
359
  return
324
360
  }
@@ -382,6 +418,9 @@ export class MediaControl extends UICorePlugin {
382
418
  }
383
419
  }
384
420
 
421
+ /**
422
+ * Disables the plugin and unmounts its UI
423
+ */
385
424
  override disable() {
386
425
  this.userDisabled = true
387
426
  this.hide()
@@ -389,6 +428,9 @@ export class MediaControl extends UICorePlugin {
389
428
  this.$el.hide()
390
429
  }
391
430
 
431
+ /**
432
+ * Reenables the plugin disabled earlier with the {@link MediaControl.disable} method
433
+ */
392
434
  override enable() {
393
435
  if (this.options.chromeless) {
394
436
  return
@@ -398,27 +440,6 @@ export class MediaControl extends UICorePlugin {
398
440
  this.show()
399
441
  }
400
442
 
401
- /**
402
- * Start the playback
403
- */
404
- play() {
405
- this.container && this.container.play()
406
- }
407
-
408
- /**
409
- * Pause the playback
410
- */
411
- pause() {
412
- this.container && this.container.pause()
413
- }
414
-
415
- /**
416
- * Stop the playback
417
- */
418
- stop() {
419
- this.container && this.container.stop()
420
- }
421
-
422
443
  /**
423
444
  * Set the initial volume, which is preserved when playback is interrupted by an advertisement
424
445
  */
@@ -1053,14 +1074,31 @@ export class MediaControl extends UICorePlugin {
1053
1074
  /**
1054
1075
  * Get a media control element DOM node
1055
1076
  * @param name - The name of the media control element
1056
- * @returns The DOM node to render the media control element
1077
+ * @returns The DOM node to render to or extend
1078
+ * @remarks
1079
+ * Use this method to render custom media control UI in a plugin
1080
+ * @example
1081
+ * ```ts
1082
+ * class MyPlugin extends UICorePlugin {
1083
+ * override render() {
1084
+ * const mediaControl = this.core.getPlugin('media_control')
1085
+ * const clipText = mediaControl.getElement('clipText')
1086
+ * clipText?.el.text('Here we go')
1087
+ * return this
1088
+ * }
1089
+ * }
1090
+ * ```
1057
1091
  */
1058
1092
  getElement(name: MediaControlElement): ZeptoResult | null {
1059
1093
  switch (name) {
1060
1094
  case 'clipText':
1061
1095
  return this.$clipText
1096
+ case 'bottomGear':
1097
+ return this.$bottomGear
1062
1098
  case 'pip':
1063
1099
  return this.$pip
1100
+ case 'playbackRate':
1101
+ return this.$playbackRate
1064
1102
  case 'seekBarContainer':
1065
1103
  return this.$seekBarContainer
1066
1104
  }
@@ -1223,6 +1261,9 @@ export class MediaControl extends UICorePlugin {
1223
1261
  $(element).find('svg path').css({ fill: this.buttonsColor })
1224
1262
  }
1225
1263
 
1264
+ /**
1265
+ * @internal
1266
+ */
1226
1267
  override destroy() {
1227
1268
  $(document).unbind('mouseup', this.stopDrag)
1228
1269
  $(document).unbind('mousemove', this.updateDrag)
@@ -1237,6 +1278,9 @@ export class MediaControl extends UICorePlugin {
1237
1278
  this.trigger(Events.MEDIACONTROL_OPTIONS_CHANGE)
1238
1279
  }
1239
1280
 
1281
+ /**
1282
+ * @internal
1283
+ */
1240
1284
  override render() {
1241
1285
  const timeout = this.options.hideMediaControlDelay || 2000
1242
1286
 
@@ -1343,11 +1387,6 @@ export class MediaControl extends UICorePlugin {
1343
1387
  }
1344
1388
  }
1345
1389
 
1346
- // TODO
1347
- setMuted(value: boolean) {
1348
- this.container.options.mute = value
1349
- }
1350
-
1351
1390
  private static getPageX(event: MouseEvent | TouchEvent): number {
1352
1391
  return getPageX(event)
1353
1392
  }
@@ -1367,7 +1406,7 @@ export class MediaControl extends UICorePlugin {
1367
1406
  }
1368
1407
 
1369
1408
  /**
1370
- * Enable the control button
1409
+ * Enable the user interaction disabled earlier
1371
1410
  */
1372
1411
  enableControlButton() {
1373
1412
  this.disabledClickableList.forEach((element) => {
@@ -1376,7 +1415,7 @@ export class MediaControl extends UICorePlugin {
1376
1415
  }
1377
1416
 
1378
1417
  /**
1379
- * Disable the control button
1418
+ * Disable the user interaction for the control buttons
1380
1419
  */
1381
1420
  disabledControlButton() {
1382
1421
  this.disabledClickableList.forEach((element) => {
@@ -1393,7 +1432,6 @@ export class MediaControl extends UICorePlugin {
1393
1432
  }
1394
1433
  }
1395
1434
 
1396
- // TODO drop?
1397
1435
  MediaControl.extend = function (properties) {
1398
1436
  return extend(MediaControl, properties)
1399
1437
  }
@@ -1,7 +1,7 @@
1
1
  import { Browser, Core, Events, Playback, template, UICorePlugin } from '@clappr/core';
2
2
  import { reportError, trace } from '@gcorevideo/utils';
3
3
 
4
- import { CLAPPR_VERSION } from '../build.js';
4
+ import { CLAPPR_VERSION } from '../../build.js';
5
5
 
6
6
  import pluginHtml from '../../../assets/multi-camera/multicamera.ejs';
7
7
  import '../../../assets/multi-camera/style.scss';
@@ -23,7 +23,7 @@ type MediaSourceInfo = {
23
23
 
24
24
  const VERSION = '0.0.1';
25
25
 
26
- const T = 'plugins.multicamera';
26
+ const T = 'plugins.media_control_multicamera';
27
27
 
28
28
  export class MultiCamera extends UICorePlugin {
29
29
  private currentCamera: MediaSourceInfo | null = null;
@@ -37,7 +37,7 @@ export class MultiCamera extends UICorePlugin {
37
37
  private noActiveStreams = false;
38
38
 
39
39
  get name() {
40
- return 'multicamera';
40
+ return 'media_control_multicamera';
41
41
  }
42
42
 
43
43
  get supportedVersion() {