@gcorevideo/player 2.22.18 → 2.22.21

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 (94) hide show
  1. package/assets/audio-selector/track-selector.ejs +3 -3
  2. package/assets/bottom-gear/bottomgear.ejs +3 -3
  3. package/assets/dvr-controls/dvr_controls.scss +0 -12
  4. package/assets/level-selector/button.ejs +1 -1
  5. package/dist/core.js +1 -1
  6. package/dist/index.css +664 -671
  7. package/dist/index.js +285 -260
  8. package/dist/player.d.ts +144 -123
  9. package/dist/plugins/index.css +758 -765
  10. package/dist/plugins/index.js +194 -172
  11. package/docs/api/player.clapprstats.exportmetrics.md +2 -2
  12. package/docs/api/player.clapprstats.md +0 -4
  13. package/docs/api/player.clapprstatsbitratetrack.md +20 -0
  14. package/docs/api/player.clapprstatschronograph.md +115 -0
  15. package/docs/api/player.clapprstatscounter.md +211 -0
  16. package/docs/api/player.clapprstatsevents.md +51 -0
  17. package/docs/api/player.clapprstatsmetrics.md +52 -0
  18. package/docs/api/player.clipspluginsettings.md +1 -1
  19. package/docs/api/player.gearevents.md +1 -1
  20. package/docs/api/player.md +57 -2
  21. package/docs/api/player.mediacontrol.mount.md +0 -5
  22. package/docs/api/player.mediacontrol.putelement.md +5 -0
  23. package/docs/api/player.mediacontrol.toggleelement.md +1 -1
  24. package/docs/api/player.nerdstats.md +3 -3
  25. package/docs/api/player.playerconfig.md +1 -1
  26. package/docs/api/player.playerconfig.playbacktype.md +6 -1
  27. package/docs/api/player.timeupdate.md +6 -3
  28. package/lib/plugins/audio-selector/AudioSelector.d.ts +1 -1
  29. package/lib/plugins/audio-selector/AudioSelector.d.ts.map +1 -1
  30. package/lib/plugins/audio-selector/AudioSelector.js +15 -8
  31. package/lib/plugins/bottom-gear/BottomGear.d.ts +1 -1
  32. package/lib/plugins/bottom-gear/BottomGear.js +2 -2
  33. package/lib/plugins/clappr-nerd-stats/NerdStats.d.ts +4 -4
  34. package/lib/plugins/clappr-nerd-stats/NerdStats.js +4 -4
  35. package/lib/plugins/clappr-stats/ClapprStats.d.ts +5 -2
  36. package/lib/plugins/clappr-stats/ClapprStats.d.ts.map +1 -1
  37. package/lib/plugins/clappr-stats/ClapprStats.js +31 -33
  38. package/lib/plugins/clappr-stats/types.d.ts +21 -21
  39. package/lib/plugins/clappr-stats/types.d.ts.map +1 -1
  40. package/lib/plugins/clappr-stats/types.js +22 -22
  41. package/lib/plugins/clappr-stats/utils.d.ts +2 -2
  42. package/lib/plugins/clappr-stats/utils.d.ts.map +1 -1
  43. package/lib/plugins/click-to-pause/ClickToPause.js +1 -1
  44. package/lib/plugins/clips/Clips.d.ts +1 -1
  45. package/lib/plugins/dvr-controls/DvrControls.d.ts +6 -2
  46. package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
  47. package/lib/plugins/dvr-controls/DvrControls.js +39 -27
  48. package/lib/plugins/media-control/MediaControl.d.ts +9 -2
  49. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  50. package/lib/plugins/media-control/MediaControl.js +26 -10
  51. package/lib/plugins/picture-in-picture/PictureInPicture.js +1 -1
  52. package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
  53. package/lib/plugins/vast-ads/VastAds.js +1 -1
  54. package/lib/plugins/vast-ads/rollmanager.js +1 -1
  55. package/lib/plugins/volume-fade/VolumeFade.d.ts +25 -10
  56. package/lib/plugins/volume-fade/VolumeFade.d.ts.map +1 -1
  57. package/lib/plugins/volume-fade/VolumeFade.js +62 -60
  58. package/lib/testUtils.d.ts.map +1 -1
  59. package/lib/testUtils.js +7 -4
  60. package/lib/types.d.ts +1 -1
  61. package/package.json +3 -3
  62. package/src/playback/__tests__/HTML5Video.test.ts +2 -2
  63. package/src/plugins/audio-selector/AudioSelector.ts +14 -7
  64. package/src/plugins/audio-selector/__tests__/AudioSelector.test.ts +8 -8
  65. package/src/plugins/audio-selector/__tests__/__snapshots__/AudioSelector.test.ts.snap +15 -15
  66. package/src/plugins/bottom-gear/BottomGear.ts +2 -2
  67. package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +8 -5
  68. package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +3 -3
  69. package/src/plugins/clappr-nerd-stats/NerdStats.ts +5 -5
  70. package/src/plugins/clappr-stats/ClapprStats.ts +41 -40
  71. package/src/plugins/clappr-stats/__tests__/ClapprStats.test.ts +12 -12
  72. package/src/plugins/clappr-stats/types.ts +21 -21
  73. package/src/plugins/clappr-stats/utils.ts +2 -2
  74. package/src/plugins/click-to-pause/ClickToPause.ts +1 -1
  75. package/src/plugins/clips/Clips.ts +1 -1
  76. package/src/plugins/clips/__tests__/Clips.test.ts +1 -1
  77. package/src/plugins/clips/__tests__/__snapshots__/Clips.test.ts.snap +1 -1
  78. package/src/plugins/dvr-controls/DvrControls.ts +51 -37
  79. package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +84 -26
  80. package/src/plugins/dvr-controls/__tests__/__snapshots__/DvrControls.test.ts.snap +0 -12
  81. package/src/plugins/level-selector/__tests__/__snapshots__/QualityLevels.test.ts.snap +1 -1
  82. package/src/plugins/media-control/MediaControl.ts +27 -10
  83. package/src/plugins/media-control/__tests__/MediaControl.test.ts +8 -5
  84. package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +20 -20
  85. package/src/plugins/picture-in-picture/PictureInPicture.ts +1 -1
  86. package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
  87. package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
  88. package/src/plugins/vast-ads/VastAds.ts +1 -1
  89. package/src/plugins/vast-ads/rollmanager.ts +1 -1
  90. package/src/plugins/volume-fade/VolumeFade.ts +92 -75
  91. package/src/testUtils.ts +11 -5
  92. package/src/types.ts +1 -1
  93. package/temp/player.api.json +634 -16
  94. package/tsconfig.tsbuildinfo +1 -1
