@gcorevideo/player 2.22.30 → 2.22.31
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/media-control/container.scss +2 -3
- package/assets/poster/poster.ejs +3 -1
- package/assets/poster/poster.scss +3 -3
- package/assets/style/main.scss +1 -1
- package/dist/core.js +1 -1
- package/dist/index.css +670 -671
- package/dist/index.js +68 -98
- package/dist/player.d.ts +63 -33
- package/docs/api/{player.seektime.bindevents.md → player.clapprstats.clearmetrics.md} +3 -3
- package/docs/api/player.clapprstats.md +14 -0
- package/docs/api/player.extendedevents.md +14 -0
- package/docs/api/player.md +13 -2
- package/docs/api/player.seektime.attributes.md +0 -1
- package/docs/api/player.seektime.md +6 -197
- package/docs/api/{player.seektime.render.md → player.seektimesettings.md} +7 -7
- package/docs/api/player.skiptime.md +3 -184
- package/lib/plugins/poster/Poster.d.ts +24 -14
- package/lib/plugins/poster/Poster.d.ts.map +1 -1
- package/lib/plugins/poster/Poster.js +67 -97
- package/lib/testUtils.d.ts +13 -39
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +14 -65
- package/package.json +1 -1
- package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +1 -1
- package/src/plugins/poster/Poster.ts +91 -110
- package/src/plugins/poster/__tests__/Poster.test.ts +119 -0
- package/src/plugins/poster/__tests__/__snapshots__/Poster.test.ts.snap +8 -0
- package/src/plugins/source-controller/__tests__/SourceController.test.ts +1 -2
- package/src/testUtils.ts +14 -86
- package/temp/player.api.json +295 -829
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.seektime.durationshown.md +0 -14
- package/docs/api/player.seektime.getseektime.md +0 -20
- package/docs/api/player.seektime.islivestreamwithdvr.md +0 -14
- package/docs/api/player.seektime.mediacontrol.md +0 -14
- package/docs/api/player.seektime.mediacontrolcontainer.md +0 -14
- package/docs/api/player.seektime.shouldbevisible.md +0 -18
- package/docs/api/player.seektime.template.md +0 -14
- package/docs/api/player.seektime.update.md +0 -18
- package/docs/api/player.skiptime.attributes.md +0 -17
- package/docs/api/player.skiptime.bindevents.md +0 -18
- package/docs/api/player.skiptime.events.md +0 -18
- package/docs/api/player.skiptime.handlerewindclicks.md +0 -18
- package/docs/api/player.skiptime.render.md +0 -18
- package/docs/api/player.skiptime.setback.md +0 -18
- package/docs/api/player.skiptime.setforward.md +0 -18
- package/docs/api/player.skiptime.setmidclick.md +0 -18
- package/docs/api/player.skiptime.template.md +0 -14
- package/docs/api/player.skiptime.togglefullscreen.md +0 -18
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
PlayerError,
|
|
9
9
|
UIContainerPlugin,
|
|
10
10
|
template,
|
|
11
|
-
$,
|
|
12
11
|
} from '@clappr/core'
|
|
13
12
|
import { trace } from '@gcorevideo/utils'
|
|
14
13
|
|
|
@@ -20,25 +19,38 @@ import posterHTML from '../../../assets/poster/poster.ejs'
|
|
|
20
19
|
import playIcon from '../../../assets/icons/new/play.svg'
|
|
21
20
|
import { PlaybackError } from '../../playback.types.js'
|
|
22
21
|
|
|
22
|
+
export type PosterPluginSettings = {
|
|
23
|
+
/**
|
|
24
|
+
* Custom CSS background
|
|
25
|
+
*/
|
|
26
|
+
custom?: string
|
|
27
|
+
/**
|
|
28
|
+
* Whether to show the poster image when the playback is noop (i.e., when there is no appropriate video playback engine for current media sources set or the media sources are not set at all)
|
|
29
|
+
*/
|
|
30
|
+
showForNoOp?: boolean
|
|
31
|
+
/**
|
|
32
|
+
* Poster image URL
|
|
33
|
+
*/
|
|
34
|
+
url?: string
|
|
35
|
+
/**
|
|
36
|
+
* Whether to show the poster after playback has ended @default true
|
|
37
|
+
*/
|
|
38
|
+
showOnVideoEnd?: boolean
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
const T = 'plugins.poster'
|
|
24
42
|
|
|
25
43
|
/**
|
|
26
44
|
* `PLUGIN` that displays a poster image in the background and a big play button on top when playback is stopped
|
|
27
45
|
* @beta
|
|
28
46
|
* @remarks
|
|
29
|
-
* When the playback is stopped, media control UI is disabled.
|
|
47
|
+
* When the playback is stopped or not yet started, the media control UI is disabled and hidden.
|
|
48
|
+
* Media control gets activated once the metadata is loaded after playback is initiated.
|
|
49
|
+
* This plugin displays a big play button on top of the poster image to allow user to start playback.
|
|
30
50
|
* Note that the poster image, if specified via the player config, will be used to update video element's poster attribute by the
|
|
31
51
|
* HTML5-video-based playback module.
|
|
32
52
|
*
|
|
33
|
-
* Configuration options
|
|
34
|
-
*
|
|
35
|
-
* - `poster.custom` - custom CSS background
|
|
36
|
-
*
|
|
37
|
-
* - `poster.showForNoOp` - whether to show the poster when the playback is not started
|
|
38
|
-
*
|
|
39
|
-
* - `poster.url` - the URL of the poster image
|
|
40
|
-
*
|
|
41
|
-
* - `poster.showOnVideoEnd` - whether to show the poster when the playback is ended
|
|
53
|
+
* Configuration options - {@link PosterPluginSettings}
|
|
42
54
|
*
|
|
43
55
|
* @example
|
|
44
56
|
* ```ts
|
|
@@ -56,14 +68,12 @@ export class Poster extends UIContainerPlugin {
|
|
|
56
68
|
|
|
57
69
|
private hasFatalError = false
|
|
58
70
|
|
|
59
|
-
private
|
|
71
|
+
private playing = false
|
|
60
72
|
|
|
61
73
|
private playRequested = false
|
|
62
74
|
|
|
63
75
|
private $playButton: ZeptoResult | null = null
|
|
64
76
|
|
|
65
|
-
private $playWrapper: ZeptoResult | null = null
|
|
66
|
-
|
|
67
77
|
/**
|
|
68
78
|
* @internal
|
|
69
79
|
*/
|
|
@@ -87,18 +97,20 @@ export class Poster extends UIContainerPlugin {
|
|
|
87
97
|
const showForNoOp = !!this.options.poster?.showForNoOp
|
|
88
98
|
return (
|
|
89
99
|
this.container.playback.name !== 'html_img' &&
|
|
90
|
-
(this.
|
|
91
|
-
showForNoOp)
|
|
100
|
+
(!this.isNoOp || showForNoOp)
|
|
92
101
|
)
|
|
93
102
|
}
|
|
94
103
|
|
|
104
|
+
private get isNoOp() {
|
|
105
|
+
return this.container.playback.getPlaybackType() === Playback.NO_OP
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
/**
|
|
96
109
|
* @internal
|
|
97
110
|
*/
|
|
98
111
|
override get attributes() {
|
|
99
112
|
return {
|
|
100
113
|
class: 'player-poster',
|
|
101
|
-
'data-poster': '',
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
|
|
@@ -111,10 +123,6 @@ export class Poster extends UIContainerPlugin {
|
|
|
111
123
|
}
|
|
112
124
|
}
|
|
113
125
|
|
|
114
|
-
private get showOnVideoEnd() {
|
|
115
|
-
return this.options.poster?.showOnVideoEnd !== false
|
|
116
|
-
}
|
|
117
|
-
|
|
118
126
|
/**
|
|
119
127
|
* @internal
|
|
120
128
|
*/
|
|
@@ -127,20 +135,27 @@ export class Poster extends UIContainerPlugin {
|
|
|
127
135
|
Events.CONTAINER_STATE_BUFFERFULL,
|
|
128
136
|
this.update,
|
|
129
137
|
)
|
|
130
|
-
this.listenTo(this.container, Events.CONTAINER_OPTIONS_CHANGE, this.
|
|
138
|
+
this.listenTo(this.container, Events.CONTAINER_OPTIONS_CHANGE, this.update)
|
|
131
139
|
this.listenTo(this.container, Events.CONTAINER_ERROR, this.onError)
|
|
132
|
-
this
|
|
140
|
+
// TODO check if this event is always accompanied with the CONTAINER_STOP
|
|
141
|
+
if (this.options.poster?.showOnVideoEnd !== false) {
|
|
133
142
|
this.listenTo(this.container, Events.CONTAINER_ENDED, this.onStop)
|
|
143
|
+
}
|
|
134
144
|
this.listenTo(this.container, Events.CONTAINER_READY, this.render)
|
|
135
|
-
this.listenTo(
|
|
145
|
+
this.listenTo(
|
|
146
|
+
this.container.playback,
|
|
147
|
+
Events.PLAYBACK_PLAY_INTENT,
|
|
148
|
+
this.onPlayIntent,
|
|
149
|
+
)
|
|
136
150
|
}
|
|
137
151
|
|
|
138
152
|
/**
|
|
139
153
|
* Reenables earlier disabled plugin
|
|
140
154
|
*/
|
|
141
155
|
override enable() {
|
|
156
|
+
trace(`${T} enable`)
|
|
142
157
|
super.enable()
|
|
143
|
-
this.
|
|
158
|
+
this.playing = this.container.playback.isPlaying()
|
|
144
159
|
this.update()
|
|
145
160
|
}
|
|
146
161
|
|
|
@@ -149,7 +164,7 @@ export class Poster extends UIContainerPlugin {
|
|
|
149
164
|
*/
|
|
150
165
|
override disable() {
|
|
151
166
|
trace(`${T} disable`)
|
|
152
|
-
this.
|
|
167
|
+
this.playing = false
|
|
153
168
|
this.playRequested = false
|
|
154
169
|
super.disable()
|
|
155
170
|
}
|
|
@@ -159,19 +174,16 @@ export class Poster extends UIContainerPlugin {
|
|
|
159
174
|
error,
|
|
160
175
|
enabled: this.enabled,
|
|
161
176
|
})
|
|
162
|
-
this.hasFatalError = error.level === PlayerError.Levels.FATAL
|
|
163
|
-
|
|
164
177
|
if (this.hasFatalError) {
|
|
165
|
-
|
|
166
|
-
if (!this.playRequested) {
|
|
167
|
-
this.showPlayButton()
|
|
168
|
-
}
|
|
178
|
+
return
|
|
169
179
|
}
|
|
180
|
+
this.hasFatalError = error.level === PlayerError.Levels.FATAL
|
|
181
|
+
// this.hasFatalError is reset on container recreate
|
|
170
182
|
}
|
|
171
183
|
|
|
172
184
|
private onPlay() {
|
|
173
185
|
trace(`${T} onPlay`)
|
|
174
|
-
this.
|
|
186
|
+
this.playing = true
|
|
175
187
|
this.playRequested = false
|
|
176
188
|
this.update()
|
|
177
189
|
}
|
|
@@ -183,24 +195,23 @@ export class Poster extends UIContainerPlugin {
|
|
|
183
195
|
}
|
|
184
196
|
|
|
185
197
|
private onStop() {
|
|
186
|
-
trace(`${T} onStop
|
|
187
|
-
|
|
188
|
-
})
|
|
189
|
-
this.hasStartedPlaying = false
|
|
198
|
+
trace(`${T} onStop`)
|
|
199
|
+
this.playing = false
|
|
190
200
|
this.playRequested = false
|
|
191
201
|
this.update()
|
|
192
202
|
}
|
|
193
203
|
|
|
194
|
-
private updatePlayButton(
|
|
195
|
-
trace(`${T} updatePlayButton
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
private updatePlayButton() {
|
|
205
|
+
trace(`${T} updatePlayButton`)
|
|
206
|
+
const show =
|
|
207
|
+
!this.isNoOp &&
|
|
208
|
+
!(this.options.chromeless && !this.options.allowUserInteraction) &&
|
|
209
|
+
!this.playRequested &&
|
|
210
|
+
!this.playing &&
|
|
211
|
+
!this.container.buffering &&
|
|
212
|
+
!this.hasFatalError &&
|
|
213
|
+
!this.options.disableMediaControl
|
|
214
|
+
if (show) {
|
|
204
215
|
this.showPlayButton()
|
|
205
216
|
} else {
|
|
206
217
|
this.hidePlayButton()
|
|
@@ -208,40 +219,31 @@ export class Poster extends UIContainerPlugin {
|
|
|
208
219
|
}
|
|
209
220
|
|
|
210
221
|
private showPlayButton() {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
if (this.hasFatalError && !this.options.disableErrorScreen) {
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
this.$playButton?.show()
|
|
222
|
+
trace(`${T} showPlayButton`)
|
|
223
|
+
this.$el.find('#poster-play').show()
|
|
219
224
|
this.$el.addClass('clickable')
|
|
220
225
|
this.container.$el.addClass('container-with-poster-clickable')
|
|
221
226
|
}
|
|
222
227
|
|
|
223
228
|
private hidePlayButton() {
|
|
224
|
-
|
|
229
|
+
trace(`${T} hidePlayButton`)
|
|
230
|
+
this.$el.find('#poster-play').hide()
|
|
225
231
|
this.$el.removeClass('clickable')
|
|
226
232
|
}
|
|
227
233
|
|
|
228
|
-
private clicked() {
|
|
229
|
-
trace(`${T} clicked
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
+
private clicked(e: MouseEvent) {
|
|
235
|
+
trace(`${T} clicked`)
|
|
236
|
+
e.preventDefault()
|
|
237
|
+
e.stopPropagation()
|
|
238
|
+
if (this.options.chromeless && !this.options.allowUserInteraction) {
|
|
239
|
+
return
|
|
240
|
+
}
|
|
234
241
|
// Let "click_to_pause" plugin handle click event if media has started playing
|
|
235
|
-
if (!this.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
this.container.playback.consent()
|
|
240
|
-
this.container.playback.play()
|
|
241
|
-
}
|
|
242
|
+
if (!this.playing) {
|
|
243
|
+
this.playRequested = true
|
|
244
|
+
this.update()
|
|
245
|
+
this.container.play()
|
|
242
246
|
}
|
|
243
|
-
|
|
244
|
-
return false
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
private shouldHideOnPlay() {
|
|
@@ -250,27 +252,15 @@ export class Poster extends UIContainerPlugin {
|
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
private update() {
|
|
253
|
-
trace(`${T} update
|
|
254
|
-
shouldRender: this.shouldRender,
|
|
255
|
-
})
|
|
256
|
-
if (!this.shouldRender) {
|
|
257
|
-
return
|
|
258
|
-
}
|
|
255
|
+
trace(`${T} update`)
|
|
259
256
|
|
|
260
|
-
|
|
261
|
-
!this.playRequested &&
|
|
262
|
-
!this.hasStartedPlaying &&
|
|
263
|
-
!this.container.buffering
|
|
264
|
-
|
|
265
|
-
this.updatePlayButton(showPlayButton)
|
|
257
|
+
this.updatePlayButton()
|
|
266
258
|
this.updatePoster()
|
|
267
259
|
}
|
|
268
260
|
|
|
269
261
|
private updatePoster() {
|
|
270
|
-
trace(`${T} updatePoster
|
|
271
|
-
|
|
272
|
-
})
|
|
273
|
-
if (!this.hasStartedPlaying) {
|
|
262
|
+
trace(`${T} updatePoster`)
|
|
263
|
+
if (!this.playing) {
|
|
274
264
|
this.showPoster()
|
|
275
265
|
} else {
|
|
276
266
|
this.hidePoster()
|
|
@@ -283,9 +273,7 @@ export class Poster extends UIContainerPlugin {
|
|
|
283
273
|
}
|
|
284
274
|
|
|
285
275
|
private hidePoster() {
|
|
286
|
-
trace(`${T} hidePoster
|
|
287
|
-
shouldHideOnPlay: this.shouldHideOnPlay(),
|
|
288
|
-
})
|
|
276
|
+
trace(`${T} hidePoster`)
|
|
289
277
|
if (!this.options.disableMediaControl) {
|
|
290
278
|
this.container.enableMediaControl()
|
|
291
279
|
}
|
|
@@ -304,34 +292,27 @@ export class Poster extends UIContainerPlugin {
|
|
|
304
292
|
|
|
305
293
|
this.$el.html(Poster.template())
|
|
306
294
|
|
|
307
|
-
const
|
|
308
|
-
this.options.poster && this.options.poster.custom === undefined
|
|
295
|
+
const isCustomPoster = this.options.poster?.custom !== undefined
|
|
309
296
|
|
|
310
|
-
if (
|
|
311
|
-
const posterUrl = this.options.poster.url || this.options.poster
|
|
312
|
-
|
|
313
|
-
this.$el.css({ 'background-image': 'url(' + posterUrl + ')' })
|
|
314
|
-
} else if (this.options.poster) {
|
|
297
|
+
if (isCustomPoster) {
|
|
315
298
|
this.$el.css({ background: this.options.poster.custom })
|
|
299
|
+
} else {
|
|
300
|
+
const posterUrl =
|
|
301
|
+
typeof this.options.poster === 'string'
|
|
302
|
+
? this.options.poster
|
|
303
|
+
: this.options.poster?.url
|
|
304
|
+
if (posterUrl) {
|
|
305
|
+
this.$el.css({ 'background-image': 'url(' + posterUrl + ')' })
|
|
306
|
+
}
|
|
316
307
|
}
|
|
317
308
|
|
|
318
309
|
this.container.$el.removeClass('container-with-poster-clickable')
|
|
319
310
|
this.container.$el.append(this.el)
|
|
320
|
-
this.$
|
|
321
|
-
this.$playWrapper.addClass('control-need-disable')
|
|
322
|
-
this.$playButton = $(
|
|
323
|
-
"<div class='circle-poster gcore-skin-button-color gcore-skin-border-color'></div>",
|
|
324
|
-
)
|
|
325
|
-
this.$playWrapper.append(this.$playButton)
|
|
326
|
-
this.$playButton.append(playIcon)
|
|
311
|
+
this.$el.find('#poster-play').append(playIcon)
|
|
327
312
|
|
|
328
|
-
if (this.options.autoPlay) {
|
|
329
|
-
this.$
|
|
313
|
+
if (this.options.autoPlay || this.isNoOp) {
|
|
314
|
+
this.$el.find('#poster-play').hide()
|
|
330
315
|
}
|
|
331
|
-
this.$playButton.addClass('poster-icon')
|
|
332
|
-
this.$playButton.attr('data-poster', '')
|
|
333
|
-
|
|
334
|
-
this.update()
|
|
335
316
|
|
|
336
317
|
return this
|
|
337
318
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Poster } from '../Poster'
|
|
2
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
3
|
+
import { createMockCore } from '../../../testUtils'
|
|
4
|
+
import { Events, PlayerError } from '@clappr/core'
|
|
5
|
+
|
|
6
|
+
describe('Poster', () => {
|
|
7
|
+
let core: any
|
|
8
|
+
let poster: Poster
|
|
9
|
+
describe('basically', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
core = createMockCore({
|
|
12
|
+
poster: {
|
|
13
|
+
url: 'https://via.placeholder.com/150.png',
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
poster = new Poster(core.activeContainer)
|
|
17
|
+
core.activeContainer.trigger(Events.CONTAINER_READY)
|
|
18
|
+
})
|
|
19
|
+
it('should render', () => {
|
|
20
|
+
expect(poster.el.innerHTML).toMatchSnapshot()
|
|
21
|
+
})
|
|
22
|
+
describe('when clicked', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
poster.el.click()
|
|
25
|
+
})
|
|
26
|
+
it('should start playback', () => {
|
|
27
|
+
expect(core.activeContainer.play).toHaveBeenCalled()
|
|
28
|
+
expect(core.activeContainer.playback.consent).not.toHaveBeenCalled()
|
|
29
|
+
})
|
|
30
|
+
it('should hide button', () => {
|
|
31
|
+
expect(poster.$el.find('#poster-play')[0].style.display).toBe('none')
|
|
32
|
+
})
|
|
33
|
+
it('should remove clickable class', () => {
|
|
34
|
+
expect(poster.el.classList.contains('clickable')).toBe(false)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
describe('when playback is triggered', () => {
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
core.activeContainer.playback.trigger(Events.PLAYBACK_PLAY_INTENT)
|
|
40
|
+
})
|
|
41
|
+
it('should hide button', () => {
|
|
42
|
+
expect(poster.$el.find('#poster-play')[0].style.display).toBe('none')
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
describe('when playback is about to start', () => {
|
|
46
|
+
describe.each([
|
|
47
|
+
[
|
|
48
|
+
Events.CONTAINER_STATE_BUFFERING,
|
|
49
|
+
], [
|
|
50
|
+
Events.CONTAINER_STATE_BUFFERFULL,
|
|
51
|
+
]
|
|
52
|
+
])("event %s", (event) => {
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
core.activeContainer.buffering = true
|
|
55
|
+
core.activeContainer.trigger(event)
|
|
56
|
+
})
|
|
57
|
+
it('should hide button', () => {
|
|
58
|
+
expect(poster.$el.find('#poster-play')[0].style.display).toBe('none')
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
describe('when playback is started', () => {
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
core.activeContainer.trigger(Events.CONTAINER_PLAY)
|
|
65
|
+
core.activeContainer.playback.trigger(Events.PLAYBACK_PLAY)
|
|
66
|
+
})
|
|
67
|
+
it('should hide poster', () => {
|
|
68
|
+
expect(poster.el.style.display).toBe('none')
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
describe('when playback is stopped', () => {
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
core.activeContainer.trigger(Events.CONTAINER_PLAY)
|
|
74
|
+
core.activeContainer.playback.trigger(Events.PLAYBACK_PLAY)
|
|
75
|
+
core.activeContainer.trigger(Events.CONTAINER_STOP)
|
|
76
|
+
})
|
|
77
|
+
it('should show poster', () => {
|
|
78
|
+
expect(poster.el.style.display).not.toBe('none')
|
|
79
|
+
})
|
|
80
|
+
it('should show button', () => {
|
|
81
|
+
expect(poster.$el.find('#poster-play')[0].style.display).not.toBe('none')
|
|
82
|
+
})
|
|
83
|
+
it('should add clickable class', () => {
|
|
84
|
+
expect(poster.el.classList.contains('clickable')).toBe(true)
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
describe('when autoplay is configured', () => {
|
|
89
|
+
beforeEach(() => {
|
|
90
|
+
core = createMockCore({
|
|
91
|
+
autoPlay: true,
|
|
92
|
+
})
|
|
93
|
+
poster = new Poster(core.activeContainer)
|
|
94
|
+
core.activeContainer.trigger(Events.CONTAINER_READY)
|
|
95
|
+
})
|
|
96
|
+
it('should hide button initially', () => {
|
|
97
|
+
expect(poster.$el.find('#poster-play')[0].style.display).toBe('none')
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
describe('when error occurs', () => {
|
|
101
|
+
beforeEach(() => {
|
|
102
|
+
core = createMockCore({
|
|
103
|
+
autoPlay: true,
|
|
104
|
+
})
|
|
105
|
+
poster = new Poster(core.activeContainer)
|
|
106
|
+
core.activeContainer.trigger(Events.CONTAINER_READY)
|
|
107
|
+
core.activeContainer.playback.trigger(Events.PLAYBACK_PLAY_INTENT)
|
|
108
|
+
core.activeContainer.trigger(Events.CONTAINER_ERROR, {
|
|
109
|
+
level: PlayerError.Levels.FATAL,
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
it('should show poster', () => {
|
|
113
|
+
expect(poster.el.style.display).not.toBe('none')
|
|
114
|
+
})
|
|
115
|
+
it('should hide button', () => {
|
|
116
|
+
expect(poster.$el.find('#poster-play')[0].style.display).toBe('none')
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
})
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`Poster > basically > should render 1`] = `
|
|
4
|
+
"<div class="play-wrapper" id="gplayer-poster">
|
|
5
|
+
<div class="circle-poster gcore-skin-button-color gcore-skin-border-color" id="poster-play">/assets/icons/new/play.svg</div>
|
|
6
|
+
</div>
|
|
7
|
+
"
|
|
8
|
+
`;
|
|
@@ -5,7 +5,6 @@ import FakeTimers from '@sinonjs/fake-timers'
|
|
|
5
5
|
import { SourceController } from '../SourceController'
|
|
6
6
|
import { PlaybackErrorCode } from '../../../playback.types.js'
|
|
7
7
|
import {
|
|
8
|
-
_MockPlayback,
|
|
9
8
|
createMockCore,
|
|
10
9
|
createMockPlayback,
|
|
11
10
|
createMockPlugin,
|
|
@@ -151,7 +150,7 @@ describe('SourceController', () => {
|
|
|
151
150
|
core.activePlayback.emit('playback:error', {
|
|
152
151
|
code: PlaybackErrorCode.MediaSourceUnavailable,
|
|
153
152
|
})
|
|
154
|
-
nextPlayback =
|
|
153
|
+
nextPlayback = createMockPlayback()
|
|
155
154
|
vi.spyOn(nextPlayback, 'consent')
|
|
156
155
|
vi.spyOn(nextPlayback, 'play')
|
|
157
156
|
core.activePlayback = nextPlayback
|
package/src/testUtils.ts
CHANGED
|
@@ -1,86 +1,6 @@
|
|
|
1
|
-
import { $,
|
|
1
|
+
import { $, UICorePlugin } from '@clappr/core'
|
|
2
2
|
import Events from 'eventemitter3'
|
|
3
3
|
import { vi } from 'vitest'
|
|
4
|
-
/**
|
|
5
|
-
* @internal
|
|
6
|
-
* @deprecated
|
|
7
|
-
* TODO use createMockPlayback() instead
|
|
8
|
-
*/
|
|
9
|
-
export class _MockPlayback extends Events {
|
|
10
|
-
constructor(
|
|
11
|
-
protected options: any,
|
|
12
|
-
readonly i18n: any,
|
|
13
|
-
protected playerError?: any,
|
|
14
|
-
) {
|
|
15
|
-
super()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
get name() {
|
|
19
|
-
return 'mock'
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
consent() {}
|
|
23
|
-
|
|
24
|
-
play() {}
|
|
25
|
-
|
|
26
|
-
pause() {}
|
|
27
|
-
|
|
28
|
-
stop() {}
|
|
29
|
-
|
|
30
|
-
destroy() {}
|
|
31
|
-
|
|
32
|
-
seek() {}
|
|
33
|
-
|
|
34
|
-
seekPercentage() {}
|
|
35
|
-
|
|
36
|
-
getDuration() {
|
|
37
|
-
return 100
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
enterPiP() {}
|
|
41
|
-
|
|
42
|
-
exitPiP() {}
|
|
43
|
-
|
|
44
|
-
getPlaybackType() {
|
|
45
|
-
return Playback.LIVE
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
getStartTimeOffset() {
|
|
49
|
-
return 0
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
getCurrentTime() {
|
|
53
|
-
return 0
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
isHighDefinitionInUse() {
|
|
57
|
-
return false
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
mute() {}
|
|
61
|
-
|
|
62
|
-
unmute() {}
|
|
63
|
-
|
|
64
|
-
volume() {}
|
|
65
|
-
|
|
66
|
-
configure() {}
|
|
67
|
-
|
|
68
|
-
attemptAutoPlay() {
|
|
69
|
-
return true
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
canAutoPlay() {
|
|
73
|
-
return true
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
onResize() {
|
|
77
|
-
return true
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
trigger(event: string, ...args: any[]) {
|
|
81
|
-
this.emit(event, ...args)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
4
|
|
|
85
5
|
export function createMockCore(
|
|
86
6
|
options: Record<string, unknown> = {},
|
|
@@ -129,11 +49,12 @@ export function createMockPlayback(name = 'mock') {
|
|
|
129
49
|
el: document.createElement('video'),
|
|
130
50
|
dvrEnabled: false,
|
|
131
51
|
dvrInUse: false,
|
|
52
|
+
isAudioOnly: false,
|
|
132
53
|
levels: [],
|
|
133
|
-
consent()
|
|
134
|
-
play()
|
|
135
|
-
pause()
|
|
136
|
-
stop()
|
|
54
|
+
consent: vi.fn(),
|
|
55
|
+
play: vi.fn(),
|
|
56
|
+
pause: vi.fn(),
|
|
57
|
+
stop: vi.fn(),
|
|
137
58
|
destroy: vi.fn(),
|
|
138
59
|
seek: vi.fn(),
|
|
139
60
|
seekPercentage: vi.fn(),
|
|
@@ -166,13 +87,20 @@ export function createMockContainer(
|
|
|
166
87
|
return Object.assign(emitter, {
|
|
167
88
|
el,
|
|
168
89
|
playback,
|
|
169
|
-
options
|
|
90
|
+
options: {
|
|
91
|
+
...options,
|
|
92
|
+
},
|
|
170
93
|
$el: $(el),
|
|
94
|
+
disableMediaControl: vi.fn(),
|
|
95
|
+
enableMediaControl: vi.fn(),
|
|
96
|
+
enterPiP: vi.fn(),
|
|
97
|
+
exitPiP: vi.fn(),
|
|
171
98
|
getDuration: vi.fn().mockReturnValue(0),
|
|
172
99
|
getPlugin: vi.fn(),
|
|
173
100
|
getPlaybackType: vi.fn(),
|
|
174
101
|
isDvrInUse: vi.fn().mockReturnValue(false),
|
|
175
102
|
isDvrEnabled: vi.fn().mockReturnValue(false),
|
|
103
|
+
isHighDefinitionInUse: vi.fn().mockReturnValue(false),
|
|
176
104
|
isPlaying: vi.fn().mockReturnValue(false),
|
|
177
105
|
play: vi.fn(),
|
|
178
106
|
seek: vi.fn(),
|