@gcorevideo/player 2.24.11 → 2.24.14
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/README.md +1 -0
- package/assets/dvr-controls/dvr_controls.scss +35 -73
- package/assets/dvr-controls/index.ejs +8 -2
- package/assets/media-control/width370.scss +1 -1
- package/dist/core.js +18 -17
- package/dist/index.css +867 -896
- package/dist/index.embed.js +91 -65
- package/dist/index.js +156 -128
- package/dist/player.d.ts +3264 -0
- package/lib/playback/dash-playback/DashPlayback.d.ts +2 -0
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +17 -11
- package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
- package/lib/playback/hls-playback/HlsPlayback.js +0 -5
- package/lib/plugins/audio-selector/AudioTracks.js +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +1 -1
- package/lib/plugins/clips/Clips.js +1 -1
- package/lib/plugins/dvr-controls/DvrControls.d.ts +3 -3
- package/lib/plugins/dvr-controls/DvrControls.d.ts.map +1 -1
- package/lib/plugins/dvr-controls/DvrControls.js +14 -12
- package/lib/plugins/media-control/MediaControl.d.ts +14 -5
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +55 -29
- package/lib/plugins/picture-in-picture/PictureInPicture.js +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +2 -0
- package/package.json +1 -1
- package/src/playback/dash-playback/DashPlayback.ts +20 -13
- package/src/playback/hls-playback/HlsPlayback.ts +3 -8
- package/src/plugins/audio-selector/AudioTracks.ts +1 -1
- package/src/plugins/audio-selector/__tests__/AudioTracks.test.ts +2 -2
- package/src/plugins/bottom-gear/BottomGear.ts +1 -1
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +2 -2
- package/src/plugins/clips/Clips.ts +1 -1
- package/src/plugins/clips/__tests__/Clips.test.ts +1 -1
- package/src/plugins/dvr-controls/DvrControls.ts +14 -14
- package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +20 -17
- package/src/plugins/dvr-controls/__tests__/__snapshots__/DvrControls.test.ts.snap +4 -2
- package/src/plugins/media-control/MediaControl.ts +69 -35
- package/src/plugins/media-control/__tests__/MediaControl.test.ts +128 -112
- package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +227 -24
- package/src/plugins/picture-in-picture/PictureInPicture.ts +1 -1
- package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
- package/src/testUtils.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, MockedFunction } from 'vitest'
|
|
2
2
|
import {
|
|
3
3
|
MediaControl,
|
|
4
4
|
MediaControlElement,
|
|
5
5
|
MediaControlSettings,
|
|
6
|
+
MediaControlSlotSelector,
|
|
6
7
|
} from '../MediaControl'
|
|
7
8
|
import { createMockCore } from '../../../testUtils'
|
|
8
9
|
import { $, Events, Playback } from '@clappr/core'
|
|
@@ -57,9 +58,10 @@ describe('MediaControl', () => {
|
|
|
57
58
|
core.activePlayback.emit(Events.PLAYBACK_LOADEDMETADATA)
|
|
58
59
|
core.activeContainer.emit(Events.CONTAINER_LOADEDMETADATA)
|
|
59
60
|
})
|
|
61
|
+
// TODO review why delay is needed
|
|
60
62
|
it('should wait a delay before rendering anything', async () => {
|
|
61
63
|
expect(mediaControl.el.innerHTML).toBe('')
|
|
62
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
63
65
|
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
64
66
|
expect(
|
|
65
67
|
mediaControl.$el.find('.media-control-left-panel [data-playpause]')
|
|
@@ -78,9 +80,114 @@ describe('MediaControl', () => {
|
|
|
78
80
|
.length,
|
|
79
81
|
).toBeGreaterThan(0)
|
|
80
82
|
})
|
|
83
|
+
it('should hide volume bar', async () => {
|
|
84
|
+
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
85
|
+
const volumeBar = mediaControl.$el.find(
|
|
86
|
+
'.media-control-left-panel .bar-container[data-volume]',
|
|
87
|
+
)
|
|
88
|
+
expect(volumeBar[0].classList.contains('volume-bar-hide')).toBe(true)
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
describe('playback type', () => {
|
|
93
|
+
beforeEach(() => {
|
|
94
|
+
mediaControl = new MediaControl(core)
|
|
95
|
+
core.emit(Events.CORE_READY)
|
|
96
|
+
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
97
|
+
})
|
|
98
|
+
describe('when live', () => {
|
|
99
|
+
beforeEach(async () => {
|
|
100
|
+
core.activeContainer.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
101
|
+
core.activePlayback.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
102
|
+
core.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
103
|
+
// This is not strictly necessary as the CSS class is applied on the root element and does not require rendering.
|
|
104
|
+
// However, it makes the scenario more realistic
|
|
105
|
+
await runMetadataLoaded(core)
|
|
106
|
+
// TODO playback.settings
|
|
107
|
+
core.activePlayback.emit(Events.PLAYBACK_SETTINGSUPDATE)
|
|
108
|
+
})
|
|
109
|
+
it('should apply live style class', () => {
|
|
110
|
+
expect(mediaControl.$el.hasClass('live')).toBe(true)
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
describe('when vod', () => {
|
|
114
|
+
beforeEach(async () => {
|
|
115
|
+
core.activeContainer.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
116
|
+
core.activePlayback.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
117
|
+
core.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
118
|
+
await runMetadataLoaded(core)
|
|
119
|
+
})
|
|
120
|
+
it('should not apply live style class', () => {
|
|
121
|
+
expect(mediaControl.$el.hasClass('live')).toBe(false)
|
|
122
|
+
})
|
|
81
123
|
})
|
|
82
124
|
})
|
|
83
|
-
|
|
125
|
+
// TODO drop, deprecated
|
|
126
|
+
describe('slot', () => {
|
|
127
|
+
beforeEach(async () => {
|
|
128
|
+
mediaControl = new MediaControl(core)
|
|
129
|
+
core.emit(Events.CORE_READY)
|
|
130
|
+
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
131
|
+
core.activeContainer.settings = {}
|
|
132
|
+
core.emit(Events.CONTAINER_SETTINGSUPDATE)
|
|
133
|
+
await runMetadataLoaded(core)
|
|
134
|
+
})
|
|
135
|
+
describe.each([
|
|
136
|
+
['pip' as MediaControlElement],
|
|
137
|
+
['gear' as MediaControlElement],
|
|
138
|
+
['cc' as MediaControlElement],
|
|
139
|
+
// ['multicamera' as MediaControlElement],
|
|
140
|
+
// ['playbackrate' as MediaControlElement],
|
|
141
|
+
// ['vr' as MediaControlElement],
|
|
142
|
+
['audiotracks' as MediaControlElement],
|
|
143
|
+
// dvr controls
|
|
144
|
+
])('%s', (mcName) => {
|
|
145
|
+
it('should put the element in the right panel', () => {
|
|
146
|
+
const element = document.createElement('div')
|
|
147
|
+
element.className = 'my-media-control'
|
|
148
|
+
element.textContent = 'test'
|
|
149
|
+
mediaControl.slot(mcName, $(element))
|
|
150
|
+
|
|
151
|
+
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
152
|
+
expect(
|
|
153
|
+
mediaControl.$el.find('.media-control-right-panel .my-media-control')
|
|
154
|
+
.length,
|
|
155
|
+
).toEqual(1)
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
describe('mount', () => {
|
|
160
|
+
beforeEach(async () => {
|
|
161
|
+
mediaControl = new MediaControl(core)
|
|
162
|
+
core.emit(Events.CORE_READY)
|
|
163
|
+
core.activeContainer.settings = {
|
|
164
|
+
left: ['playpause', 'position', 'duration', 'volume'],
|
|
165
|
+
default: ['_'],
|
|
166
|
+
right: ['fullscreen', 'hd-indicator'],
|
|
167
|
+
seekEnabled: true,
|
|
168
|
+
} as MediaControlSettings
|
|
169
|
+
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
170
|
+
core.emit(Events.CONTAINER_SETTINGSUPDATE)
|
|
171
|
+
await runMetadataLoaded(core)
|
|
172
|
+
})
|
|
173
|
+
describe.each([
|
|
174
|
+
['root', '> #test-element'],
|
|
175
|
+
['base', '.media-control-layer > #test-element'],
|
|
176
|
+
['left', '.media-control-left-panel > #test-element'],
|
|
177
|
+
['right', '.media-control-right-panel > #test-element'],
|
|
178
|
+
['center', '.media-control-center-panel > #test-element'],
|
|
179
|
+
])('%s', (name: string, checkSelector: string) => {
|
|
180
|
+
it('should attach node to DOM tree', () => {
|
|
181
|
+
mediaControl.mount(
|
|
182
|
+
name as MediaControlSlotSelector,
|
|
183
|
+
$('<div id="test-element">test</div>'),
|
|
184
|
+
)
|
|
185
|
+
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
186
|
+
expect(mediaControl.$el.find(checkSelector).length).toBe(1)
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
describe('container/playback settings', () => {
|
|
84
191
|
beforeEach(async () => {
|
|
85
192
|
mediaControl = new MediaControl(core)
|
|
86
193
|
core.emit(Events.CORE_READY)
|
|
@@ -89,6 +196,7 @@ describe('MediaControl', () => {
|
|
|
89
196
|
})
|
|
90
197
|
describe.each([
|
|
91
198
|
[
|
|
199
|
+
// TODO nothing has changed
|
|
92
200
|
'vod',
|
|
93
201
|
{
|
|
94
202
|
left: ['playpause', 'position', 'duration', 'volume'],
|
|
@@ -96,6 +204,8 @@ describe('MediaControl', () => {
|
|
|
96
204
|
right: ['fullscreen', 'hd-indicator'],
|
|
97
205
|
seekEnabled: true,
|
|
98
206
|
} as MediaControlSettings,
|
|
207
|
+
// live
|
|
208
|
+
// live + dvr
|
|
99
209
|
],
|
|
100
210
|
])('%s', (_, settings: MediaControlSettings) => {
|
|
101
211
|
beforeEach(() => {
|
|
@@ -156,119 +266,25 @@ describe('MediaControl', () => {
|
|
|
156
266
|
}
|
|
157
267
|
})
|
|
158
268
|
})
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
165
|
-
})
|
|
166
|
-
describe('when live', () => {
|
|
167
|
-
beforeEach(async () => {
|
|
168
|
-
core.activeContainer.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
169
|
-
core.activePlayback.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
170
|
-
core.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
171
|
-
// This is not strictly necessary as the CSS class is applied on the root element and does not require rendering.
|
|
172
|
-
// However, it makes the scenario more realistic
|
|
173
|
-
await runMetadataLoaded(core)
|
|
174
|
-
// TODO playback.settings
|
|
175
|
-
core.activePlayback.emit(Events.PLAYBACK_SETTINGSUPDATE)
|
|
176
|
-
})
|
|
177
|
-
it('should apply live style class', () => {
|
|
178
|
-
expect(mediaControl.$el.hasClass('live')).toBe(true)
|
|
179
|
-
})
|
|
180
|
-
})
|
|
181
|
-
describe('when vod', () => {
|
|
182
|
-
beforeEach(async () => {
|
|
183
|
-
core.activeContainer.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
184
|
-
core.activePlayback.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
185
|
-
core.getPlaybackType.mockReturnValue(Playback.VOD)
|
|
186
|
-
await runMetadataLoaded(core)
|
|
187
|
-
})
|
|
188
|
-
it('should not apply live style class', () => {
|
|
189
|
-
expect(mediaControl.$el.hasClass('live')).toBe(false)
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
})
|
|
193
|
-
describe('mount', () => {
|
|
194
|
-
beforeEach(async () => {
|
|
195
|
-
mediaControl = new MediaControl(core)
|
|
196
|
-
core.emit(Events.CORE_READY)
|
|
197
|
-
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
198
|
-
core.activeContainer.settings = {}
|
|
199
|
-
core.emit(Events.CONTAINER_SETTINGSUPDATE)
|
|
200
|
-
await runMetadataLoaded(core)
|
|
201
|
-
})
|
|
202
|
-
describe.each([
|
|
203
|
-
['pip' as MediaControlElement],
|
|
204
|
-
['gear' as MediaControlElement],
|
|
205
|
-
['cc' as MediaControlElement],
|
|
206
|
-
// ['multicamera' as MediaControlElement],
|
|
207
|
-
// ['playbackrate' as MediaControlElement],
|
|
208
|
-
// ['vr' as MediaControlElement],
|
|
209
|
-
['audiotracks' as MediaControlElement],
|
|
210
|
-
// dvr controls
|
|
211
|
-
])('%s', (mcName) => {
|
|
212
|
-
it('should put the element in the right panel', () => {
|
|
213
|
-
const element = document.createElement('div')
|
|
214
|
-
element.className = 'my-media-control'
|
|
215
|
-
element.textContent = 'test'
|
|
216
|
-
mediaControl.mount(mcName, $(element))
|
|
217
|
-
|
|
218
|
-
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
219
|
-
expect(
|
|
220
|
-
mediaControl.$el.find('.media-control-right-panel .my-media-control')
|
|
221
|
-
.length,
|
|
222
|
-
).toEqual(1)
|
|
223
|
-
})
|
|
224
|
-
})
|
|
225
|
-
})
|
|
226
|
-
describe('updateSettings', () => {
|
|
227
|
-
beforeEach(() => {
|
|
228
|
-
mediaControl = new MediaControl(core)
|
|
229
|
-
core.emit(Events.CORE_READY)
|
|
230
|
-
})
|
|
231
|
-
describe('dvr', () => {
|
|
232
|
-
beforeEach(async () => {
|
|
233
|
-
core.activeContainer.settings = {
|
|
234
|
-
left: ['playpause', 'position', 'duration'],
|
|
235
|
-
seekEnabled: true,
|
|
236
|
-
}
|
|
237
|
-
core.emit(Events.CORE_ACTIVE_CONTAINER_CHANGED, core.activeContainer)
|
|
238
|
-
core.activePlayback.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
239
|
-
core.activeContainer.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
240
|
-
core.getPlaybackType.mockReturnValue(Playback.LIVE)
|
|
241
|
-
await runMetadataLoaded(core)
|
|
269
|
+
describe('basically', () => {
|
|
270
|
+
let handler: MockedFunction<() => void>
|
|
271
|
+
beforeEach(() => {
|
|
272
|
+
handler = vi.fn()
|
|
273
|
+
mediaControl.on(Events.MEDIACONTROL_RENDERED, handler, null)
|
|
242
274
|
})
|
|
243
|
-
describe('when
|
|
275
|
+
describe('when settings change', () => {
|
|
244
276
|
beforeEach(() => {
|
|
245
|
-
core.
|
|
246
|
-
|
|
277
|
+
core.activeContainer.settings = {
|
|
278
|
+
left: ['playpause', 'position', 'duration'],
|
|
279
|
+
seekEnabled: true,
|
|
280
|
+
right: ['fullscreen', 'hd-indicator'],
|
|
281
|
+
}
|
|
282
|
+
handler = vi.fn()
|
|
283
|
+
mediaControl.on(Events.MEDIACONTROL_RENDERED, handler, null)
|
|
247
284
|
core.activeContainer.emit(Events.CONTAINER_SETTINGSUPDATE)
|
|
248
285
|
})
|
|
249
|
-
it('should
|
|
250
|
-
|
|
251
|
-
element.className = 'my-dvr-controls'
|
|
252
|
-
element.textContent = 'live'
|
|
253
|
-
mediaControl.mount('dvr', $(element))
|
|
254
|
-
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
255
|
-
expect(
|
|
256
|
-
mediaControl.$el.find('.media-control-left-panel .my-dvr-controls')
|
|
257
|
-
.length,
|
|
258
|
-
).toEqual(1)
|
|
259
|
-
})
|
|
260
|
-
})
|
|
261
|
-
describe('when disabled', () => {
|
|
262
|
-
it('should disable DVR controls', () => {
|
|
263
|
-
const element = document.createElement('div')
|
|
264
|
-
element.className = 'my-dvr-controls'
|
|
265
|
-
element.textContent = 'live'
|
|
266
|
-
mediaControl.mount('dvr', $(element))
|
|
267
|
-
expect(mediaControl.el.innerHTML).toMatchSnapshot()
|
|
268
|
-
expect(
|
|
269
|
-
mediaControl.$el.find('.media-control-left-panel .my-dvr-controls')
|
|
270
|
-
.length,
|
|
271
|
-
).toEqual(0)
|
|
286
|
+
it('should trigger MEDIACONTROL_RENDERED event', () => {
|
|
287
|
+
expect(handler).toHaveBeenCalled()
|
|
272
288
|
})
|
|
273
289
|
})
|
|
274
290
|
})
|