@@ -1,6 +1,6 @@
1
- import type { Metrics } from './types'
1
+ import type { ClapprStatsMetrics } from './types'
2
2
 
3
- export function newMetrics(): Metrics {
3
+ export function newMetrics(): ClapprStatsMetrics {
4
4
  return {
5
5
  counters: {
6
6
  play: 0,
@@ -25,7 +25,7 @@ export class ClickToPause extends ContainerPlugin {
25
25
  * @internal
26
26
  */
27
27
  get name() {
28
- return 'click_to_pause_custom'
28
+ return 'click_to_pause'
29
29
  }
30
30
 
31
31
  /**
@@ -12,7 +12,7 @@ import clipsHTML from '../../../assets/clips/clips.ejs'
12
12
  const T = 'plugins.clips'
13
13
 
14
14
  /**
15
- * Configuration options for the {@link ClipsPlugin} plugin.
15
+ * Configuration options for the {@link Clips} plugin.
16
16
  * @beta
17
17
  */
18
18
  export interface ClipsPluginSettings {
@@ -8,7 +8,7 @@ import { Events } from '@clappr/core'
8
8
  // Logger.enable('*')
9
9
  // setTracer(new LogTracer('Clips.text'))
10
10
 
11
- describe('ClipsPlugin', () => {
11
+ describe('Clips', () => {
12
12
  let core: any
13
13
  let mediaControl: any
14
14
  let clips: Clips
@@ -1,6 +1,6 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`ClipsPlugin > should render indicator 1`] = `
3
+ exports[`Clips > should render indicator 1`] = `
4
4
  "<div class="media-clip-text" id="clips-text">Introduction</div><svg width="0" height="0">
5
5
  <defs>
6
6
  <clipPath id="myClip">
@@ -1,14 +1,14 @@
1
- import { Core, Events, Playback, UICorePlugin, template } from '@clappr/core'
1
+ import { Events, Playback, UICorePlugin, template } from '@clappr/core'
2
2
  import assert from 'assert'
3
3
 
4
4
  import { CLAPPR_VERSION } from '../../build.js'
5
5
 
6
6
  import dvrHTML from '../../../assets/dvr-controls/index.ejs'
7
7
  import '../../../assets/dvr-controls/dvr_controls.scss'
8
- import { trace } from '@gcorevideo/utils'
8
+ // import { trace } from '@gcorevideo/utils'
9
9
  import { MediaControl } from '../media-control/MediaControl.js'
10
10
 
11
- const T = 'plugins.dvr_controls'
11
+ // const T = 'plugins.dvr_controls'
12
12
 
13
13
  /**
14
14
  * `PLUGIN` that adds the DVR controls to the media control UI
@@ -63,11 +63,11 @@ export class DvrControls extends UICorePlugin {
63
63
  * @internal
64
64
  */
65
65
  override bindEvents() {
66
- this.listenTo(this.core, Events.CORE_READY, this.onCoreReady)
66
+ this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady)
67
67
  this.listenTo(
68
68
  this.core,
69
69
  Events.CORE_ACTIVE_CONTAINER_CHANGED,
70
- this.bindContainerEvents,
70
+ this.onActiveContainerChanged,
71
71
  )
72
72
  }
73
73
 
@@ -75,21 +75,19 @@ export class DvrControls extends UICorePlugin {
75
75
  const mediaControl = this.core.getPlugin('media_control')
76
76
  assert(mediaControl, 'media_control plugin is required')
77
77
 
78
- this.listenTo(
79
- mediaControl,
80
- Events.MEDIACONTROL_RENDERED,
81
- this.render,
82
- )
83
- // MediaControl has been rendered
84
- this.render()
78
+ this.listenTo(mediaControl, Events.MEDIACONTROL_RENDERED, this.mount)
85
79
  }
86
80
 
87
- private bindContainerEvents() {
88
- trace(`${T} bindContainerEvents`)
89
- this.listenToOnce(
81
+ private onActiveContainerChanged() {
82
+ this.listenTo(
90
83
  this.core.activeContainer,
91
- Events.CONTAINER_TIMEUPDATE,
92
- this.render,
84
+ Events.CONTAINER_LOADEDMETADATA,
85
+ this.onMetadataLoaded,
86
+ )
87
+ this.listenTo(
88
+ this.core.activeContainer,
89
+ Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
90
+ this.onDvrStateChanged,
93
91
  )
94
92
  }
95
93
 
@@ -101,36 +99,52 @@ export class DvrControls extends UICorePlugin {
101
99
  container.seek(container.getDuration())
102
100
  }
103
101
 
104
- private shouldRender() {
105
- return this.core.getPlaybackType() === Playback.LIVE
106
- }
107
-
108
102
  /**
109
103
  * @internal
110
104
  */
111
105
  override render() {
112
- trace(`${T} render`, {
113
- dvrEnabled: this.core.activePlayback?.dvrEnabled,
114
- playbackType: this.core.getPlaybackType(),
115
- })
116
- const mediaControl = this.core.getPlugin('media_control') as MediaControl
117
- if (!mediaControl) {
118
- return this
119
- }
120
- if (!this.shouldRender()) {
121
- return this
122
- }
123
-
124
- mediaControl.toggleElement('duration', false)
125
- mediaControl.toggleElement('position', false)
126
-
127
106
  this.$el.html(
128
107
  DvrControls.template({
129
108
  i18n: this.core.i18n,
130
109
  }),
131
110
  )
132
- mediaControl.putElement('dvr', this.$el)
133
111
 
134
112
  return this
135
113
  }
114
+
115
+ private onMediacontrolRendered() {
116
+ this.render()
117
+ }
118
+
119
+ private onMetadataLoaded() {
120
+ this.mount()
121
+ this.toggleState(this.core.activeContainer.isDvrInUse())
122
+ }
123
+
124
+ private mount() {
125
+ // TODO move mount point management logic to MediaControl
126
+ if (this.core.getPlaybackType() !== Playback.LIVE) {
127
+ return
128
+ }
129
+ const mediaControl = this.core.getPlugin('media_control') as MediaControl
130
+ assert(mediaControl, 'media_control plugin is required')
131
+ // TODO -> to MediaControl
132
+ mediaControl.toggleElement('duration', false)
133
+ mediaControl.toggleElement('position', false)
134
+ mediaControl.mount('dvr', this.$el)
135
+ }
136
+
137
+ private onDvrStateChanged(dvrInUse: boolean) {
138
+ this.toggleState(dvrInUse)
139
+ }
140
+
141
+ private toggleState(dvrInUse: boolean) {
142
+ if (dvrInUse) {
143
+ this.$el.find('#media-control-back-to-live').show()
144
+ this.$el.find('#media-control-live').hide()
145
+ } else {
146
+ this.$el.find('#media-control-back-to-live').hide()
147
+ this.$el.find('#media-control-live').show()
148
+ }
149
+ }
136
150
  }
@@ -20,11 +20,30 @@ describe('DvrControls', () => {
20
20
  }
21
21
  core.getPlugin.mockImplementation((name: string) => plugins[name])
22
22
  dvrControls = new DvrControls(core)
23
- plugins.dvr_controls = dvrControls
23
+ core.emit(Events.CORE_READY)
24
+ mediaControl.trigger(Events.MEDIACONTROL_RENDERED)
25
+ core.trigger(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
26
+ })
27
+ describe('basically', () => {
28
+ it('should render', () => {
29
+ expect(dvrControls.el.innerHTML).toMatchSnapshot()
30
+ expect(dvrControls.el.textContent).toMatch(/\blive\b/)
31
+ expect(dvrControls.el.textContent).toMatch(/\bback_to_live\b/)
32
+ })
33
+ })
34
+ describe('while playback type is unknown', () => {
35
+ it('should not mount', () => {
36
+ expect(mediaControl.mount).not.toHaveBeenCalledWith(
37
+ 'dvr',
38
+ dvrControls.$el,
39
+ )
40
+ })
24
41
  })
25
42
  describe('live stream', () => {
26
43
  beforeEach(() => {
27
44
  core.getPlaybackType.mockReturnValue('live')
45
+ core.activeContainer.getPlaybackType.mockReturnValue('live')
46
+ core.activePlayback.getPlaybackType.mockReturnValue('live')
28
47
  })
29
48
  describe.each([
30
49
  ['no DVR', false, false, false],
@@ -33,36 +52,75 @@ describe('DvrControls', () => {
33
52
  beforeEach(() => {
34
53
  core.activePlayback.dvrEnabled = dvrEnabled
35
54
  core.activeContainer.isDvrEnabled.mockReturnValue(dvrEnabled)
36
- core.trigger(Events.CORE_READY)
37
- core.trigger(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
55
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
56
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
38
57
  if (dvrInUse) {
39
58
  core.activePlayback.dvrInUse = true
40
59
  core.activeContainer.isDvrInUse.mockReturnValue(true)
41
- core.activeContainer.emit(Events.CONTAINER_PLAYBACKDVRSTATECHANGED, true)
60
+ core.activeContainer.emit(
61
+ Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
62
+ true,
63
+ )
42
64
  }
43
65
  })
44
- it('should render', () => {
45
- expect(dvrControls.el.textContent).toBeTruthy()
46
- expect(dvrControls.el.innerHTML).toMatchSnapshot()
47
- })
66
+ // TODO let the media control itself handle this
48
67
  it('should hide duration and position indicators', () => {
49
- expect(mediaControl.toggleElement).toHaveBeenCalledWith('duration', false)
50
- expect(mediaControl.toggleElement).toHaveBeenCalledWith('position', false)
68
+ expect(mediaControl.toggleElement).toHaveBeenCalledWith(
69
+ 'duration',
70
+ false,
71
+ )
72
+ expect(mediaControl.toggleElement).toHaveBeenCalledWith(
73
+ 'position',
74
+ false,
75
+ )
51
76
  })
52
- it('should render to the media control', () => {
53
- expect(mediaControl.putElement).toHaveBeenCalledWith('dvr', dvrControls.$el)
77
+ it('should mount to the media control', () => {
78
+ expect(mediaControl.mount).toHaveBeenCalledWith('dvr', dvrControls.$el)
54
79
  })
80
+ if (dvrEnabled) {
81
+ if (dvrInUse) {
82
+ it('should show back_to_live button', () => {
83
+ expect(
84
+ dvrControls.$el
85
+ .find('#media-control-back-to-live')
86
+ .css('display'),
87
+ ).not.toBe('none')
88
+ })
89
+ it('should hide live inficator', () => {
90
+ expect(
91
+ dvrControls.$el.find('#media-control-live').css('display'),
92
+ ).toBe('none')
93
+ })
94
+ } else {
95
+ it('should show live inficator', () => {
96
+ expect(
97
+ dvrControls.$el.find('#media-control-live').css('display'),
98
+ ).not.toBe('none')
99
+ })
100
+ it('should hide back_to_live button', () => {
101
+ expect(
102
+ dvrControls.$el
103
+ .find('#media-control-back-to-live')
104
+ .css('display'),
105
+ ).toBe('none')
106
+ })
107
+ }
108
+ }
55
109
  })
56
110
  describe('when back_to_live button is clicked', () => {
57
111
  beforeEach(() => {
58
112
  core.activePlayback.dvrEnabled = true
59
- core.trigger('core:ready')
60
- core.trigger('core:active:container:changed')
113
+ core.activeContainer.isDvrEnabled.mockReturnValue(true)
114
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
115
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
61
116
  core.activeContainer.getDuration.mockReturnValue(180)
62
- core.activeContainer.trigger('container:dvr', true)
63
- dvrControls.$el.find('.live-button').click()
117
+ core.activeContainer.emit(
118
+ Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
119
+ true,
120
+ )
121
+ dvrControls.$el.find('#media-control-back-to-live').click()
64
122
  })
65
- it('should call active container play', () => {
123
+ it('should play stream', () => {
66
124
  expect(core.activeContainer.play).toHaveBeenCalled()
67
125
  })
68
126
  it('should seek to live edge', () => {
@@ -70,20 +128,20 @@ describe('DvrControls', () => {
70
128
  })
71
129
  })
72
130
  })
73
- describe('basically', () => {
131
+ describe('VOD stream', () => {
74
132
  beforeEach(() => {
75
133
  core.getPlaybackType.mockReturnValue(Playback.VOD)
76
134
  core.activeContainer.getPlaybackType.mockReturnValue(Playback.VOD)
77
135
  core.activePlayback.getPlaybackType.mockReturnValue(Playback.VOD)
136
+ core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
137
+ core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
78
138
  })
79
- beforeEach(() => {
80
- core.trigger(Events.CORE_READY)
81
- core.trigger(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
82
- })
83
- it('should render', () => {
84
- expect(dvrControls.el.innerHTML).toMatchSnapshot()
85
- expect(dvrControls.el.textContent).toContain('live')
86
- expect(dvrControls.el.textContent).toContain('back_to_live')
139
+ // TODO handle mount points in MediaControl
140
+ it('should not mount', () => {
141
+ expect(mediaControl.mount).not.toHaveBeenCalledWith(
142
+ 'dvr',
143
+ expect.anything(),
144
+ )
87
145
  })
88
146
  })
89
147
  })
@@ -5,15 +5,3 @@ exports[`DvrControls > basically > should render 1`] = `
5
5
  <button type="button" class="live-button" aria-label="back_to_live" id="media-control-back-to-live">back_to_live</button>
6
6
  "
7
7
  `;
8
-
9
- exports[`DvrControls > live stream > DVR at live edge > should render 1`] = `
10
- "<div class="live-info" id="media-control-live">live</div>
11
- <button type="button" class="live-button" aria-label="back_to_live" id="media-control-back-to-live">back_to_live</button>
12
- "
13
- `;
14
-
15
- exports[`DvrControls > live stream > no DVR > should render 1`] = `
16
- "<div class="live-info" id="media-control-live">live</div>
17
- <button type="button" class="live-button" aria-label="back_to_live" id="media-control-back-to-live">back_to_live</button>
18
- "
19
- `;
@@ -154,7 +154,7 @@ exports[`QualityLevels > options.restrictResolution > given vertical video forma
154
154
  `;
155
155
 
156
156
  exports[`QualityLevels > options.restrictResolution > initially > should render the restricted quality level label 1`] = `
157
- "<button class="gplayer-lite-btn gcore-skin-text-color gear-option" aria-haspopup="menu">
157
+ "<button class="gplayer-lite-btn gcore-skin-text-color gear-option" aria-haspopup="menu" id="quality-levels">
158
158
  <span class="gear-option_icon hidden">/assets/icons/new/hd.svg</span>
159
159
  <span class="gear-option_label">quality</span>
160
160
  <span class="gear-option_value">360p</span>
@@ -81,6 +81,16 @@ export type MediaControlElement =
81
81
  | MediaControlLayerElement
82
82
  | MediaControlRightElement
83
83
 
84
+ const MANAGED_ELEMENTS: MediaControlElement[] = [
85
+ 'dvr',
86
+ 'duration',
87
+ 'fullscreen',
88
+ 'hd-indicator',
89
+ 'position',
90
+ 'seekbar',
91
+ 'volume',
92
+ ]
93
+
84
94
  /**
85
95
  * Specifies the allowed media control elements in each area.
86
96
  * Can be used to restrict rendered media control elements.
@@ -99,8 +109,6 @@ const DEFAULT_SETTINGS: MediaControlSettings = {
99
109
  right: [
100
110
  'audiotracks',
101
111
  'cc',
102
- // 'dvr',
103
- // 'duration',
104
112
  'fullscreen',
105
113
  'gear',
106
114
  'multicamera',
@@ -122,12 +130,16 @@ const T = 'plugins.media_control'
122
130
  const LEFT_ORDER = [
123
131
  'playpause',
124
132
  'playstop',
125
- 'dvr',
126
133
  'volume',
127
134
  'position',
128
135
  'duration',
136
+ 'dvr',
129
137
  ]
130
138
 
139
+ export enum ExtendedEvents {
140
+ MEDIACONTROL_VOLUME = 'mediacontrol:volume',
141
+ }
142
+
131
143
  const { Config, Fullscreen, formatTime, extend, removeArrayItem } = Utils
132
144
 
133
145
  function orderByOrderPattern(arr: string[], order: string[]): string[] {
@@ -785,16 +797,17 @@ export class MediaControl extends UICorePlugin {
785
797
  // if the container is not ready etc
786
798
  this.intendedVolume = value
787
799
  this.persistConfig && !isInitialVolume && Config.persist('volume', value)
788
- // TODO
789
800
  const setWhenContainerReady = () => {
790
801
  if (this.core.activeContainer && this.core.activeContainer.isReady) {
791
802
  this.core.activeContainer.setVolume(value)
803
+ this.trigger(ExtendedEvents.MEDIACONTROL_VOLUME, value)
792
804
  } else {
793
805
  this.listenToOnce(
794
806
  this.core.activeContainer,
795
807
  Events.CONTAINER_READY,
796
808
  () => {
797
809
  this.core.activeContainer.setVolume(value)
810
+ this.trigger(ExtendedEvents.MEDIACONTROL_VOLUME, value)
798
811
  },
799
812
  )
800
813
  }
@@ -996,8 +1009,7 @@ export class MediaControl extends UICorePlugin {
996
1009
  }
997
1010
  this.$el.show()
998
1011
  this.trigger(Events.MEDIACONTROL_SHOW, this.name)
999
- this.container &&
1000
- this.container.trigger(Events.CONTAINER_MEDIACONTROL_SHOW, this.name)
1012
+ this.core.activeContainer?.trigger(Events.CONTAINER_MEDIACONTROL_SHOW, this.name)
1001
1013
  this.$el.removeClass('media-control-hide')
1002
1014
  this.hideId = setTimeout(() => this.hide(), timeout)
1003
1015
  if (event) {
@@ -1066,7 +1078,7 @@ export class MediaControl extends UICorePlugin {
1066
1078
  )
1067
1079
  trace(`${T} updateSettings`, { newSettings })
1068
1080
 
1069
- newSettings.left.push('clips') // TODO
1081
+ newSettings.left.push('clips') // TODO settings
1070
1082
  // TODO make order controlled via CSS
1071
1083
  newSettings.left = orderByOrderPattern(
1072
1084
  [...newSettings.left, 'volume', 'clips'],
@@ -1155,7 +1167,6 @@ export class MediaControl extends UICorePlugin {
1155
1167
  * Get a media control element DOM node
1156
1168
  * @param name - The name of the media control element
1157
1169
  * @returns The DOM node to render to or extend
1158
- * @deprecated Use {@link MediaControl.putElement} instead
1159
1170
  * @remarks
1160
1171
  * Use this method to render custom media control UI in a plugin
1161
1172
  * @example
@@ -1171,7 +1182,7 @@ export class MediaControl extends UICorePlugin {
1171
1182
  */
1172
1183
  mount(name: MediaControlElement, element: ZeptoResult) {
1173
1184
  const panel = this.getElementLocation(name)
1174
- trace(`${T} putElement`, { name, panel: !!panel })
1185
+ trace(`${T} mount`, { name, panel: !!panel })
1175
1186
  if (panel) {
1176
1187
  const current = panel.find(`[data-${name}]`)
1177
1188
  element.attr(`data-${name}`, '')
@@ -1188,6 +1199,11 @@ export class MediaControl extends UICorePlugin {
1188
1199
  }
1189
1200
  }
1190
1201
 
1202
+ /**
1203
+ * @deprecated Use {@link MediaControl.mount} instead
1204
+ * @param name
1205
+ * @param element
1206
+ */
1191
1207
  putElement(name: MediaControlElement, element: ZeptoResult) {
1192
1208
  this.mount(name, element)
1193
1209
  }
@@ -1195,7 +1211,7 @@ export class MediaControl extends UICorePlugin {
1195
1211
  /**
1196
1212
  * Toggle the visibility of a media control element
1197
1213
  * @param name - The name of the media control element
1198
- * @param show - Whether to show or hide the element
1214
+ * @param show - Visibility state
1199
1215
  */
1200
1216
  toggleElement(area: MediaControlElement, show: boolean) {
1201
1217
  this.$el.find(`[data-${area}]`).toggle(show)
@@ -1456,6 +1472,7 @@ export class MediaControl extends UICorePlugin {
1456
1472
  width: this.options.width,
1457
1473
  height: this.options.height,
1458
1474
  })
1475
+ // TODO check out
1459
1476
  this.hideVolumeBar(0)
1460
1477
  }, 0)
1461
1478
 
@@ -189,7 +189,7 @@ describe('MediaControl', () => {
189
189
  })
190
190
  })
191
191
  })
192
- describe('putElement', () => {
192
+ describe('mount', () => {
193
193
  beforeEach(async () => {
194
194
  mediaControl = new MediaControl(core)
195
195
  core.emit(Events.CORE_READY)
@@ -212,7 +212,7 @@ describe('MediaControl', () => {
212
212
  const element = document.createElement('div')
213
213
  element.className = 'my-media-control'
214
214
  element.textContent = 'test'
215
- mediaControl.putElement(mcName, $(element))
215
+ mediaControl.mount(mcName, $(element))
216
216
 
217
217
  expect(mediaControl.el.innerHTML).toMatchSnapshot()
218
218
  expect(
@@ -234,19 +234,22 @@ describe('MediaControl', () => {
234
234
  seekEnabled: true,
235
235
  }
236
236
  core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
237
+ core.activePlayback.getPlaybackType.mockReturnValue(Playback.LIVE)
238
+ core.activeContainer.getPlaybackType.mockReturnValue(Playback.LIVE)
239
+ core.getPlaybackType.mockReturnValue(Playback.LIVE)
237
240
  await runMetadataLoaded(core)
238
241
  })
239
242
  describe('when enabled', () => {
240
243
  beforeEach(() => {
241
244
  core.activePlayback.dvrEnabled = true
242
245
  core.activeContainer.isDvrEnabled.mockReturnValue(true)
243
- core.activeContainer.emit(Events.CONTAINER_SETTINGSUPDATE, true)
246
+ core.activeContainer.emit(Events.CONTAINER_SETTINGSUPDATE)
244
247
  })
245
248
  it('should enable DVR controls', () => {
246
249
  const element = document.createElement('div')
247
250
  element.className = 'my-dvr-controls'
248
251
  element.textContent = 'live'
249
- mediaControl.putElement('dvr', $(element))
252
+ mediaControl.mount('dvr', $(element))
250
253
  expect(mediaControl.el.innerHTML).toMatchSnapshot()
251
254
  expect(
252
255
  mediaControl.$el.find('.media-control-left-panel .my-dvr-controls')
@@ -259,7 +262,7 @@ describe('MediaControl', () => {
259
262
  const element = document.createElement('div')
260
263
  element.className = 'my-dvr-controls'
261
264
  element.textContent = 'live'
262
- mediaControl.putElement('dvr', $(element))
265
+ mediaControl.mount('dvr', $(element))
263
266
  expect(mediaControl.el.innerHTML).toMatchSnapshot()
264
267
  expect(
265
268
  mediaControl.$el.find('.media-control-left-panel .my-dvr-controls')