@gcorevideo/player 2.22.4 → 2.22.7
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/button.ejs +1 -1
- package/assets/level-selector/list.ejs +10 -4
- package/assets/level-selector/style.scss +8 -3
- package/assets/media-control/media-control.ejs +1 -2
- package/dist/core.js +2 -2
- package/dist/index.css +916 -912
- package/dist/index.js +452 -413
- package/dist/plugins/index.css +668 -664
- package/dist/plugins/index.js +514 -474
- package/lib/index.plugins.d.ts +2 -1
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +2 -1
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +1 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +2 -2
- package/lib/plugins/level-selector/LevelSelector.d.ts +6 -5
- package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
- package/lib/plugins/level-selector/LevelSelector.js +11 -8
- package/lib/plugins/level-selector/QualityLevels.d.ts +112 -0
- package/lib/plugins/level-selector/QualityLevels.d.ts.map +1 -0
- package/lib/plugins/level-selector/QualityLevels.js +280 -0
- package/lib/plugins/media-control/MediaControl.d.ts +37 -6
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +54 -36
- package/lib/plugins/playback-rate/PlaybackRate.d.ts +5 -4
- package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
- package/lib/plugins/playback-rate/PlaybackRate.js +46 -24
- package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
- package/lib/plugins/utils/fullscreen.d.ts +4 -0
- package/lib/plugins/utils/fullscreen.d.ts.map +1 -0
- package/lib/plugins/utils/fullscreen.js +30 -0
- package/lib/plugins/utils.d.ts +0 -1
- package/lib/plugins/utils.d.ts.map +1 -1
- package/lib/plugins/utils.js +0 -28
- package/lib/plugins/vast-ads/VastAds.d.ts +1 -0
- package/lib/plugins/vast-ads/VastAds.d.ts.map +1 -1
- package/lib/plugins/vast-ads/VastAds.js +6 -3
- package/lib/utils/fullscreen.d.ts +3 -0
- package/lib/utils/fullscreen.d.ts.map +1 -0
- package/lib/utils/fullscreen.js +2 -0
- package/package.json +1 -1
- package/src/index.plugins.ts +2 -1
- package/src/playback/dash-playback/DashPlayback.ts +1 -4
- package/src/plugins/bottom-gear/BottomGear.ts +2 -2
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +15 -3
- package/src/plugins/level-selector/{LevelSelector.ts → QualityLevels.ts} +19 -13
- package/src/plugins/level-selector/__tests__/{LevelSelector.test.ts → QualityLevels.test.ts} +20 -6
- package/src/plugins/level-selector/__tests__/__snapshots__/{LevelSelector.test.ts.snap → QualityLevels.test.ts.snap} +58 -25
- package/src/plugins/media-control/MediaControl.ts +111 -62
- package/src/plugins/media-control/__tests__/MediaControl.test.ts +118 -8
- package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +149 -5
- package/src/plugins/playback-rate/PlaybackRate.ts +48 -26
- package/src/plugins/playback-rate/__tests__/PlaybackRate.test.ts +125 -55
- package/src/plugins/playback-rate/__tests__/__snapshots__/PlaybackRate.test.ts.snap +1 -1
- package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
- package/src/plugins/utils/fullscreen.ts +34 -0
- package/src/plugins/utils.ts +0 -31
- package/src/plugins/vast-ads/VastAds.ts +8 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -24,7 +24,8 @@ import { Kibo } from '../kibo/index.js'
|
|
|
24
24
|
|
|
25
25
|
import { CLAPPR_VERSION } from '../../build.js'
|
|
26
26
|
import { ZeptoResult } from '../../types.js'
|
|
27
|
-
import { getPageX
|
|
27
|
+
import { getPageX } from '../utils.js'
|
|
28
|
+
import { fullscreenEnabled, isFullscreen } from '../utils/fullscreen.js'
|
|
28
29
|
|
|
29
30
|
import '../../../assets/media-control/media-control.scss'
|
|
30
31
|
|
|
@@ -38,48 +39,92 @@ import fullscreenOffIcon from '../../../assets/icons/new/fullscreen-off.svg'
|
|
|
38
39
|
import fullscreenOnIcon from '../../../assets/icons/new/fullscreen-on.svg'
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
|
-
* Media control elements
|
|
42
|
+
* Media control elements that appear in the left area.
|
|
42
43
|
* @beta
|
|
43
44
|
*/
|
|
44
|
-
export type
|
|
45
|
+
export type MediaControlLeftElement =
|
|
46
|
+
| 'clipText' // TODO lowercase
|
|
47
|
+
| 'duration'
|
|
48
|
+
| 'dvr'
|
|
49
|
+
| 'playpause'
|
|
50
|
+
| 'playstop'
|
|
51
|
+
| 'position'
|
|
52
|
+
| 'volume'
|
|
53
|
+
// | 'seekbar'
|
|
54
|
+
// | 'seekBarContainer' // TODO rename seekbar
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Media control elements that appear in main layer, spanning the entire width of the player.
|
|
58
|
+
* @beta
|
|
59
|
+
*/
|
|
60
|
+
export type MediaControlLayerElement =
|
|
61
|
+
| 'seekbar'
|
|
62
|
+
| 'seekBarContainer' // TODO rename seekbar
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Media control elements that appear in the right area.
|
|
66
|
+
* @beta
|
|
67
|
+
*/
|
|
68
|
+
export type MediaControlRightElement =
|
|
45
69
|
| 'audiotracks'
|
|
46
70
|
| 'cc'
|
|
47
|
-
| 'clipText'
|
|
48
|
-
| 'dvr'
|
|
49
|
-
| 'duration'
|
|
50
71
|
| 'fullscreen'
|
|
72
|
+
| 'hd-indicator'
|
|
51
73
|
| 'gear'
|
|
52
74
|
| 'multicamera'
|
|
53
75
|
| 'pip'
|
|
54
|
-
| 'playbackRate'
|
|
55
|
-
| 'position'
|
|
56
|
-
| 'seekBarContainer'
|
|
57
76
|
| 'vr'
|
|
58
|
-
| 'volume'
|
|
59
77
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Built-in media control elements.
|
|
80
|
+
* @beta
|
|
81
|
+
*/
|
|
82
|
+
export type MediaControlElement =
|
|
83
|
+
| MediaControlLeftElement
|
|
84
|
+
| MediaControlLayerElement
|
|
85
|
+
| MediaControlRightElement
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Specifies the allowed media control elements in each area.
|
|
89
|
+
* Can be used to restrict rendered media control elements.
|
|
90
|
+
* @beta
|
|
91
|
+
*/
|
|
92
|
+
export type MediaControlSettings = {
|
|
93
|
+
left: MediaControlLeftElement[]
|
|
94
|
+
right: MediaControlRightElement[]
|
|
95
|
+
default: MediaControlLayerElement[]
|
|
64
96
|
seekEnabled: boolean
|
|
65
97
|
}
|
|
66
98
|
|
|
67
99
|
const DEFAULT_SETTINGS: MediaControlSettings = {
|
|
68
|
-
|
|
100
|
+
default: [],
|
|
101
|
+
left: [
|
|
102
|
+
'dvr'
|
|
103
|
+
],
|
|
69
104
|
right: [
|
|
105
|
+
'audiotracks',
|
|
106
|
+
'cc',
|
|
107
|
+
// 'dvr',
|
|
108
|
+
// 'duration',
|
|
70
109
|
'fullscreen',
|
|
71
|
-
'pip',
|
|
72
110
|
'gear',
|
|
73
|
-
'cc',
|
|
74
111
|
'multicamera',
|
|
75
|
-
|
|
112
|
+
'pip',
|
|
76
113
|
'vr',
|
|
77
|
-
'audiotracks',
|
|
78
114
|
],
|
|
79
|
-
default: [],
|
|
80
115
|
seekEnabled: true,
|
|
81
116
|
}
|
|
82
117
|
|
|
118
|
+
const INITIAL_SETTINGS: MediaControlSettings = {
|
|
119
|
+
left: [
|
|
120
|
+
],
|
|
121
|
+
right: [
|
|
122
|
+
],
|
|
123
|
+
default: [
|
|
124
|
+
],
|
|
125
|
+
seekEnabled: false,
|
|
126
|
+
}
|
|
127
|
+
|
|
83
128
|
const T = 'plugins.media_control'
|
|
84
129
|
|
|
85
130
|
const LEFT_ORDER = [
|
|
@@ -112,13 +157,18 @@ type DisabledClickable = {
|
|
|
112
157
|
* @beta
|
|
113
158
|
* @remarks
|
|
114
159
|
* The methods exposed are to be used by the other plugins that extend the media control UI.
|
|
160
|
+
*
|
|
161
|
+
* Configuration options:
|
|
162
|
+
*
|
|
163
|
+
* - `mediaControl`: {@link MediaControlSettings} - specifies the allowed media control elements in each area
|
|
164
|
+
*
|
|
165
|
+
* - `persistConfig`: boolean - `common` option, makes the plugin persist the media control settings
|
|
166
|
+
*
|
|
167
|
+
* - `chromeless`: boolean
|
|
115
168
|
*/
|
|
116
169
|
export class MediaControl extends UICorePlugin {
|
|
117
170
|
// private advertisementPlaying = false
|
|
118
171
|
|
|
119
|
-
private customAreaElements: Record<string, HTMLElement> = {}
|
|
120
|
-
private customAreaHandler?: (name: string, element: HTMLElement) => void
|
|
121
|
-
|
|
122
172
|
private buttonsColor: string | null = null
|
|
123
173
|
|
|
124
174
|
private currentDurationValue: number = 0
|
|
@@ -133,7 +183,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
133
183
|
private draggingSeekBar = false
|
|
134
184
|
private draggingVolumeBar = false
|
|
135
185
|
|
|
136
|
-
private fullScreenOnVideoTagSupported
|
|
186
|
+
private fullScreenOnVideoTagSupported = false
|
|
137
187
|
|
|
138
188
|
private hideId: ReturnType<typeof setTimeout> | null = null
|
|
139
189
|
private hideVolumeId: ReturnType<typeof setTimeout> | null = null
|
|
@@ -147,11 +197,13 @@ export class MediaControl extends UICorePlugin {
|
|
|
147
197
|
private lastMouseX = 0
|
|
148
198
|
private lastMouseY = 0
|
|
149
199
|
|
|
200
|
+
private needsUpdate = false
|
|
201
|
+
|
|
150
202
|
private persistConfig: boolean
|
|
151
203
|
|
|
152
204
|
private rendered = false
|
|
153
205
|
|
|
154
|
-
private settings: MediaControlSettings =
|
|
206
|
+
private settings: MediaControlSettings = INITIAL_SETTINGS
|
|
155
207
|
|
|
156
208
|
private userDisabled = false
|
|
157
209
|
|
|
@@ -173,8 +225,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
173
225
|
|
|
174
226
|
private $playStopToggle: ZeptoResult | null = null
|
|
175
227
|
|
|
176
|
-
private $playbackRate: ZeptoResult | null = null
|
|
177
|
-
|
|
178
228
|
private $position: ZeptoResult | null = null
|
|
179
229
|
|
|
180
230
|
private $seekBarContainer: ZeptoResult | null = null
|
|
@@ -305,6 +355,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
305
355
|
constructor(core: Core) {
|
|
306
356
|
super(core)
|
|
307
357
|
this.persistConfig = this.options.persistConfig
|
|
358
|
+
|
|
308
359
|
this.setInitialVolume()
|
|
309
360
|
|
|
310
361
|
this.kibo = new Kibo(this.options.focusElement)
|
|
@@ -492,7 +543,8 @@ export class MediaControl extends UICorePlugin {
|
|
|
492
543
|
|
|
493
544
|
// video.webkitSupportsFullscreen is deprecated but iOS appears to only use this
|
|
494
545
|
// see https://github.com/clappr/clappr/issues/1127
|
|
495
|
-
if (!
|
|
546
|
+
if (!fullscreenEnabled() && video.webkitSupportsFullscreen) {
|
|
547
|
+
// TODO sort out, use single utility function
|
|
496
548
|
this.fullScreenOnVideoTagSupported = true
|
|
497
549
|
}
|
|
498
550
|
this.updateSettings()
|
|
@@ -769,24 +821,20 @@ export class MediaControl extends UICorePlugin {
|
|
|
769
821
|
}
|
|
770
822
|
|
|
771
823
|
private onActiveContainerChanged() {
|
|
772
|
-
this.fullScreenOnVideoTagSupported =
|
|
824
|
+
this.fullScreenOnVideoTagSupported = false
|
|
773
825
|
// set the new container to match the volume of the last one
|
|
774
826
|
this.setInitialVolume()
|
|
775
827
|
this.changeTogglePlay()
|
|
776
828
|
this.bindContainerEvents()
|
|
829
|
+
// TODO remove?
|
|
777
830
|
this.updateSettings()
|
|
778
|
-
// TODO
|
|
779
|
-
this.core.activeContainer.trigger(
|
|
780
|
-
Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
|
|
781
|
-
this.core.activeContainer.isDvrInUse(),
|
|
782
|
-
)
|
|
783
|
-
// TODO test
|
|
831
|
+
// TODO test, figure out if this is needed
|
|
784
832
|
if (this.core.activeContainer.mediaControlDisabled) {
|
|
785
833
|
this.disable()
|
|
786
834
|
} else {
|
|
787
835
|
this.enable()
|
|
788
836
|
}
|
|
789
|
-
this.trigger(Events.MEDIACONTROL_CONTAINERCHANGED) // TODO
|
|
837
|
+
this.trigger(Events.MEDIACONTROL_CONTAINERCHANGED) // TODO figure out
|
|
790
838
|
|
|
791
839
|
if (this.core.activeContainer.$el) {
|
|
792
840
|
this.core.activeContainer.$el.addClass('container-skin-1')
|
|
@@ -1007,6 +1055,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
1007
1055
|
}
|
|
1008
1056
|
|
|
1009
1057
|
private updateSettings() {
|
|
1058
|
+
trace(`${T} updateSettings`, { settings: this.settings })
|
|
1010
1059
|
const newSettings = $.extend(
|
|
1011
1060
|
true,
|
|
1012
1061
|
{
|
|
@@ -1016,6 +1065,8 @@ export class MediaControl extends UICorePlugin {
|
|
|
1016
1065
|
},
|
|
1017
1066
|
this.core.activeContainer.settings,
|
|
1018
1067
|
)
|
|
1068
|
+
trace(`${T} updateSettings`, { newSettings })
|
|
1069
|
+
|
|
1019
1070
|
|
|
1020
1071
|
// TODO make order controlled via CSS
|
|
1021
1072
|
newSettings.left = orderByOrderPattern(
|
|
@@ -1031,13 +1082,18 @@ export class MediaControl extends UICorePlugin {
|
|
|
1031
1082
|
}
|
|
1032
1083
|
|
|
1033
1084
|
// actual order of the items appear rendered is controlled by CSS
|
|
1034
|
-
newSettings.right = DEFAULT_SETTINGS.right
|
|
1085
|
+
newSettings.right = DEFAULT_SETTINGS.right // TODO get from the options
|
|
1035
1086
|
|
|
1036
1087
|
if (
|
|
1037
1088
|
(!this.fullScreenOnVideoTagSupported &&
|
|
1038
|
-
!
|
|
1089
|
+
!fullscreenEnabled()) ||
|
|
1039
1090
|
this.options.fullscreenDisable
|
|
1040
1091
|
) {
|
|
1092
|
+
trace(`${T} updateSettings removing fullscreen`, {
|
|
1093
|
+
supported: this.fullScreenOnVideoTagSupported,
|
|
1094
|
+
enabled: Fullscreen.fullscreenEnabled(),
|
|
1095
|
+
optionsDisable: this.options.fullscreenDisable,
|
|
1096
|
+
})
|
|
1041
1097
|
// remove fullscreen from settings if it is not available
|
|
1042
1098
|
removeArrayItem(newSettings.default, 'fullscreen')
|
|
1043
1099
|
removeArrayItem(newSettings.left, 'fullscreen')
|
|
@@ -1057,6 +1113,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
1057
1113
|
|
|
1058
1114
|
if (settingsChanged) {
|
|
1059
1115
|
this.settings = newSettings
|
|
1116
|
+
this.needsUpdate = true
|
|
1060
1117
|
this.render()
|
|
1061
1118
|
}
|
|
1062
1119
|
}
|
|
@@ -1090,9 +1147,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
1090
1147
|
this.$volumeBarBackground = this.$el.find('.bar-background[data-volume]')
|
|
1091
1148
|
this.$volumeBarFill = this.$el.find('.bar-fill-1[data-volume]')
|
|
1092
1149
|
this.$volumeBarScrubber = this.$el.find('.bar-scrubber[data-volume]')
|
|
1093
|
-
this.$playbackRate = this.$el.find(
|
|
1094
|
-
'.media-control-playbackrate[data-playbackrate]',
|
|
1095
|
-
)
|
|
1096
1150
|
this.$multiCameraSelector = this.$el.find(
|
|
1097
1151
|
'.media-control-multicamera[data-multicamera]',
|
|
1098
1152
|
)
|
|
@@ -1130,8 +1184,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
1130
1184
|
return null
|
|
1131
1185
|
case 'clipText':
|
|
1132
1186
|
return this.$clipText
|
|
1133
|
-
case 'playbackRate':
|
|
1134
|
-
return this.$playbackRate
|
|
1135
1187
|
case 'seekBarContainer':
|
|
1136
1188
|
return this.$seekBarContainer
|
|
1137
1189
|
}
|
|
@@ -1156,14 +1208,6 @@ export class MediaControl extends UICorePlugin {
|
|
|
1156
1208
|
}
|
|
1157
1209
|
}
|
|
1158
1210
|
|
|
1159
|
-
handleCustomArea(handler: (name: string, content: HTMLElement) => void) {
|
|
1160
|
-
this.customAreaHandler = handler
|
|
1161
|
-
Object.entries(this.customAreaElements).forEach(([name, element]) => {
|
|
1162
|
-
handler(name, element)
|
|
1163
|
-
})
|
|
1164
|
-
this.customAreaElements = {}
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
1211
|
/**
|
|
1168
1212
|
* Toggle the visibility of a media control element
|
|
1169
1213
|
* @param name - The name of the media control element
|
|
@@ -1283,8 +1327,8 @@ export class MediaControl extends UICorePlugin {
|
|
|
1283
1327
|
keys.forEach((i) => {
|
|
1284
1328
|
this.bindKeyAndShow(i, () => {
|
|
1285
1329
|
this.settings.seekEnabled &&
|
|
1286
|
-
this.
|
|
1287
|
-
this.
|
|
1330
|
+
this.core.activeContainer &&
|
|
1331
|
+
this.core.activeContainer.seekPercentage(Number(i) * 10)
|
|
1288
1332
|
return false
|
|
1289
1333
|
})
|
|
1290
1334
|
})
|
|
@@ -1362,11 +1406,13 @@ export class MediaControl extends UICorePlugin {
|
|
|
1362
1406
|
* @internal
|
|
1363
1407
|
*/
|
|
1364
1408
|
override render() {
|
|
1365
|
-
trace(`${T} render
|
|
1409
|
+
trace(`${T} render`, { needsUpdate: this.needsUpdate })
|
|
1410
|
+
if (!this.needsUpdate) {
|
|
1411
|
+
return this
|
|
1412
|
+
}
|
|
1366
1413
|
const timeout = this.options.hideMediaControlDelay || 2000
|
|
1367
1414
|
|
|
1368
|
-
|
|
1369
|
-
this.$el.html(html)
|
|
1415
|
+
this.$el.html(MediaControl.template({ settings: this.settings }))
|
|
1370
1416
|
// const style = Styler.getStyleFor(mediaControlStyle, { baseUrl: this.options.baseUrl });
|
|
1371
1417
|
// this.$el.append(style[0]);
|
|
1372
1418
|
this.createCachedElements()
|
|
@@ -1424,7 +1470,9 @@ export class MediaControl extends UICorePlugin {
|
|
|
1424
1470
|
|
|
1425
1471
|
this.rendered = true
|
|
1426
1472
|
this.updateVolumeUI()
|
|
1427
|
-
|
|
1473
|
+
|
|
1474
|
+
this.needsUpdate = false
|
|
1475
|
+
// TODO setTimeout?
|
|
1428
1476
|
this.trigger(Events.MEDIACONTROL_RENDERED)
|
|
1429
1477
|
|
|
1430
1478
|
return this
|
|
@@ -1504,6 +1552,7 @@ export class MediaControl extends UICorePlugin {
|
|
|
1504
1552
|
})
|
|
1505
1553
|
}
|
|
1506
1554
|
|
|
1555
|
+
// TODO drop
|
|
1507
1556
|
private isSeekEnabledForHtml5Playback() {
|
|
1508
1557
|
if (this.core.getPlaybackType() === Playback.LIVE) {
|
|
1509
1558
|
return this.options.dvrEnabled
|
|
@@ -1519,13 +1568,13 @@ export class MediaControl extends UICorePlugin {
|
|
|
1519
1568
|
left: this.settings.left,
|
|
1520
1569
|
default: this.settings.default,
|
|
1521
1570
|
})
|
|
1522
|
-
if (this.settings.right?.includes(name)) {
|
|
1571
|
+
if (this.settings.right?.includes(name as MediaControlRightElement)) {
|
|
1523
1572
|
return this.getRightPanel()
|
|
1524
1573
|
}
|
|
1525
|
-
if (this.settings.left?.includes(name)) {
|
|
1574
|
+
if (this.settings.left?.includes(name as MediaControlLeftElement)) {
|
|
1526
1575
|
return this.getLeftPanel()
|
|
1527
1576
|
}
|
|
1528
|
-
if (this.settings.default?.includes(name)) {
|
|
1577
|
+
if (this.settings.default?.includes(name as MediaControlLayerElement)) {
|
|
1529
1578
|
return this.getCenterPanel()
|
|
1530
1579
|
}
|
|
1531
1580
|
return null
|
|
@@ -1545,8 +1594,8 @@ MediaControl.extend = function (properties) {
|
|
|
1545
1594
|
}
|
|
1546
1595
|
|
|
1547
1596
|
function serializeSettings(s: MediaControlSettings) {
|
|
1548
|
-
return s.left
|
|
1549
|
-
.slice()
|
|
1597
|
+
return (s.left
|
|
1598
|
+
.slice() as MediaControlElement[])
|
|
1550
1599
|
.sort()
|
|
1551
1600
|
.concat(s.right.slice().sort())
|
|
1552
1601
|
.concat(s.default.slice().sort())
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
MediaControl,
|
|
4
|
+
MediaControlElement,
|
|
5
|
+
MediaControlSettings,
|
|
6
|
+
} from '../MediaControl'
|
|
3
7
|
import { createMockCore } from '../../../testUtils'
|
|
4
8
|
import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
|
|
5
9
|
import { $, Events, Playback } from '@clappr/core'
|
|
6
10
|
|
|
11
|
+
vi.mock('../../utils/fullscreen', () => ({
|
|
12
|
+
fullscreenEnabled: vi.fn().mockReturnValue(true),
|
|
13
|
+
isFullscreen: vi.fn().mockReturnValue(false),
|
|
14
|
+
}))
|
|
15
|
+
|
|
7
16
|
Logger.enable('*')
|
|
8
17
|
setTracer(new LogTracer('MediaControl.test'))
|
|
9
18
|
|
|
@@ -14,16 +23,96 @@ describe('MediaControl', () => {
|
|
|
14
23
|
beforeEach(() => {
|
|
15
24
|
core = createMockCore()
|
|
16
25
|
})
|
|
26
|
+
describe('initially', () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
mediaControl = new MediaControl(core)
|
|
29
|
+
core.emit(Events.CORE_READY)
|
|
30
|
+
})
|
|
31
|
+
it('should not render', () => {
|
|
32
|
+
expect(mediaControl.el.innerHTML).toBe('')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
describe('when container settings update', () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
mediaControl = new MediaControl(core)
|
|
38
|
+
core.emit(Events.CORE_READY)
|
|
39
|
+
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
40
|
+
core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
|
|
41
|
+
core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
|
|
42
|
+
})
|
|
43
|
+
describe.each([
|
|
44
|
+
[
|
|
45
|
+
'vod',
|
|
46
|
+
{
|
|
47
|
+
left: ['playpause', 'position', 'duration'],
|
|
48
|
+
default: ['seekbar'],
|
|
49
|
+
right: ['fullscreen', 'volume', 'hd-indicator'],
|
|
50
|
+
seekEnabled: true,
|
|
51
|
+
} as MediaControlSettings,
|
|
52
|
+
],
|
|
53
|
+
])('%s', (_, settings: MediaControlSettings) => {
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
core.activeContainer.settings = settings
|
|
56
|
+
core.activePlayback.emit(Events.PLAYBACK_SETTINGSUPDATE)
|
|
57
|
+
core.activeContainer.emit(Events.CONTAINER_SETTINGSUPDATE)
|
|
58
|
+
})
|
|
59
|
+
it('should render', () => {
|
|
60
|
+
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
61
|
+
})
|
|
62
|
+
it.each(
|
|
63
|
+
settings.left
|
|
64
|
+
)("should render %s control", (element) => {
|
|
65
|
+
const el = mediaControl.$el.find(`.media-control-left-panel [data-${element}]`)
|
|
66
|
+
expect(el.length).toEqual(1)
|
|
67
|
+
})
|
|
68
|
+
it.each(
|
|
69
|
+
arraySubtract(['playpause', 'playstop', 'position', 'duration'], settings.left)
|
|
70
|
+
)("should not render %s control", (element) => {
|
|
71
|
+
const el = mediaControl.$el.find(`.media-control-left-panel [data-${element}]`)
|
|
72
|
+
expect(el.length).toEqual(0)
|
|
73
|
+
})
|
|
74
|
+
it(`should ${settings.seekEnabled ? '' : 'not '}render the seek bar`, () => {
|
|
75
|
+
const seekbar = mediaControl.$el.find('.media-control-center-panel [data-seekbar]')
|
|
76
|
+
expect(seekbar.length).toBeGreaterThan(1)
|
|
77
|
+
if (settings.seekEnabled) {
|
|
78
|
+
expect(seekbar.hasClass('seek-disabled')).toBe(false)
|
|
79
|
+
} else {
|
|
80
|
+
expect(seekbar.hasClass('seek-disabled')).toBe(true)
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
it(`should ${settings.right.includes('volume') ? '' : 'not '}render the volume control`, () => {
|
|
84
|
+
const volume = mediaControl.$el.find('.drawer-container[data-volume]')
|
|
85
|
+
if (settings.right.includes('volume')) {
|
|
86
|
+
expect(volume.length).toEqual(1)
|
|
87
|
+
} else {
|
|
88
|
+
expect(volume.length).toEqual(0)
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
it(`should ${settings.right.includes('fullscreen') ? '' : 'not '}render the fullscreen control`, () => {
|
|
92
|
+
const fullscreen = mediaControl.$el.find('.media-control-right-panel [data-fullscreen]')
|
|
93
|
+
if (settings.right.includes('fullscreen')) {
|
|
94
|
+
expect(fullscreen.length).toEqual(1)
|
|
95
|
+
} else {
|
|
96
|
+
expect(fullscreen.length).toEqual(0)
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
17
101
|
describe('playback type', () => {
|
|
18
102
|
beforeEach(() => {
|
|
19
103
|
mediaControl = new MediaControl(core)
|
|
20
|
-
core.emit(
|
|
104
|
+
core.emit(Events.CORE_READY)
|
|
21
105
|
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
22
106
|
})
|
|
23
107
|
describe('when live', () => {
|
|
24
108
|
beforeEach(() => {
|
|
25
109
|
core.activeContainer.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
110
|
+
core.activePlayback.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
111
|
+
core.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
26
112
|
core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
|
|
113
|
+
core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
|
|
114
|
+
// TODO playback.settings
|
|
115
|
+
core.activePlayback.emit(Events.PLAYBACK_SETTINGSUPDATE)
|
|
27
116
|
})
|
|
28
117
|
it('should apply live style class', () => {
|
|
29
118
|
expect(mediaControl.$el.hasClass('live')).toBe(true)
|
|
@@ -32,6 +121,8 @@ describe('MediaControl', () => {
|
|
|
32
121
|
describe('when vod', () => {
|
|
33
122
|
beforeEach(() => {
|
|
34
123
|
core.activeContainer.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
124
|
+
core.activePlayback.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
125
|
+
core.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
35
126
|
core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
|
|
36
127
|
})
|
|
37
128
|
it('should not apply live style class', () => {
|
|
@@ -53,7 +144,7 @@ describe('MediaControl', () => {
|
|
|
53
144
|
// ['multicamera' as MediaControlElement],
|
|
54
145
|
// ['playbackrate' as MediaControlElement],
|
|
55
146
|
// ['vr' as MediaControlElement],
|
|
56
|
-
|
|
147
|
+
['audiotracks' as MediaControlElement],
|
|
57
148
|
// dvr controls
|
|
58
149
|
])('%s', (mcName) => {
|
|
59
150
|
it('should put the element in the right panel', () => {
|
|
@@ -63,14 +154,17 @@ describe('MediaControl', () => {
|
|
|
63
154
|
mediaControl.putElement(mcName, $(element))
|
|
64
155
|
|
|
65
156
|
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
66
|
-
expect(
|
|
157
|
+
expect(
|
|
158
|
+
mediaControl.$el.find('.media-control-right-panel .my-media-control')
|
|
159
|
+
.length,
|
|
160
|
+
).toEqual(1)
|
|
67
161
|
})
|
|
68
162
|
})
|
|
69
163
|
})
|
|
70
164
|
describe('updateSettings', () => {
|
|
71
165
|
beforeEach(() => {
|
|
72
166
|
mediaControl = new MediaControl(core)
|
|
73
|
-
core.emit(
|
|
167
|
+
core.emit(Events.CORE_READY)
|
|
74
168
|
})
|
|
75
169
|
describe('dvr', () => {
|
|
76
170
|
beforeEach(() => {
|
|
@@ -92,7 +186,10 @@ describe('MediaControl', () => {
|
|
|
92
186
|
element.textContent = 'live'
|
|
93
187
|
mediaControl.putElement('dvr', $(element))
|
|
94
188
|
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
95
|
-
expect(
|
|
189
|
+
expect(
|
|
190
|
+
mediaControl.$el.find('.media-control-left-panel .my-dvr-controls')
|
|
191
|
+
.length,
|
|
192
|
+
).toEqual(1)
|
|
96
193
|
})
|
|
97
194
|
})
|
|
98
195
|
describe('when disabled', () => {
|
|
@@ -102,7 +199,10 @@ describe('MediaControl', () => {
|
|
|
102
199
|
element.textContent = 'live'
|
|
103
200
|
mediaControl.putElement('dvr', $(element))
|
|
104
201
|
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
105
|
-
expect(
|
|
202
|
+
expect(
|
|
203
|
+
mediaControl.$el.find('.media-control-left-panel .my-dvr-controls')
|
|
204
|
+
.length,
|
|
205
|
+
).toEqual(0)
|
|
106
206
|
})
|
|
107
207
|
})
|
|
108
208
|
})
|
|
@@ -122,7 +222,10 @@ describe('MediaControl', () => {
|
|
|
122
222
|
beforeEach(() => {
|
|
123
223
|
core.activeContainer.isDvrInUse.mockReturnValue(true)
|
|
124
224
|
core.activePlayback.dvrInUse = true
|
|
125
|
-
core.activeContainer.emit(
|
|
225
|
+
core.activeContainer.emit(
|
|
226
|
+
Events.CONTAINER_PLAYBACKDVRSTATECHANGED,
|
|
227
|
+
true,
|
|
228
|
+
)
|
|
126
229
|
})
|
|
127
230
|
it('should apply DVR style class', () => {
|
|
128
231
|
expect(mediaControl.$el.hasClass('dvr')).toBe(true)
|
|
@@ -130,3 +233,10 @@ describe('MediaControl', () => {
|
|
|
130
233
|
})
|
|
131
234
|
})
|
|
132
235
|
})
|
|
236
|
+
|
|
237
|
+
function arraySubtract<T extends string>(arr1: T[], arr2: T[]) {
|
|
238
|
+
// const ret = arr1.filter((item) => !arr2.includes(item))
|
|
239
|
+
return arr1.filter((item) => !arr2.includes(item))
|
|
240
|
+
// console.log('arraySubtract %s - %s: %s', arr1, arr2, ret)
|
|
241
|
+
// return ret
|
|
242
|
+
}
|