@gcorevideo/player 2.30.1 → 2.30.3

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 (53) hide show
  1. package/assets/audio-tracks/template.ejs +1 -1
  2. package/dist/core.js +1 -1
  3. package/dist/index.css +335 -335
  4. package/dist/index.embed.js +43 -13
  5. package/dist/index.js +69 -32
  6. package/lib/plugins/audio-selector/AudioTracks.d.ts +4 -0
  7. package/lib/plugins/audio-selector/AudioTracks.d.ts.map +1 -1
  8. package/lib/plugins/audio-selector/AudioTracks.js +42 -12
  9. package/lib/plugins/media-control/MediaControl.d.ts +1 -0
  10. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  11. package/lib/plugins/media-control/MediaControl.js +9 -1
  12. package/package.json +1 -1
  13. package/src/plugins/audio-selector/AudioTracks.ts +51 -16
  14. package/src/plugins/audio-selector/__tests__/__snapshots__/AudioTracks.test.ts.snap +9 -9
  15. package/src/plugins/media-control/MediaControl.ts +10 -1
  16. package/tsconfig.tsbuildinfo +1 -1
  17. package/assets/vast-ads/style.scss +0 -112
  18. package/lib/plugins/vast-ads/VastAds.d.ts +0 -74
  19. package/lib/plugins/vast-ads/VastAds.d.ts.map +0 -1
  20. package/lib/plugins/vast-ads/VastAds.js +0 -693
  21. package/lib/plugins/vast-ads/loaderxml.d.ts +0 -32
  22. package/lib/plugins/vast-ads/loaderxml.d.ts.map +0 -1
  23. package/lib/plugins/vast-ads/loaderxml.js +0 -229
  24. package/lib/plugins/vast-ads/roll.d.ts +0 -60
  25. package/lib/plugins/vast-ads/roll.d.ts.map +0 -1
  26. package/lib/plugins/vast-ads/roll.js +0 -421
  27. package/lib/plugins/vast-ads/rollmanager.d.ts +0 -62
  28. package/lib/plugins/vast-ads/rollmanager.d.ts.map +0 -1
  29. package/lib/plugins/vast-ads/rollmanager.js +0 -357
  30. package/lib/plugins/vast-ads/sctemanager.d.ts +0 -18
  31. package/lib/plugins/vast-ads/sctemanager.d.ts.map +0 -1
  32. package/lib/plugins/vast-ads/sctemanager.js +0 -117
  33. package/lib/plugins/vast-ads/types.d.ts +0 -12
  34. package/lib/plugins/vast-ads/types.d.ts.map +0 -1
  35. package/lib/plugins/vast-ads/types.js +0 -1
  36. package/lib/plugins/vast-ads/urlhandler.d.ts +0 -4
  37. package/lib/plugins/vast-ads/urlhandler.d.ts.map +0 -1
  38. package/lib/plugins/vast-ads/urlhandler.js +0 -30
  39. package/lib/plugins/vast-ads/xmlhttprequest.d.ts +0 -6
  40. package/lib/plugins/vast-ads/xmlhttprequest.d.ts.map +0 -1
  41. package/lib/plugins/vast-ads/xmlhttprequest.js +0 -40
  42. package/lib/plugins/vast-ads/xmlmerge.d.ts +0 -12
  43. package/lib/plugins/vast-ads/xmlmerge.d.ts.map +0 -1
  44. package/lib/plugins/vast-ads/xmlmerge.js +0 -83
  45. package/src/plugins/vast-ads/VastAds.ts +0 -919
  46. package/src/plugins/vast-ads/loaderxml.ts +0 -301
  47. package/src/plugins/vast-ads/roll.ts +0 -590
  48. package/src/plugins/vast-ads/rollmanager.ts +0 -447
  49. package/src/plugins/vast-ads/sctemanager.ts +0 -152
  50. package/src/plugins/vast-ads/types.ts +0 -20
  51. package/src/plugins/vast-ads/urlhandler.ts +0 -42
  52. package/src/plugins/vast-ads/xmlhttprequest.ts +0 -49
  53. package/src/plugins/vast-ads/xmlmerge.ts +0 -106
