@gcorevideo/player 2.24.14 → 2.25.0
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/clips/clips.ejs +1 -1
- package/assets/clips/clips.scss +7 -5
- package/assets/media-control/width370.scss +3 -5
- package/dist/core.js +1 -1
- package/dist/index.css +870 -871
- package/dist/index.embed.js +171 -100
- package/dist/index.js +150 -78
- package/dist/player.d.ts +106 -42
- package/docs/api/player.md +18 -20
- package/docs/api/player.mediacontrol.defaultsettings.md +32 -0
- package/docs/api/player.mediacontrol.extendsettings.md +77 -0
- package/docs/api/player.mediacontrol.md +31 -11
- package/docs/api/player.mediacontrol.mount.md +8 -8
- package/docs/api/player.mediacontrol.slot.md +97 -0
- package/docs/api/player.mediacontrolelement.md +6 -3
- package/docs/api/player.mediacontrolpluginsettings.md +13 -0
- package/docs/api/player.mediacontrolsettings.md +5 -5
- package/docs/api/{player.mediacontrol.enablecontrolbutton.md → player.mediacontrolslotmountpoint.md} +4 -8
- package/docs/api/{player.mediacontrol.disabledcontrolbutton.md → player.standardmediacontrolelement.md} +4 -8
- package/lib/plugins/clips/Clips.d.ts +1 -0
- package/lib/plugins/clips/Clips.d.ts.map +1 -1
- package/lib/plugins/clips/Clips.js +16 -2
- package/lib/plugins/dvr-controls/DvrControls.js +1 -1
- package/lib/plugins/media-control/MediaControl.d.ts +87 -34
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +121 -76
- package/package.json +1 -1
- package/src/plugins/clips/Clips.ts +17 -2
- package/src/plugins/clips/__tests__/Clips.test.ts +1 -1
- package/src/plugins/clips/__tests__/__snapshots__/Clips.test.ts.snap +1 -1
- package/src/plugins/dvr-controls/DvrControls.ts +1 -1
- package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +1 -1
- package/src/plugins/media-control/MediaControl.ts +170 -141
- package/src/plugins/media-control/__tests__/MediaControl.test.ts +24 -17
- package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +125 -93
- package/temp/player.api.json +186 -108
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.mediacontrollayerelement.md +0 -16
- package/docs/api/player.mediacontrolleftelement.md +0 -16
- package/docs/api/player.mediacontrolrightelement.md +0 -16
|
@@ -38,60 +38,36 @@ import volumeOffIcon from '../../../assets/icons/new/volume-off.svg'
|
|
|
38
38
|
import fullscreenOffIcon from '../../../assets/icons/new/fullscreen-off.svg'
|
|
39
39
|
import fullscreenOnIcon from '../../../assets/icons/new/fullscreen-on.svg'
|
|
40
40
|
|
|
41
|
+
const STANDARD_MEDIA_CONTROL_ELEMENTS: string[] = [
|
|
42
|
+
'duration',
|
|
43
|
+
'fullscreen',
|
|
44
|
+
'hd-indicator',
|
|
45
|
+
'playpause',
|
|
46
|
+
'playstop',
|
|
47
|
+
'position',
|
|
48
|
+
'seekbar',
|
|
49
|
+
'volume',
|
|
50
|
+
]
|
|
51
|
+
|
|
41
52
|
/**
|
|
42
|
-
*
|
|
53
|
+
* Built-in media control elements.
|
|
43
54
|
* @beta
|
|
44
55
|
*/
|
|
45
|
-
export type
|
|
46
|
-
| 'clipText' // TODO lowercase
|
|
56
|
+
export type StandardMediaControlElement =
|
|
47
57
|
| 'duration'
|
|
48
|
-
| '
|
|
58
|
+
| 'fullscreen'
|
|
59
|
+
| 'hd-indicator'
|
|
49
60
|
| 'playpause'
|
|
50
61
|
| 'playstop'
|
|
51
62
|
| 'position'
|
|
63
|
+
| 'seekbar'
|
|
52
64
|
| 'volume'
|
|
53
|
-
| 'clips'
|
|
54
65
|
|
|
55
66
|
/**
|
|
56
|
-
*
|
|
67
|
+
* Identifies a location for mounting custom media control elements.
|
|
57
68
|
* @beta
|
|
58
69
|
*/
|
|
59
|
-
export type
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Media control elements that appear in the right area.
|
|
63
|
-
* @beta
|
|
64
|
-
*/
|
|
65
|
-
export type MediaControlRightElement =
|
|
66
|
-
| 'audiotracks'
|
|
67
|
-
| 'cc'
|
|
68
|
-
| 'fullscreen'
|
|
69
|
-
| 'hd-indicator'
|
|
70
|
-
| 'gear'
|
|
71
|
-
| 'multicamera'
|
|
72
|
-
| 'pip'
|
|
73
|
-
| 'vr'
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Built-in media control elements.
|
|
77
|
-
* @beta
|
|
78
|
-
*/
|
|
79
|
-
export type MediaControlElement =
|
|
80
|
-
| MediaControlLeftElement
|
|
81
|
-
| MediaControlLayerElement
|
|
82
|
-
| MediaControlRightElement
|
|
83
|
-
|
|
84
|
-
const MANAGED_ELEMENTS: MediaControlElement[] = [
|
|
85
|
-
'dvr',
|
|
86
|
-
'duration',
|
|
87
|
-
'fullscreen',
|
|
88
|
-
'hd-indicator',
|
|
89
|
-
'position',
|
|
90
|
-
'seekbar',
|
|
91
|
-
'volume',
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
export type MediaControlSlotSelector =
|
|
70
|
+
export type MediaControlSlotMountPoint =
|
|
95
71
|
| 'root'
|
|
96
72
|
| 'base'
|
|
97
73
|
| 'left'
|
|
@@ -100,28 +76,36 @@ export type MediaControlSlotSelector =
|
|
|
100
76
|
| 'seekbar'
|
|
101
77
|
|
|
102
78
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
79
|
+
* Media control element.
|
|
80
|
+
* Each element's token in the media control layout settings determines where the element is rendered.
|
|
81
|
+
* @beta
|
|
82
|
+
* @remarks
|
|
83
|
+
* Standard media control elements are defined in the {@link StandardMediaControlElement} type.
|
|
84
|
+
* Custom media control elements can be identified by a unique token.
|
|
85
|
+
*/
|
|
86
|
+
export type MediaControlElement = string
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Specifies the layout of media control elements.
|
|
90
|
+
* Actual elements will be rendered according to the playback settings. Custom elements rendered by the plugins
|
|
91
|
+
* will be mounted at the specified locations.
|
|
105
92
|
* @beta
|
|
106
93
|
*/
|
|
107
94
|
export type MediaControlSettings = {
|
|
108
|
-
left:
|
|
109
|
-
right:
|
|
110
|
-
default:
|
|
95
|
+
left: MediaControlElement[]
|
|
96
|
+
right: MediaControlElement[]
|
|
97
|
+
default: MediaControlElement[]
|
|
111
98
|
seekEnabled: boolean
|
|
112
99
|
}
|
|
113
100
|
|
|
101
|
+
// TODO export
|
|
114
102
|
const DEFAULT_SETTINGS: MediaControlSettings = {
|
|
115
|
-
default: [],
|
|
116
|
-
left: ['
|
|
103
|
+
default: ['seekbar'],
|
|
104
|
+
left: ['playpause', 'playstop', 'position', 'duration', 'volume'],
|
|
117
105
|
right: [
|
|
118
|
-
'
|
|
119
|
-
'
|
|
106
|
+
'*',
|
|
107
|
+
// 'hd-indicator',
|
|
120
108
|
'fullscreen',
|
|
121
|
-
'gear',
|
|
122
|
-
'multicamera',
|
|
123
|
-
'pip',
|
|
124
|
-
'vr',
|
|
125
109
|
],
|
|
126
110
|
seekEnabled: true,
|
|
127
111
|
}
|
|
@@ -135,15 +119,6 @@ const INITIAL_SETTINGS: MediaControlSettings = {
|
|
|
135
119
|
|
|
136
120
|
const T = 'plugins.media_control'
|
|
137
121
|
|
|
138
|
-
const LEFT_ORDER = [
|
|
139
|
-
'playpause',
|
|
140
|
-
'playstop',
|
|
141
|
-
'volume',
|
|
142
|
-
'position',
|
|
143
|
-
'duration',
|
|
144
|
-
'dvr',
|
|
145
|
-
]
|
|
146
|
-
|
|
147
122
|
/**
|
|
148
123
|
* Extended events for the {@link MediaControl} plugin
|
|
149
124
|
* @beta
|
|
@@ -155,33 +130,25 @@ export enum ExtendedEvents {
|
|
|
155
130
|
|
|
156
131
|
const { Config, Fullscreen, formatTime, extend, removeArrayItem } = Utils
|
|
157
132
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const ordered = order.filter((item) => arrWithoutDuplicates.includes(item))
|
|
161
|
-
|
|
162
|
-
const rest = arrWithoutDuplicates.filter((item) => !order.includes(item))
|
|
163
|
-
|
|
164
|
-
return [...ordered, ...rest]
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
type DisabledClickable = {
|
|
168
|
-
el: ZeptoResult
|
|
169
|
-
pointerEventValue: string
|
|
133
|
+
export type MediaControlPluginSettings = {
|
|
134
|
+
hideMediaControlDelay?: number
|
|
170
135
|
}
|
|
171
136
|
|
|
172
137
|
/**
|
|
173
|
-
* `PLUGIN` that provides
|
|
138
|
+
* `PLUGIN` that provides framework for building media control UI.
|
|
174
139
|
* @beta
|
|
175
140
|
* @remarks
|
|
176
141
|
* The methods exposed are to be used by the other plugins that extend the media control UI.
|
|
177
142
|
*
|
|
178
|
-
* Configuration options
|
|
143
|
+
* Configuration options (root level)
|
|
144
|
+
*
|
|
145
|
+
* - `hideMediaControlDelay`: number - specifies the delay in milliseconds before the media control UI is hidden after the last user interaction
|
|
179
146
|
*
|
|
180
|
-
* - `mediaControl`: {@link MediaControlSettings} - specifies the
|
|
147
|
+
* - `mediaControl`: {@link MediaControlSettings} - specifies the media control dashboard layout
|
|
181
148
|
*
|
|
182
149
|
* - `persistConfig`: boolean - `common` option, makes the plugin persist the media control settings
|
|
183
150
|
*
|
|
184
|
-
* - `chromeless`: boolean
|
|
151
|
+
* - `chromeless`: boolean - `common` option, hides the media control UI
|
|
185
152
|
*/
|
|
186
153
|
export class MediaControl extends UICorePlugin {
|
|
187
154
|
// private advertisementPlaying = false
|
|
@@ -192,7 +159,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
192
159
|
private currentPositionValue: number = 0
|
|
193
160
|
private currentSeekBarPercentage = 0
|
|
194
161
|
|
|
195
|
-
private disabledClickableList: DisabledClickable[] = []
|
|
162
|
+
// private disabledClickableList: DisabledClickable[] = []
|
|
196
163
|
private displayedDuration: string | null = null
|
|
197
164
|
private displayedPosition: string | null = null
|
|
198
165
|
private displayedSeekBarPercentage: number | null = null
|
|
@@ -236,8 +203,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
236
203
|
|
|
237
204
|
private $fullscreenToggle: ZeptoResult | null = null
|
|
238
205
|
|
|
239
|
-
private $multiCameraSelector: ZeptoResult | null = null
|
|
240
|
-
|
|
241
206
|
private $playPauseToggle: ZeptoResult | null = null
|
|
242
207
|
|
|
243
208
|
private $playStopToggle: ZeptoResult | null = null
|
|
@@ -282,6 +247,48 @@ export class MediaControl extends UICorePlugin {
|
|
|
282
247
|
return { min: CLAPPR_VERSION }
|
|
283
248
|
}
|
|
284
249
|
|
|
250
|
+
/**
|
|
251
|
+
* @returns Default media control layout settings
|
|
252
|
+
* @remark
|
|
253
|
+
* The method can be used to change the default dashboard layout, for example, removing the standard UI elements
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* const settings = MediaControl.defaultSettings()
|
|
257
|
+
* settings.left = settings.filter(item => item !== 'playpause' && item !== 'playstop')
|
|
258
|
+
* ...
|
|
259
|
+
* new Player({
|
|
260
|
+
* mediaControl: settings,
|
|
261
|
+
* })
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
static defaultSettings() {
|
|
265
|
+
return $.extend(true, {}, DEFAULT_SETTINGS)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Extend the default media control layout settings
|
|
270
|
+
* @param settings - Additional settings
|
|
271
|
+
* @returns The extended settings
|
|
272
|
+
* @remarks
|
|
273
|
+
* This method allows adding custom elements to the media control dashboard.
|
|
274
|
+
* The default settings are not modified.
|
|
275
|
+
* @example
|
|
276
|
+
* ```ts
|
|
277
|
+
* new Player({
|
|
278
|
+
* mediaControl: MediaControl.extendSettings({
|
|
279
|
+
* left: ['*'], // add all custom elements to the left panel
|
|
280
|
+
* }),
|
|
281
|
+
* })
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
static extendSettings(settings: Partial<MediaControlSettings>) {
|
|
285
|
+
return {
|
|
286
|
+
left: mergeElements(DEFAULT_SETTINGS.left, settings.left ?? []),
|
|
287
|
+
right: mergeElements(DEFAULT_SETTINGS.right, settings.right ?? []),
|
|
288
|
+
default: mergeElements(DEFAULT_SETTINGS.default, settings.default ?? []),
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
285
292
|
private get disabled() {
|
|
286
293
|
const playbackIsNOOP =
|
|
287
294
|
this.core.activeContainer &&
|
|
@@ -648,10 +655,8 @@ export class MediaControl extends UICorePlugin {
|
|
|
648
655
|
}
|
|
649
656
|
|
|
650
657
|
private changeTogglePlay() {
|
|
651
|
-
// assert.ok(this.$playPauseToggle, 'play/pause toggle must be present');
|
|
652
658
|
this.$playPauseToggle?.html('')
|
|
653
659
|
|
|
654
|
-
// assert.ok(this.$playStopToggle, 'play/stop toggle must be present');
|
|
655
660
|
this.$playStopToggle?.html('')
|
|
656
661
|
if (this.container && this.container.isPlaying()) {
|
|
657
662
|
this.$playPauseToggle?.append(pauseIcon)
|
|
@@ -1099,7 +1104,8 @@ export class MediaControl extends UICorePlugin {
|
|
|
1099
1104
|
}
|
|
1100
1105
|
|
|
1101
1106
|
private updateSettings() {
|
|
1102
|
-
|
|
1107
|
+
// TODO use this.options.mediaControl to additionally filter the settings
|
|
1108
|
+
const container = $.extend(
|
|
1103
1109
|
true,
|
|
1104
1110
|
{
|
|
1105
1111
|
left: [],
|
|
@@ -1109,44 +1115,34 @@ export class MediaControl extends UICorePlugin {
|
|
|
1109
1115
|
this.core.activeContainer.settings,
|
|
1110
1116
|
)
|
|
1111
1117
|
|
|
1112
|
-
|
|
1113
|
-
// TODO make order controlled via CSS
|
|
1114
|
-
newSettings.left = orderByOrderPattern(
|
|
1115
|
-
[...newSettings.left, 'volume', 'clips'],
|
|
1116
|
-
LEFT_ORDER,
|
|
1117
|
-
)
|
|
1118
|
-
if (
|
|
1119
|
-
this.core.activePlayback.getPlaybackType() === Playback.LIVE &&
|
|
1120
|
-
this.core.activePlayback.dvrEnabled
|
|
1121
|
-
) {
|
|
1122
|
-
newSettings.left.push('dvr')
|
|
1123
|
-
}
|
|
1118
|
+
container.left.push('volume')
|
|
1124
1119
|
|
|
1125
|
-
|
|
1126
|
-
newSettings.right = DEFAULT_SETTINGS.right // TODO get from the options
|
|
1120
|
+
const setup = this.options.mediaControl ?? DEFAULT_SETTINGS
|
|
1127
1121
|
|
|
1128
1122
|
if (
|
|
1129
1123
|
(!this.fullScreenOnVideoTagSupported && !fullscreenEnabled()) ||
|
|
1130
1124
|
this.options.fullscreenDisable
|
|
1131
1125
|
) {
|
|
1132
1126
|
// remove fullscreen from settings if it is not available
|
|
1133
|
-
removeArrayItem(
|
|
1134
|
-
removeArrayItem(
|
|
1135
|
-
removeArrayItem(
|
|
1127
|
+
removeArrayItem(container.default, 'fullscreen')
|
|
1128
|
+
removeArrayItem(container.left, 'fullscreen')
|
|
1129
|
+
removeArrayItem(container.right, 'fullscreen')
|
|
1136
1130
|
}
|
|
1137
1131
|
|
|
1138
|
-
removeArrayItem(newSettings.default, 'hd-indicator')
|
|
1139
|
-
removeArrayItem(newSettings.left, 'hd-indicator')
|
|
1140
|
-
|
|
1141
1132
|
// TODO get from container's settings
|
|
1142
1133
|
if (this.core.activePlayback.name === 'html5_video') {
|
|
1143
|
-
|
|
1134
|
+
container.seekEnabled = this.isSeekEnabledForHtml5Playback()
|
|
1135
|
+
// TODO remove seekbar if seek is disabled?
|
|
1144
1136
|
}
|
|
1145
1137
|
|
|
1146
|
-
|
|
1138
|
+
container.left = evalSettings(container.left, setup.left)
|
|
1139
|
+
container.right = evalSettings(container.right, setup.right)
|
|
1140
|
+
container.default = evalSettings(container.default, setup.default)
|
|
1141
|
+
|
|
1142
|
+
const settingsChanged = !isEqualSettings(this.settings, container)
|
|
1147
1143
|
|
|
1148
1144
|
if (settingsChanged) {
|
|
1149
|
-
this.settings =
|
|
1145
|
+
this.settings = container
|
|
1150
1146
|
this.hasUpdate = true
|
|
1151
1147
|
this.render()
|
|
1152
1148
|
}
|
|
@@ -1181,18 +1177,38 @@ export class MediaControl extends UICorePlugin {
|
|
|
1181
1177
|
this.$volumeBarBackground = this.$el.find('.bar-background[data-volume]')
|
|
1182
1178
|
this.$volumeBarFill = this.$el.find('.bar-fill-1[data-volume]')
|
|
1183
1179
|
this.$volumeBarScrubber = this.$el.find('.bar-scrubber[data-volume]')
|
|
1184
|
-
this.$multiCameraSelector = this.$el.find(
|
|
1185
|
-
'.media-control-multicamera[data-multicamera]',
|
|
1186
|
-
)
|
|
1187
1180
|
this.resetIndicators()
|
|
1188
1181
|
this.initializeIcons()
|
|
1189
1182
|
}
|
|
1190
1183
|
|
|
1191
1184
|
/**
|
|
1192
|
-
*
|
|
1185
|
+
* Mount a media control to its configured location
|
|
1193
1186
|
* @param name - The name of the media control element
|
|
1194
1187
|
* @param element - The DOM node/fragment to mount
|
|
1195
|
-
* @
|
|
1188
|
+
* @remarks
|
|
1189
|
+
* Media controls layout is configured via {@link MediaControlSettings}.
|
|
1190
|
+
* A plugin implementing custom elements on the media control dashboard,
|
|
1191
|
+
* should use this method to mount the element to the correct location.
|
|
1192
|
+
* The actual location is defined by the occurence of the element token in the `left`, `right` or `default` section
|
|
1193
|
+
* of the {@link MediaControlSettings}.
|
|
1194
|
+
* @example
|
|
1195
|
+
* ```ts
|
|
1196
|
+
* class MyPlugin extends UICorePlugin {
|
|
1197
|
+
* override render() {
|
|
1198
|
+
* // mount the element where it is configured in the layout
|
|
1199
|
+
* this.core.getPlugin('media_control').slot('my-element', this.$el)
|
|
1200
|
+
* }
|
|
1201
|
+
* }
|
|
1202
|
+
* ...
|
|
1203
|
+
* Player.registerPlugin(MyPlugin)
|
|
1204
|
+
* ...
|
|
1205
|
+
* // Configuration of the media control layout
|
|
1206
|
+
* new Player({
|
|
1207
|
+
* mediaControl: {
|
|
1208
|
+
* left: ['my-element'], // the element will be mounted to the left panel
|
|
1209
|
+
* },
|
|
1210
|
+
* })
|
|
1211
|
+
* ```
|
|
1196
1212
|
*/
|
|
1197
1213
|
slot(name: MediaControlElement, element: ZeptoResult): void {
|
|
1198
1214
|
const panel = this.getElementLocation(name)
|
|
@@ -1219,11 +1235,11 @@ export class MediaControl extends UICorePlugin {
|
|
|
1219
1235
|
* }
|
|
1220
1236
|
* ```
|
|
1221
1237
|
*/
|
|
1222
|
-
mount(name:
|
|
1238
|
+
mount(name: MediaControlSlotMountPoint, element: ZeptoResult) {
|
|
1223
1239
|
mountTo(this.getMountParent(name), element)
|
|
1224
1240
|
}
|
|
1225
1241
|
|
|
1226
|
-
private getMountParent(name:
|
|
1242
|
+
private getMountParent(name: MediaControlSlotMountPoint): ZeptoResult {
|
|
1227
1243
|
switch (name) {
|
|
1228
1244
|
case 'root':
|
|
1229
1245
|
return this.$el
|
|
@@ -1451,7 +1467,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
1451
1467
|
}
|
|
1452
1468
|
const timeout = this.options.hideMediaControlDelay || 2000
|
|
1453
1469
|
|
|
1454
|
-
trace(`${T} render`, { settings: this.settings })
|
|
1455
1470
|
this.$el.html(MediaControl.template({ settings: this.settings }))
|
|
1456
1471
|
// const style = Styler.getStyleFor(mediaControlStyle, { baseUrl: this.options.baseUrl });
|
|
1457
1472
|
// this.$el.append(style[0]);
|
|
@@ -1572,24 +1587,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
1572
1587
|
return 0
|
|
1573
1588
|
}
|
|
1574
1589
|
|
|
1575
|
-
/**
|
|
1576
|
-
* Enable the user interaction disabled earlier
|
|
1577
|
-
*/
|
|
1578
|
-
enableControlButton() {
|
|
1579
|
-
this.disabledClickableList.forEach((element) => {
|
|
1580
|
-
element.el.css({ 'pointer-events': element.pointerEventValue })
|
|
1581
|
-
})
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
/**
|
|
1585
|
-
* Disable the user interaction for the control buttons
|
|
1586
|
-
*/
|
|
1587
|
-
disabledControlButton() {
|
|
1588
|
-
this.disabledClickableList.forEach((element) => {
|
|
1589
|
-
element.el.css({ 'pointer-events': 'none' })
|
|
1590
|
-
})
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
1590
|
// TODO drop
|
|
1594
1591
|
private isSeekEnabledForHtml5Playback() {
|
|
1595
1592
|
if (this.core.getPlaybackType() === Playback.LIVE) {
|
|
@@ -1600,13 +1597,16 @@ export class MediaControl extends UICorePlugin {
|
|
|
1600
1597
|
}
|
|
1601
1598
|
|
|
1602
1599
|
private getElementLocation(name: MediaControlElement) {
|
|
1603
|
-
if (this.settings.
|
|
1604
|
-
return this.getRightPanel()
|
|
1605
|
-
}
|
|
1606
|
-
if (this.settings.left?.includes(name as MediaControlLeftElement)) {
|
|
1600
|
+
if (this.settings.left.includes(name) || this.settings.left.includes('*')) {
|
|
1607
1601
|
return this.getLeftPanel()
|
|
1608
1602
|
}
|
|
1609
|
-
if (
|
|
1603
|
+
if (
|
|
1604
|
+
this.settings.right.includes(name) ||
|
|
1605
|
+
this.settings.right.includes('*')
|
|
1606
|
+
) {
|
|
1607
|
+
return this.getRightPanel()
|
|
1608
|
+
}
|
|
1609
|
+
if (this.settings.default.includes(name)) {
|
|
1610
1610
|
return this.getCenterPanel()
|
|
1611
1611
|
}
|
|
1612
1612
|
return null
|
|
@@ -1626,7 +1626,8 @@ MediaControl.extend = function (properties) {
|
|
|
1626
1626
|
}
|
|
1627
1627
|
|
|
1628
1628
|
function serializeSettings(s: MediaControlSettings) {
|
|
1629
|
-
return
|
|
1629
|
+
return s.left
|
|
1630
|
+
.slice()
|
|
1630
1631
|
.sort()
|
|
1631
1632
|
.concat(s.right.slice().sort())
|
|
1632
1633
|
.concat(s.default.slice().sort())
|
|
@@ -1643,3 +1644,31 @@ function mountTo(parent: ZeptoResult, element: ZeptoResult) {
|
|
|
1643
1644
|
parent.append(element)
|
|
1644
1645
|
}
|
|
1645
1646
|
}
|
|
1647
|
+
|
|
1648
|
+
function isStandardMediaControl(name: MediaControlElement) {
|
|
1649
|
+
return STANDARD_MEDIA_CONTROL_ELEMENTS.includes(name)
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
function evalSettings(
|
|
1653
|
+
container: MediaControlElement[],
|
|
1654
|
+
setup: MediaControlElement[],
|
|
1655
|
+
): MediaControlElement[] {
|
|
1656
|
+
return setup.filter((item) => {
|
|
1657
|
+
if (isStandardMediaControl(item)) {
|
|
1658
|
+
return container.includes(item)
|
|
1659
|
+
}
|
|
1660
|
+
return true
|
|
1661
|
+
})
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
function mergeElements(
|
|
1665
|
+
a: MediaControlElement[],
|
|
1666
|
+
b: MediaControlElement[],
|
|
1667
|
+
): MediaControlElement[] {
|
|
1668
|
+
return b.reduce((acc, item) => {
|
|
1669
|
+
if (!acc.includes(item)) {
|
|
1670
|
+
acc.push(item)
|
|
1671
|
+
}
|
|
1672
|
+
return acc
|
|
1673
|
+
}, a)
|
|
1674
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, MockedFunction } from 'vitest'
|
|
2
2
|
import {
|
|
3
3
|
MediaControl,
|
|
4
|
-
MediaControlElement,
|
|
5
4
|
MediaControlSettings,
|
|
6
|
-
|
|
5
|
+
MediaControlSlotMountPoint,
|
|
7
6
|
} from '../MediaControl'
|
|
8
7
|
import { createMockCore } from '../../../testUtils'
|
|
9
8
|
import { $, Events, Playback } from '@clappr/core'
|
|
@@ -122,9 +121,13 @@ describe('MediaControl', () => {
|
|
|
122
121
|
})
|
|
123
122
|
})
|
|
124
123
|
})
|
|
125
|
-
// TODO drop, deprecated
|
|
126
124
|
describe('slot', () => {
|
|
127
125
|
beforeEach(async () => {
|
|
126
|
+
core.options.mediaControl = MediaControl.extendSettings({
|
|
127
|
+
left: ['dvr', 'clips'],
|
|
128
|
+
right: ['pip', 'gear', 'cc', 'audiotracks'],
|
|
129
|
+
default: ['seekbar'],
|
|
130
|
+
})
|
|
128
131
|
mediaControl = new MediaControl(core)
|
|
129
132
|
core.emit(Events.CORE_READY)
|
|
130
133
|
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
@@ -133,36 +136,40 @@ describe('MediaControl', () => {
|
|
|
133
136
|
await runMetadataLoaded(core)
|
|
134
137
|
})
|
|
135
138
|
describe.each([
|
|
136
|
-
['pip'
|
|
137
|
-
['gear'
|
|
138
|
-
['cc'
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
['audiotracks' as MediaControlElement],
|
|
139
|
+
['pip', '.media-control-right-panel'],
|
|
140
|
+
['gear', '.media-control-right-panel'],
|
|
141
|
+
['cc', '.media-control-right-panel'],
|
|
142
|
+
['audiotracks', '.media-control-right-panel'],
|
|
143
|
+
['dvr', '.media-control-left-panel'],
|
|
144
|
+
['clips', '.media-control-left-panel'],
|
|
143
145
|
// dvr controls
|
|
144
|
-
])('%s', (mcName) => {
|
|
145
|
-
it('should put the element
|
|
146
|
+
])('%s', (mcName, checkSelector) => {
|
|
147
|
+
it('should put the element according to layout', () => {
|
|
146
148
|
const element = document.createElement('div')
|
|
147
149
|
element.className = 'my-media-control'
|
|
150
|
+
element.id = 'my-media-control'
|
|
148
151
|
element.textContent = 'test'
|
|
149
152
|
mediaControl.slot(mcName, $(element))
|
|
150
153
|
|
|
151
154
|
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
152
155
|
expect(
|
|
153
|
-
mediaControl.$el.find(
|
|
154
|
-
.length,
|
|
156
|
+
mediaControl.$el.find(`${checkSelector} #my-media-control`).length,
|
|
155
157
|
).toEqual(1)
|
|
156
158
|
})
|
|
157
159
|
})
|
|
158
160
|
})
|
|
159
161
|
describe('mount', () => {
|
|
160
162
|
beforeEach(async () => {
|
|
161
|
-
mediaControl = new MediaControl(core)
|
|
162
163
|
core.emit(Events.CORE_READY)
|
|
164
|
+
core.options.mediaControl = {
|
|
165
|
+
left: ['playpause', 'position', 'duration', 'volume'],
|
|
166
|
+
default: ['_'], // placeholder is needed because otherwise the panel is not rendered
|
|
167
|
+
right: ['fullscreen', 'hd-indicator'],
|
|
168
|
+
} as MediaControlSettings
|
|
169
|
+
mediaControl = new MediaControl(core)
|
|
163
170
|
core.activeContainer.settings = {
|
|
164
171
|
left: ['playpause', 'position', 'duration', 'volume'],
|
|
165
|
-
default: [
|
|
172
|
+
default: [], // placeholder is needed because otherwise the panel is not rendered
|
|
166
173
|
right: ['fullscreen', 'hd-indicator'],
|
|
167
174
|
seekEnabled: true,
|
|
168
175
|
} as MediaControlSettings
|
|
@@ -179,7 +186,7 @@ describe('MediaControl', () => {
|
|
|
179
186
|
])('%s', (name: string, checkSelector: string) => {
|
|
180
187
|
it('should attach node to DOM tree', () => {
|
|
181
188
|
mediaControl.mount(
|
|
182
|
-
name as
|
|
189
|
+
name as MediaControlSlotMountPoint,
|
|
183
190
|
$('<div id="test-element">test</div>'),
|
|
184
191
|
)
|
|
185
192
|
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|