@@ -1,919 +0,0 @@
1
- import {
2
- $,
3
- Browser,
4
- Container,
5
- Core,
6
- Events,
7
- HTML5Video,
8
- Log,
9
- Playback,
10
- UIContainerPlugin,
11
- UICorePlugin,
12
- Utils,
13
- } from '@clappr/core'
14
- import { reportError } from '@gcorevideo/utils'
15
- import assert from 'assert'
16
- import { TimePosition } from '../../playback.types.js'
17
-
18
- import { CLAPPR_VERSION } from '../../build.js'
19
- import { ZeptoResult } from '../../types.js'
20
- import { TimerId } from '../../utils/types.js'
21
- import RollManager from './rollmanager.js'
22
- import SCTEManager from './sctemanager.js'
23
- import { VolumeFadeEvents } from '../volume-fade/VolumeFade.js'
24
- import { AdRollItem, AdRollType } from './types.js'
25
-
26
- import '../../../assets/vast-ads/style.scss'
27
- import volumeIcon from '../../../assets/icons/new/volume-max.svg'
28
- import volumeMuteIcon from '../../../assets/icons/new/volume-off.svg'
29
-
30
- const VERSION = '0.0.1'
31
-
32
- type State = 'play' | 'pause' | 'switch' | ''
33
-
34
- export class VastAds extends UICorePlugin {
35
- private _clickToPausePlugin: UIContainerPlugin | null = null
36
-
37
- private _cloneContainerEvents: Record<string, Function> | null = null
38
-
39
- private _clonePlaybackEvents: Record<string, Function> | null = null
40
-
41
- private countMiddleRoll = 0
42
-
43
- private countRepeatableRoll = 0
44
-
45
- private _container: Container | null = null
46
-
47
- private container: Container | null = null
48
-
49
- private _contentElement: HTMLElement | null = null
50
-
51
- private _currentPosition = 0
52
-
53
- private currentState: State = ''
54
-
55
- private _imaIsloaded = false
56
-
57
- private _imaLoadResult = false
58
-
59
- private intervalTimer: TimerId | null = null
60
-
61
- private _playback: Playback | null = null
62
-
63
- private _pluginIsReady = false
64
-
65
- private _posterBigPlayStyle: ZeptoResult | null = null
66
-
67
- private _posterPlugin: UIContainerPlugin | null = null
68
-
69
- private _prevVolumeValue = 0
70
-
71
- private vast: RollManager | null = null
72
-
73
- private _volume = 80
74
-
75
- private startTimeRepeatableRoll = 0
76
-
77
- private startTimeRepeatableRollGap = 0
78
-
79
- private _scteManager = new SCTEManager()
80
-
81
- private $skipAd: ZeptoResult | null = null
82
-
83
- private $muteIcon: ZeptoResult | null = null
84
-
85
- private $areaClick: ZeptoResult | null = null
86
-
87
- private _$adContainer: ZeptoResult | null = null
88
-
89
- private _adContainer: HTMLElement | null = null
90
-
91
- get name() {
92
- return 'clappr-vast-ad-plugin'
93
- }
94
-
95
- get supportedVersion() {
96
- return { min: CLAPPR_VERSION }
97
- }
98
-
99
- static get version() {
100
- return VERSION
101
- }
102
-
103
- get mediaControl() {
104
- return this.core.mediaControl
105
- }
106
-
107
- override get attributes() {
108
- return {
109
- class: this.name,
110
- 'data-vast-ads': '',
111
- }
112
- }
113
-
114
- constructor(core: Core) {
115
- super(core)
116
-
117
- const cfg = this.options.vastAds
118
-
119
- try {
120
- const no_lib = 'google' in window && (window.google as any).ima
121
-
122
- if (!no_lib || !cfg) {
123
- this.disable()
124
-
125
- return
126
- }
127
- } catch (error) {
128
- // LogManager.exception(error);
129
- reportError(error)
130
- this.disable()
131
-
132
- return
133
- }
134
-
135
- // TODO: Add an option which is an array of plugin name to disable
136
- try {
137
- if (!cfg.preroll) {
138
- this._pluginError('tag option is required')
139
- this.disable()
140
-
141
- return
142
- }
143
- } catch (error) {
144
- this._pluginError('tag option is required')
145
- this.disable()
146
- // LogManager.message('Advertisement: tag option is required', SentryLogLevel.ERROR);
147
- reportError(error)
148
-
149
- return
150
- }
151
-
152
- if (cfg.middleroll?.data?.length > 0) {
153
- cfg.middleroll.data = cfg.middleroll.data
154
- .filter(
155
- ({ startTimePercent }: AdRollItem) =>
156
- startTimePercent >= 10 && startTimePercent <= 90,
157
- )
158
- .sort(
159
- (a: AdRollItem, b: AdRollItem) =>
160
- a.startTimePercent - b.startTimePercent,
161
- )
162
- }
163
-
164
- if (cfg.repeatableroll?.data?.length > 0) {
165
- cfg.repeatableroll.data = cfg.repeatableroll.data
166
- .filter(({ startTime }: AdRollItem) => startTime >= 2)
167
- .sort((a: AdRollItem, b: AdRollItem) => a.startTime - b.startTime)
168
- }
169
-
170
- let lang = (this.core.options.language || Utils.getBrowserLanguage())
171
- .toLowerCase()
172
- .replace(/_/g, '-')
173
-
174
- if (lang.indexOf('_') < 0) {
175
- lang += '_' + lang
176
- }
177
-
178
- if ('google' in window && (window.google as any).ima) {
179
- ;(window.google as any).ima.settings.setLocale(lang)
180
- }
181
- }
182
-
183
- override bindEvents() {
184
- const no_lib = 'google' in window && (window.google as any).ima
185
-
186
- if (!no_lib) {
187
- return
188
- }
189
- if (this._scteManager) {
190
- // @ts-ignore
191
- this._scteManager.on('startSCTERoll', () => {
192
- this.initializeRollManager({
193
- type: 'scteroll',
194
- })
195
- })
196
-
197
- // @ts-ignore
198
- this._scteManager.on('stopSCTERoll', () => {
199
- this._playVideoContent('scteroll')
200
- })
201
- }
202
-
203
- this.listenToOnce(this.core, Events.CORE_READY, this._onCoreReady)
204
-
205
- this.listenTo(this.core, Events.CORE_RESIZE, this.playerResize)
206
-
207
- if (this.container) {
208
- this.listenTo(
209
- this.container,
210
- Events.CONTAINER_VOLUME,
211
- this._onContainerVolume,
212
- )
213
- }
214
- this.listenTo(this.core, VolumeFadeEvents.FADE, this._onVolumeChanged)
215
- if (this.playback) {
216
- this.listenTo(this.container, Events.CONTAINER_SEEK, (e: number) => {
217
- if ((this.container as any).advertisement.type === 'middleroll') {
218
- this.countMiddleRoll = this.findCloserAdvertisement(
219
- this.options.vastAds.middleroll,
220
- 'startTimePercent',
221
- this.countMiddleRoll,
222
- e,
223
- )
224
- } else {
225
- this.countRepeatableRoll = this.findCloserAdvertisement(
226
- this.options.vastAds.repeatableroll,
227
- 'startTime',
228
- this.countRepeatableRoll,
229
- e,
230
- )
231
- }
232
- })
233
- this.listenTo(this.playback, Events.PLAYBACK_LEVEL_SWITCH_START, () => {
234
- if (this.currentState === 'pause') {
235
- return
236
- }
237
- this.currentState = 'switch'
238
- })
239
-
240
- this.listenTo(
241
- this.playback,
242
- Events.PLAYBACK_TIMEUPDATE,
243
- this.onPlaybackTimeUpdate,
244
- )
245
-
246
- this.listenTo(this.playback, Events.PLAYBACK_ENDED, this.onPlaybackEnded)
247
-
248
- this._pauserollListeners()
249
- this.listenToOnce(this.playback, Events.PLAYBACK_PLAY, () => {
250
- if (this._posterBigPlayStyle) {
251
- this._posterBigPlayStyle.remove()
252
- this._posterBigPlayStyle = null
253
- }
254
- })
255
- this.listenTo(
256
- this.playback,
257
- Events.PLAYBACK_PLAY,
258
- this.onPlaybackPlay.bind(this),
259
- )
260
-
261
- this.listenToOnce(
262
- this.playback,
263
- 'playback:preroll:request',
264
- this.onPlaybackPrerollRequest,
265
- )
266
- }
267
-
268
- if (this.mediaControl) {
269
- this.listenToOnce(
270
- this.mediaControl,
271
- Events.MEDIACONTROL_CONTAINERCHANGED,
272
- this.containerChanged,
273
- )
274
- }
275
- }
276
-
277
- private onPlaybackEnded() {
278
- if (this.playback?.getPlaybackType() !== 'live') {
279
- this.countMiddleRoll = 0
280
- this.countRepeatableRoll = 0
281
- this.initializeRollManager({
282
- type: 'postroll',
283
- })
284
- this._pauserollListeners()
285
- }
286
- }
287
-
288
- private onPlaybackPlay() {
289
- setTimeout(() => {
290
- const posterPlugin = this.container?.getPlugin('poster')
291
-
292
- posterPlugin?.enable()
293
- posterPlugin?.$el.hide()
294
- ;(this._posterPlugin as any)?.$playWrapper.show()
295
- // TODO trigger event or call a method instead
296
- }, 0)
297
- }
298
-
299
- private onPlaybackPrerollRequest() {
300
- try {
301
- this.initializeRollManager({
302
- type: 'preroll',
303
- })
304
- } catch (error) {
305
- // LogManager.exception(error);
306
- reportError(error)
307
- }
308
- }
309
-
310
- private onPlaybackTimeUpdate(e: TimePosition) {
311
- if ((this.container as any)?.advertisement.type !== 'idle') {
312
- return
313
- }
314
- const middleroll = this._options.VastAds.middleroll
315
-
316
- assert(this.playback, 'playback is not defined')
317
-
318
- if (middleroll && this.playback.getPlaybackType() === 'vod') {
319
- const currentPercent = Math.floor((e.current / e.total) * 100)
320
- const middlerollData = middleroll.data[this.countMiddleRoll]
321
-
322
- if (middlerollData && middlerollData.startTimePercent <= currentPercent) {
323
- // TODO fixit
324
- // @ts-ignore
325
- this._currentPosition = this.playback.getCurrentTime()
326
- this.initializeRollManager({
327
- type: 'middleroll',
328
- count: this.countMiddleRoll,
329
- })
330
- }
331
- }
332
-
333
- if (
334
- this._options.VastAds.repeatableroll &&
335
- this.playback.getPlaybackType() === 'live'
336
- ) {
337
- try {
338
- if (
339
- !(this.playback.el as HTMLMediaElement).played ||
340
- !(this.playback.el as HTMLMediaElement).played.length
341
- ) {
342
- return
343
- }
344
- let startTime =
345
- (this.playback.el as HTMLMediaElement).played.start(0) ||
346
- this.startTimeRepeatableRoll
347
-
348
- if (!this.startTimeRepeatableRoll) {
349
- if (!startTime) {
350
- this.startTimeRepeatableRoll = startTime = (
351
- this.playback.el as HTMLMediaElement
352
- ).currentTime
353
- }
354
- }
355
-
356
- const currentTime =
357
- (this.playback.el as HTMLMediaElement).currentTime -
358
- startTime +
359
- this.startTimeRepeatableRollGap
360
- const repeatablerollData =
361
- this._options.VastAds.repeatableroll.data[this.countRepeatableRoll]
362
-
363
- if (repeatablerollData && repeatablerollData.startTime <= currentTime) {
364
- this.startTimeRepeatableRollGap = currentTime
365
- this.initializeRollManager({
366
- type: 'repeatableroll',
367
- })
368
- }
369
- } catch (error) {
370
- // LogManager.exception(error);
371
- reportError(error)
372
- }
373
- }
374
- }
375
-
376
- private rebindNextAd() {
377
- if (Object.keys(this._scteManager).length > 0) {
378
- this.containerChanged()
379
- }
380
- }
381
-
382
- private initializeRollManager({
383
- type,
384
- count,
385
- }: {
386
- type: AdRollType
387
- count?: number
388
- }) {
389
- this.destroyRoll()
390
- assert(this._adContainer, '_adContainer is not defined')
391
- const vast = new RollManager(
392
- this.core,
393
- this.options,
394
- this.$skipAd,
395
- this.$muteIcon,
396
- this.$areaClick,
397
- this._adContainer,
398
- type,
399
- count || 0,
400
- this._volume,
401
- this._prevVolumeValue,
402
- )
403
-
404
- // @ts-ignore
405
- vast.on('advertisement_finish', (data: { type: AdRollType }) => {
406
- this._playVideoContent(data.type, !!Browser.isiOS)
407
- })
408
- // @ts-ignore
409
- vast.on('advertisement_dont_play', (data: { type: AdRollType }) => {
410
- this._playVideoContent(data.type, true)
411
- })
412
- // @ts-ignore
413
- vast.on('disable_plugin', (data: { type: AdRollType }) => {
414
- this._playVideoContent(data.type)
415
- this.disable()
416
- })
417
- // @ts-ignore
418
- vast.on('advertisement_started', () => {
419
- this.adsPlaying()
420
- })
421
- // @ts-ignore
422
- vast.on('volume', (obj) => {
423
- this.changeVolume(obj)
424
- })
425
- // @ts-ignore
426
- vast.on('change_counter', (data) => {
427
- if (data.type === 'middleroll') {
428
- this.countMiddleRoll = data.value
429
- }
430
- if (data.type === 'repeatableroll') {
431
- this.countRepeatableRoll = data.value
432
- }
433
- })
434
- this.vast = vast
435
- vast.setupRoll()
436
- }
437
-
438
- private changeVolume(obj: { volume: number; mute: boolean }) {
439
- this._volume = obj.volume
440
- this.core.options.mute = this.options.mute = obj.mute
441
- Utils.Config.persist('volume', this._volume)
442
- }
443
-
444
- private findCloserAdvertisement(
445
- roll: { data: AdRollItem[] } | undefined,
446
- key: 'startTime' | 'startTimePercent',
447
- counter: number,
448
- time: number,
449
- ) {
450
- if (!roll) {
451
- return -1
452
- }
453
- if (roll.data.length <= counter) {
454
- return -1
455
- }
456
-
457
- let val = 0
458
-
459
- assert(this.playback, 'playback is not defined')
460
- if (~key.indexOf('Percent')) {
461
- val = (time / this.playback.getDuration()) * 100
462
- } else {
463
- val = time
464
- }
465
-
466
- const getNumber = (arr: AdRollItem[], searchNum: number) =>
467
- arr.find(
468
- (it) =>
469
- Math.abs(it[key] - searchNum) ===
470
- Math.min(...arr.map((it) => Math.abs(it[key] - searchNum))),
471
- )
472
-
473
- const searchEl = getNumber(roll.data, val)
474
- if (!searchEl) {
475
- return -1
476
- }
477
-
478
- return roll.data.findIndex(
479
- (el) => el.startTimePercent === searchEl.startTimePercent,
480
- )
481
- }
482
-
483
- private _validateData(roll: {
484
- data: AdRollItem[]
485
- oneByOne?: boolean
486
- }): boolean {
487
- try {
488
- if (roll.data.length) {
489
- if (!Object.prototype.hasOwnProperty.call(roll, 'oneByOne')) {
490
- roll.oneByOne = false
491
- }
492
-
493
- return true
494
- } else {
495
- return false
496
- }
497
- } catch (error) {
498
- // LogManager.exception(error);
499
- reportError(error)
500
-
501
- return false
502
- }
503
- }
504
-
505
- private playerResize(size: { width: number; height: number }) {
506
- this.$el.removeClass('w370')
507
- if (size.width <= 370 || this.options.hideVolumeBar) {
508
- this.$el.addClass('w370')
509
- }
510
- if (this.vast) {
511
- this.vast.playerResize(size)
512
- }
513
- }
514
-
515
- private _stopPauserollListeners() {
516
- // @ts-ignore
517
- this.stopListening(this.playback, Events.PLAYBACK_PLAY)
518
- // @ts-ignore
519
- this.stopListening(this.playback, Events.PLAYBACK_PAUSE)
520
- }
521
-
522
- private get pluginOptions() {
523
- return this.options.vastAds
524
- }
525
-
526
- private _pauserollListeners() {
527
- if (!this._validateData(this.pluginOptions.pauseroll)) {
528
- return
529
- }
530
- this._stopPauserollListeners()
531
- this.currentState = ''
532
- this.listenTo(this.playback, Events.PLAYBACK_PLAY, () => {
533
- if (this.currentState === 'pause') {
534
- this.currentState = 'play'
535
- setTimeout(() => {
536
- assert(this.playback, 'playback is not defined')
537
- this.playback.pause()
538
- // @ts-ignore
539
- this._currentPosition = this.playback.getCurrentTime()
540
- this.initializeRollManager({
541
- type: 'pauseroll',
542
- })
543
- }, 0)
544
-
545
- return
546
- }
547
- // @ts-ignore
548
- this.stopListening(this.playback, Events.PLAYBACK_PAUSE)
549
- // @ts-ignore
550
- this.stopListening(this.playback, Events.PLAYBACK_STOP)
551
-
552
- const wsPlugin = this.core.getPlugin('ws_plugin')
553
-
554
- if (
555
- this.playback?.getPlaybackType() === 'live' &&
556
- wsPlugin?.state === 'live'
557
- ) {
558
- this.listenToOnce(this.playback, Events.PLAYBACK_STOP, () => {
559
- console.warn('stop stream', this.currentState)
560
- this.currentState = 'pause'
561
- })
562
- } else {
563
- this.listenToOnce(this.playback, Events.PLAYBACK_PAUSE, () => {
564
- console.warn('pause stream', this.currentState)
565
- if (this.currentState === 'switch') {
566
- return
567
- }
568
- this.currentState = 'pause'
569
- })
570
- }
571
- this.currentState = 'play'
572
- })
573
- }
574
-
575
- unBindEvents() {
576
- // @ts-ignore
577
- this.stopListening(this.core, Events.CORE_READY)
578
- // @ts-ignore
579
- this.stopListening(this.mediaControl, Events.MEDIACONTROL_CONTAINERCHANGED)
580
- // @ts-ignore
581
- this.stopListening(this.container, Events.CONTAINER_LOADEDMETADATA)
582
- }
583
-
584
- private containerChanged() {
585
- this.container = this.core.activeContainer
586
- // TODO don't mutate the container
587
- ;(this.container as any).advertisement = { type: 'idle' }
588
- this._container = this.container
589
- this.playback = this.container?.playback
590
- assert(this.playback, 'playback is not defined')
591
- this._contentElement = this.playback.el
592
- this._volume =
593
- this.core &&
594
- this.core.mediaControl &&
595
- this.core.mediaControl.volume !== null &&
596
- this.core.mediaControl.volume !== undefined &&
597
- !isNaN(this.core.mediaControl.volume)
598
- ? this.core.mediaControl.volume
599
- : 80
600
- this._prevVolumeValue = this._volume ? this._volume : 80
601
- this.core.mediaControl.container.$el.append(this.el)
602
- this.$el.hide()
603
- // @ts-ignore
604
- this.stopListening()
605
- // @ts-ignore
606
- this._scteManager.off()
607
- this.bindEvents()
608
- }
609
-
610
- private _pluginError(msg: string) {
611
- console.error(this.name + ': ' + msg)
612
- }
613
-
614
- private _onCoreReady() {
615
- this._container = this.core.activeContainer
616
-
617
- if (!this._container) {
618
- this._pluginError('failed to get Clappr current container')
619
- }
620
- // Get current playback. (To get playback element)
621
- this.playback = this.core.activePlayback
622
- if (!this.playback) {
623
- this._pluginError('failed to get Clappr playback')
624
- }
625
- // Attempt to get poster plugin. (May interfere with media control)
626
- this._posterPlugin = this._container?.getPlugin('poster')
627
-
628
- // Attempt to get click-to-pause plugin. (May interfere with advert click handling)
629
- this._clickToPausePlugin = this._container?.getPlugin('click_to_pause')
630
-
631
- assert(this.playback, 'playback is not defined')
632
- this._contentElement = this.playback.el
633
-
634
- if (this._pluginIsReady) {
635
- return
636
- }
637
-
638
- this._initPlugin()
639
- }
640
-
641
- set playback(value: Playback) {
642
- this._scteManager.playback = value
643
- this._playback = value
644
- }
645
-
646
- get playback(): Playback | null {
647
- return this._playback
648
- }
649
-
650
- private _onContainerVolume(value: number) {
651
- if (value === 0) {
652
- this.options.mute = true
653
- } else {
654
- this._prevVolumeValue = value
655
- this.options.mute = false
656
- }
657
- this._volume = value
658
- }
659
-
660
- _onVolumeChanged(e: number) {
661
- if (this._volume === e || e === 0) {
662
- return
663
- }
664
- this.options.mute = e === 0
665
- this._volume = e
666
- }
667
-
668
- _stopListening() {
669
- try {
670
- assert(this._container, 'container is not defined')
671
- if (!this._clonePlaybackEvents) {
672
- for (const id in this._container._listeningTo) {
673
- this._clonePlaybackEvents = Object.assign(
674
- {},
675
- (this._container._listeningTo as any)[id]._events,
676
- )
677
- ;(this._container._listeningTo as any)[id]._events = {}
678
- }
679
- }
680
- if (!this._cloneContainerEvents) {
681
- this._cloneContainerEvents = Object.assign({}, this._container._events)
682
- this._container._events = {}
683
- }
684
- } catch (error) {
685
- // LogManager.exception(error);
686
- reportError(error)
687
- }
688
- }
689
-
690
- _startListening() {
691
- try {
692
- assert(this._container, 'container is not defined')
693
- for (const id in this._container._listeningTo) {
694
- ;(this._container._listeningTo as any)[id]._events = Object.assign(
695
- {},
696
- this._clonePlaybackEvents,
697
- )
698
- }
699
- this._container._events = Object.assign({}, this._cloneContainerEvents)
700
- this._cloneContainerEvents = null
701
- this._clonePlaybackEvents = null
702
- } catch (error) {
703
- // LogManager.exception(error);
704
- reportError(error)
705
- }
706
- }
707
-
708
- _initPlugin() {
709
- assert(this.playback, 'playback is not defined')
710
- // Ensure browser can play video content. (Avoid to display an ad with nothing after)
711
- if ((this.playback as any).name === 'no_op') {
712
- return
713
- }
714
-
715
- // Ensure playback is using HTML5 video element if mobile device
716
- if (this.playback.tagName !== 'video' && Browser.isMobile) {
717
- this.destroy()
718
-
719
- return
720
- }
721
-
722
- this._pluginIsReady = true
723
- }
724
-
725
- private adsPlaying() {
726
- assert(this.container, 'container is not defined')
727
- const poster = this.container.getPlugin('poster')
728
-
729
- poster && poster.disable()
730
- try {
731
- const logo = this.container.getPlugin('logo')
732
-
733
- logo && logo.disable()
734
- } catch (error) {
735
- // LogManager.exception(error);
736
- reportError(error)
737
- }
738
-
739
- this.core.mediaControl.disable()
740
- this.$el.show()
741
- if ((this.container as any).advertisement.type !== 'scteroll') {
742
- if (!Browser.isiOS) {
743
- setTimeout(() => {
744
- this.playback?.pause()
745
- }, 0)
746
- }
747
- this._stopListening()
748
- } else {
749
- assert(
750
- this.playback instanceof HTML5Video,
751
- 'playback is not an instance of HTML5Video',
752
- )
753
- if (!this.playback.isMuted()) {
754
- ;(this.container as any).advertisement.isMuted = true
755
- this.playback.mute()
756
- }
757
- }
758
- // TODO trigger event on the core object
759
- // Player.player.trigger('advertisementIsPlaying', data);
760
-
761
- try {
762
- const spinnerPlugin = this.container?.getPlugin('spinner')
763
-
764
- spinnerPlugin?.hide()
765
- spinnerPlugin?.disable()
766
- } catch (error) {
767
- // LogManager.exception(error);
768
- reportError(error)
769
- }
770
- }
771
-
772
- private destroyRoll() {
773
- if (this.vast) {
774
- // @ts-ignore
775
- this.vast.off()
776
- this.vast.destroyRoll()
777
- this.vast = null
778
- }
779
- }
780
-
781
- private _playVideoContent(currentRoll: AdRollType, justPlay?: boolean) {
782
- // const currentRoll = type;
783
-
784
- this.destroyRoll()
785
- if (currentRoll === 'preroll') {
786
- this.pluginOptions[currentRoll] = []
787
- }
788
-
789
- this.currentState = ''
790
- this.$el.hide()
791
- if (!this.options.disableClickOnPause) {
792
- // TODO sort out
793
- this._clickToPausePlugin?.enable()
794
- }
795
-
796
- try {
797
- const logoPlugin = this.container?.getPlugin('logo')
798
-
799
- logoPlugin?.enable()
800
- } catch (error) {
801
- // LogManager.exception(error);
802
- reportError(error)
803
- }
804
-
805
- try {
806
- const spinnerPlugin = this.container?.getPlugin('spinner')
807
-
808
- spinnerPlugin?.enable()
809
- spinnerPlugin?.hide()
810
- } catch (error) {
811
- // LogManager.exception(error);
812
- reportError(error)
813
- }
814
-
815
- if (this.intervalTimer !== null) {
816
- clearInterval(this.intervalTimer)
817
- this.intervalTimer = null
818
- }
819
- // @ts-ignore
820
- this.stopListening(this.playback, Events.PLAYBACK_PAUSE)
821
- setTimeout(async () => {
822
- if (currentRoll === 'scteroll') {
823
- this.options.mute = this.core.options.mute
824
- this.setMuted(this.core.options.mute)
825
- this.core.mediaControl.setInitialVolume()
826
- }
827
-
828
- // this.adTemplates = null;
829
- this._posterBigPlayStyle = $(
830
- '<style>div.play-wrapper { display:none; }</style>',
831
- )
832
- this._posterBigPlayStyle.appendTo(this.$el)
833
- // TODO check that the core event is enough
834
- // Player.player.trigger('advertisementWasFinished');
835
- this.core.trigger('core:advertisement:finish')
836
- assert(this.container, 'container is not defined')
837
- this.container.trigger('container:advertisement:finish')
838
- ;(this.container as any).advertisement = { type: 'idle' }
839
- this.container.enableMediaControl()
840
- Log.debug('Advertisement', 'advertisement finished and start video')
841
- const playbackOptions = this.core.options.playback || {}
842
-
843
- playbackOptions.recycleVideo = Browser.isMobile
844
-
845
- if (this._clonePlaybackEvents || this._cloneContainerEvents) {
846
- this._startListening()
847
- }
848
-
849
- if (currentRoll === 'preroll' || currentRoll === 'repeatableroll') {
850
- if (currentRoll === 'repeatableroll') {
851
- this.startTimeRepeatableRoll = 0
852
- }
853
-
854
- if (!justPlay) {
855
- if (this.core.containers) {
856
- this.core.containers.forEach(function (container: Container) {
857
- container.destroy()
858
- })
859
- this.core.containers = []
860
- }
861
- }
862
-
863
- setTimeout(() => {
864
- this.core.configure({
865
- playback: playbackOptions,
866
- sources: this.options.source,
867
- autoPlay: true,
868
- disableCanAutoPlay: true,
869
- mute: this.core.options.mute,
870
- })
871
- this.core.activeContainer.mediaControlDisabled = false
872
- }, 0)
873
-
874
- // TODO figure out where it should go
875
- // if (currentRoll === 'postroll') {
876
- // this.playback.stop();
877
- // }
878
- }
879
-
880
- if (currentRoll === 'pauseroll' || currentRoll === 'middleroll') {
881
- if (Browser.isiOS && this._currentPosition > 0) {
882
- this.listenToOnce(this.playback, Events.PLAYBACK_PLAY, () => {
883
- this.playback?.seek(this._currentPosition)
884
- this._currentPosition = 0
885
- })
886
- }
887
- await this.playback?.play()
888
- this.options.mute = this.core.options.mute
889
- this.setMuted(this.core.options.mute)
890
- this.core.mediaControl.setInitialVolume()
891
- }
892
- }, 0)
893
- }
894
-
895
- override render() {
896
- this.$skipAd = $("<div class='skip-ad-button control-need-disable'></div>")
897
- this.$muteIcon = $("<div class='mute-ad-icon control-need-disable'></div>")
898
- this.$areaClick = $("<div class='area-ad-click enable'></div>")
899
- this.$muteIcon.append(volumeIcon)
900
- this.$muteIcon.append(volumeMuteIcon)
901
- this.$el.append(this.$areaClick)
902
- this.$el.append(this.$skipAd)
903
- this.$el.append(this.$muteIcon)
904
- this.$muteIcon.hide()
905
- this.$skipAd.hide()
906
- this.$areaClick.hide()
907
- this._$adContainer = $('<div />')
908
- .addClass('preroll-container')
909
- .attr('data-preroll', '')
910
- this.$el.append(this._$adContainer)
911
- this._adContainer = this._$adContainer[0]
912
-
913
- return this
914
- }
915
-
916
- private setMuted(muted: boolean) {
917
- this.core.activeContainer.options.mute = muted
918
- }
919
- }