@mindedge/vuetify-player 0.3.1 → 0.4.1
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 +90 -50
- package/package.json +1 -1
- package/src/components/Media/CaptionsMenu.vue +269 -99
- package/src/components/Media/Html5Player.vue +454 -304
- package/src/components/Media/PlaylistMenu.vue +40 -42
- package/src/components/Media/SettingsMenu.vue +98 -0
- package/src/components/Media/YoutubePlayer.vue +5 -1
- package/src/components/VuetifyPlayer.vue +218 -28
- package/src/i18n/en-US.js +9 -0
- package/src/i18n/es-ES.js +12 -0
- package/src/i18n/i18n.js +6 -1
- package/src/i18n/sv-SE.js +11 -0
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-container>
|
|
3
3
|
<v-row>
|
|
4
|
-
<v-col
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
<v-col
|
|
5
|
+
ref="playerContainer"
|
|
6
|
+
:cols="!state.expandedCaptions ? 12 : 6"
|
|
7
|
+
class="pb-0 mb-0"
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
v-if="resolvedType === 'video' && buffering"
|
|
11
|
+
class="player-overlay"
|
|
12
|
+
>
|
|
13
|
+
<div class="player-overlay--icon">
|
|
14
|
+
<v-progress-circular
|
|
15
|
+
:size="50"
|
|
16
|
+
indeterminate
|
|
17
|
+
></v-progress-circular>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div
|
|
21
|
+
v-if="resolvedType === 'video' && state.replay"
|
|
22
|
+
class="player-overlay"
|
|
23
|
+
>
|
|
24
|
+
<div class="player-overlay--icon">
|
|
25
|
+
<v-icon class="player-overlay--replay-icon">
|
|
26
|
+
mdi-replay
|
|
27
|
+
</v-icon>
|
|
28
|
+
</div>
|
|
10
29
|
</div>
|
|
11
30
|
<video
|
|
12
31
|
ref="player"
|
|
13
32
|
tabindex="0"
|
|
14
|
-
:class="'player-' +
|
|
33
|
+
:class="'player-' + resolvedType"
|
|
15
34
|
:height="attributes.height"
|
|
16
35
|
:width="attributes.width"
|
|
17
36
|
:autoplay="attributes.autoplay"
|
|
@@ -27,7 +46,7 @@
|
|
|
27
46
|
:playsinline="attributes.playsinline"
|
|
28
47
|
:poster="src.poster || attributes.poster"
|
|
29
48
|
:preload="attributes.preload"
|
|
30
|
-
@click="
|
|
49
|
+
@click="playToggle"
|
|
31
50
|
@seeking="onSeeking"
|
|
32
51
|
@timeupdate="onTimeupdate"
|
|
33
52
|
@progress="onMediaProgress"
|
|
@@ -44,6 +63,8 @@
|
|
|
44
63
|
@emptied="$emit('emptied', $event)"
|
|
45
64
|
@stalled="$emit('stalled', $event)"
|
|
46
65
|
@abort="$emit('abort', $event)"
|
|
66
|
+
@focusin="$emit('focusin', $event)"
|
|
67
|
+
@focusout="$emit('focusout', $event)"
|
|
47
68
|
>
|
|
48
69
|
<source
|
|
49
70
|
v-for="(source, index) of current.sources"
|
|
@@ -65,12 +86,13 @@
|
|
|
65
86
|
</video>
|
|
66
87
|
|
|
67
88
|
<div
|
|
89
|
+
ref="controlsContainer"
|
|
68
90
|
class="controls-container"
|
|
69
91
|
v-if="attributes.controls"
|
|
70
92
|
@mouseover="onControlsHover"
|
|
71
93
|
>
|
|
72
94
|
<v-slide-y-reverse-transition>
|
|
73
|
-
<div v-if="player &&
|
|
95
|
+
<div v-if="player && state.controls" class="controls">
|
|
74
96
|
<v-slider
|
|
75
97
|
dark
|
|
76
98
|
v-model="currentPercent"
|
|
@@ -89,25 +111,23 @@
|
|
|
89
111
|
>
|
|
90
112
|
<template #prepend>
|
|
91
113
|
<!-- Play button -->
|
|
92
|
-
<v-tooltip v-if="!
|
|
93
|
-
<template
|
|
94
|
-
v-slot:activator="{ on, attrs }"
|
|
95
|
-
>
|
|
114
|
+
<v-tooltip v-if="!state.replay" top>
|
|
115
|
+
<template #activator="{ on, attrs }">
|
|
96
116
|
<v-btn
|
|
97
117
|
small
|
|
98
118
|
text
|
|
99
119
|
v-bind="attrs"
|
|
100
120
|
v-on="on"
|
|
101
|
-
@click="
|
|
121
|
+
@click="playToggle"
|
|
102
122
|
>
|
|
103
123
|
<v-icon>{{
|
|
104
|
-
|
|
124
|
+
state.paused
|
|
105
125
|
? 'mdi-play'
|
|
106
126
|
: 'mdi-pause'
|
|
107
127
|
}}</v-icon>
|
|
108
128
|
<span class="d-sr-only">
|
|
109
129
|
{{
|
|
110
|
-
|
|
130
|
+
state.paused
|
|
111
131
|
? t(
|
|
112
132
|
language,
|
|
113
133
|
'player.play'
|
|
@@ -121,17 +141,15 @@
|
|
|
121
141
|
</v-btn>
|
|
122
142
|
</template>
|
|
123
143
|
<span>{{
|
|
124
|
-
|
|
144
|
+
state.paused
|
|
125
145
|
? t(language, 'player.play')
|
|
126
146
|
: t(language, 'player.pause')
|
|
127
147
|
}}</span>
|
|
128
148
|
</v-tooltip>
|
|
129
149
|
|
|
130
150
|
<!-- Replay button -->
|
|
131
|
-
<v-tooltip v-if="
|
|
132
|
-
<template
|
|
133
|
-
v-slot:activator="{ on, attrs }"
|
|
134
|
-
>
|
|
151
|
+
<v-tooltip v-if="state.replay" top>
|
|
152
|
+
<template #activator="{ on, attrs }">
|
|
135
153
|
<v-btn
|
|
136
154
|
small
|
|
137
155
|
text
|
|
@@ -160,15 +178,13 @@
|
|
|
160
178
|
v-if="attributes.rewind && !activeAd"
|
|
161
179
|
top
|
|
162
180
|
>
|
|
163
|
-
<template
|
|
164
|
-
v-slot:activator="{ on, attrs }"
|
|
165
|
-
>
|
|
181
|
+
<template #activator="{ on, attrs }">
|
|
166
182
|
<v-btn
|
|
167
183
|
small
|
|
168
184
|
text
|
|
169
185
|
v-bind="attrs"
|
|
170
186
|
v-on="on"
|
|
171
|
-
@click="
|
|
187
|
+
@click="rewind"
|
|
172
188
|
>
|
|
173
189
|
<v-icon>mdi-rewind-10</v-icon>
|
|
174
190
|
<span class="sr-only">{{
|
|
@@ -192,22 +208,21 @@
|
|
|
192
208
|
current.tracks &&
|
|
193
209
|
current.tracks.length > 0
|
|
194
210
|
"
|
|
211
|
+
:attach="$refs.controlsContainer"
|
|
195
212
|
open-on-hover
|
|
196
|
-
top
|
|
197
213
|
offset-y
|
|
214
|
+
top
|
|
198
215
|
>
|
|
199
|
-
<template
|
|
200
|
-
v-slot:activator="{ on, attrs }"
|
|
201
|
-
>
|
|
216
|
+
<template #activator="{ on, attrs }">
|
|
202
217
|
<v-btn
|
|
203
218
|
small
|
|
204
219
|
text
|
|
205
220
|
v-bind="attrs"
|
|
206
221
|
v-on="on"
|
|
207
|
-
@click="
|
|
222
|
+
@click="CCToggle"
|
|
208
223
|
>
|
|
209
224
|
<v-icon>{{
|
|
210
|
-
|
|
225
|
+
state.cc
|
|
211
226
|
? 'mdi-closed-caption'
|
|
212
227
|
: 'mdi-closed-caption-outline'
|
|
213
228
|
}}</v-icon>
|
|
@@ -240,45 +255,47 @@
|
|
|
240
255
|
</v-menu>
|
|
241
256
|
|
|
242
257
|
<!-- Volume -->
|
|
243
|
-
<v-menu
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
258
|
+
<v-menu
|
|
259
|
+
:attach="$refs.controlsContainer"
|
|
260
|
+
open-on-hover
|
|
261
|
+
offset-y
|
|
262
|
+
top
|
|
263
|
+
>
|
|
264
|
+
<template #activator="{ on, attrs }">
|
|
247
265
|
<v-btn
|
|
248
266
|
small
|
|
249
267
|
text
|
|
250
268
|
v-bind="attrs"
|
|
251
269
|
v-on="on"
|
|
252
|
-
@click="
|
|
270
|
+
@click="muteToggle"
|
|
253
271
|
>
|
|
254
272
|
<v-icon
|
|
255
273
|
v-if="
|
|
256
|
-
!
|
|
257
|
-
|
|
274
|
+
!state.muted &&
|
|
275
|
+
state.volume > 0.75
|
|
258
276
|
"
|
|
259
277
|
>mdi-volume-high</v-icon
|
|
260
278
|
>
|
|
261
279
|
<v-icon
|
|
262
280
|
v-if="
|
|
263
|
-
!
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
options.volume <= 0.75
|
|
281
|
+
!state.muted &&
|
|
282
|
+
state.volume >= 0.25 &&
|
|
283
|
+
state.volume <= 0.75
|
|
267
284
|
"
|
|
268
285
|
>mdi-volume-medium</v-icon
|
|
269
286
|
>
|
|
270
287
|
<v-icon
|
|
271
288
|
v-if="
|
|
272
|
-
!
|
|
273
|
-
|
|
274
|
-
|
|
289
|
+
!state.muted &&
|
|
290
|
+
state.volume > 0 &&
|
|
291
|
+
state.volume < 0.25
|
|
275
292
|
"
|
|
276
293
|
>mdi-volume-low</v-icon
|
|
277
294
|
>
|
|
278
295
|
<v-icon
|
|
279
296
|
v-if="
|
|
280
|
-
|
|
281
|
-
|
|
297
|
+
state.muted ||
|
|
298
|
+
state.volume === 0
|
|
282
299
|
"
|
|
283
300
|
>mdi-volume-off</v-icon
|
|
284
301
|
>
|
|
@@ -299,31 +316,29 @@
|
|
|
299
316
|
)
|
|
300
317
|
}}</span>
|
|
301
318
|
<v-slider
|
|
302
|
-
v-model="
|
|
319
|
+
v-model="state.volume"
|
|
303
320
|
inverse-label
|
|
304
321
|
:min="0"
|
|
305
322
|
:max="1"
|
|
306
323
|
:step="0.1"
|
|
307
324
|
vertical
|
|
308
|
-
@change="
|
|
325
|
+
@change="volumeChange"
|
|
309
326
|
></v-slider>
|
|
310
327
|
</v-sheet>
|
|
311
328
|
</v-menu>
|
|
312
329
|
|
|
313
330
|
<!-- Fullscreen -->
|
|
314
|
-
<v-tooltip v-if="
|
|
315
|
-
<template
|
|
316
|
-
v-slot:activator="{ on, attrs }"
|
|
317
|
-
>
|
|
331
|
+
<v-tooltip v-if="allowFullscreen" top>
|
|
332
|
+
<template #activator="{ on, attrs }">
|
|
318
333
|
<v-btn
|
|
319
334
|
small
|
|
320
335
|
text
|
|
321
336
|
v-bind="attrs"
|
|
322
337
|
v-on="on"
|
|
323
|
-
@click="
|
|
338
|
+
@click="fullscreenToggle"
|
|
324
339
|
>
|
|
325
340
|
<v-icon>{{
|
|
326
|
-
!
|
|
341
|
+
!state.fullscreen
|
|
327
342
|
? 'mdi-fullscreen'
|
|
328
343
|
: 'mdi-fullscreen-exit'
|
|
329
344
|
}}</v-icon>
|
|
@@ -350,9 +365,7 @@
|
|
|
350
365
|
"
|
|
351
366
|
top
|
|
352
367
|
>
|
|
353
|
-
<template
|
|
354
|
-
v-slot:activator="{ on, attrs }"
|
|
355
|
-
>
|
|
368
|
+
<template #activator="{ on, attrs }">
|
|
356
369
|
<v-btn
|
|
357
370
|
small
|
|
358
371
|
text
|
|
@@ -380,13 +393,8 @@
|
|
|
380
393
|
</v-tooltip>
|
|
381
394
|
|
|
382
395
|
<!-- Remote playback -->
|
|
383
|
-
<v-tooltip
|
|
384
|
-
|
|
385
|
-
top
|
|
386
|
-
>
|
|
387
|
-
<template
|
|
388
|
-
v-slot:activator="{ on, attrs }"
|
|
389
|
-
>
|
|
396
|
+
<v-tooltip v-if="allowRemotePlayback" top>
|
|
397
|
+
<template #activator="{ on, attrs }">
|
|
390
398
|
<v-btn
|
|
391
399
|
small
|
|
392
400
|
text
|
|
@@ -412,10 +420,8 @@
|
|
|
412
420
|
</v-tooltip>
|
|
413
421
|
|
|
414
422
|
<!-- Download -->
|
|
415
|
-
<v-tooltip v-if="
|
|
416
|
-
<template
|
|
417
|
-
v-slot:activator="{ on, attrs }"
|
|
418
|
-
>
|
|
423
|
+
<v-tooltip v-if="allowDownload" top>
|
|
424
|
+
<template #activator="{ on, attrs }">
|
|
419
425
|
<v-btn
|
|
420
426
|
small
|
|
421
427
|
text
|
|
@@ -438,117 +444,18 @@
|
|
|
438
444
|
</v-tooltip>
|
|
439
445
|
|
|
440
446
|
<!-- Settings -->
|
|
441
|
-
<
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
:
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
v-bind="attrs"
|
|
454
|
-
v-on="on"
|
|
455
|
-
>
|
|
456
|
-
<v-icon>mdi-cog</v-icon>
|
|
457
|
-
<span class="d-sr-only">{{
|
|
458
|
-
t(
|
|
459
|
-
language,
|
|
460
|
-
'player.toggle_settings'
|
|
461
|
-
)
|
|
462
|
-
}}</span>
|
|
463
|
-
</v-btn>
|
|
464
|
-
</template>
|
|
465
|
-
|
|
466
|
-
<v-list>
|
|
467
|
-
<v-list-item>
|
|
468
|
-
<v-list-item-title>
|
|
469
|
-
<v-icon
|
|
470
|
-
>mdi-play-speed</v-icon
|
|
471
|
-
>
|
|
472
|
-
{{
|
|
473
|
-
t(
|
|
474
|
-
language,
|
|
475
|
-
'player.playback_speed'
|
|
476
|
-
)
|
|
477
|
-
}}
|
|
478
|
-
</v-list-item-title>
|
|
479
|
-
</v-list-item>
|
|
480
|
-
<v-list-item>
|
|
481
|
-
<v-list-item-title
|
|
482
|
-
class="text-center"
|
|
483
|
-
>
|
|
484
|
-
<v-btn
|
|
485
|
-
small
|
|
486
|
-
:disabled="
|
|
487
|
-
options.playbackRateIndex ===
|
|
488
|
-
0
|
|
489
|
-
"
|
|
490
|
-
@click="
|
|
491
|
-
onPlaybackSpeed(
|
|
492
|
-
options.playbackRateIndex -
|
|
493
|
-
1
|
|
494
|
-
)
|
|
495
|
-
"
|
|
496
|
-
>
|
|
497
|
-
<v-icon>
|
|
498
|
-
mdi-clock-minus-outline
|
|
499
|
-
</v-icon>
|
|
500
|
-
<span
|
|
501
|
-
class="d-sr-only"
|
|
502
|
-
>{{
|
|
503
|
-
t(
|
|
504
|
-
language,
|
|
505
|
-
'player.playback_decrease'
|
|
506
|
-
)
|
|
507
|
-
}}</span
|
|
508
|
-
>
|
|
509
|
-
</v-btn>
|
|
510
|
-
<span class="pl-2 pr-2"
|
|
511
|
-
>{{
|
|
512
|
-
attributes
|
|
513
|
-
.playbackrates[
|
|
514
|
-
options
|
|
515
|
-
.playbackRateIndex
|
|
516
|
-
]
|
|
517
|
-
}}x</span
|
|
518
|
-
>
|
|
519
|
-
<v-btn
|
|
520
|
-
small
|
|
521
|
-
:disabled="
|
|
522
|
-
options.playbackRateIndex >=
|
|
523
|
-
attributes
|
|
524
|
-
.playbackrates
|
|
525
|
-
.length -
|
|
526
|
-
1
|
|
527
|
-
"
|
|
528
|
-
@click="
|
|
529
|
-
onPlaybackSpeed(
|
|
530
|
-
options.playbackRateIndex +
|
|
531
|
-
1
|
|
532
|
-
)
|
|
533
|
-
"
|
|
534
|
-
>
|
|
535
|
-
<v-icon>
|
|
536
|
-
mdi-clock-plus-outline
|
|
537
|
-
</v-icon>
|
|
538
|
-
<span
|
|
539
|
-
class="d-sr-only"
|
|
540
|
-
>{{
|
|
541
|
-
t(
|
|
542
|
-
language,
|
|
543
|
-
'player.playback_increase'
|
|
544
|
-
)
|
|
545
|
-
}}</span
|
|
546
|
-
>
|
|
547
|
-
</v-btn>
|
|
548
|
-
</v-list-item-title>
|
|
549
|
-
</v-list-item>
|
|
550
|
-
</v-list>
|
|
551
|
-
</v-menu>
|
|
447
|
+
<SettingsMenu
|
|
448
|
+
:attach="$refs.controlsContainer"
|
|
449
|
+
:state="state"
|
|
450
|
+
:attributes="attributes"
|
|
451
|
+
:language="language"
|
|
452
|
+
:captions-visible.sync="
|
|
453
|
+
captionsVisibleState
|
|
454
|
+
"
|
|
455
|
+
@change:playback-rate-index="
|
|
456
|
+
onPlaybackSpeedChange
|
|
457
|
+
"
|
|
458
|
+
></SettingsMenu>
|
|
552
459
|
</template>
|
|
553
460
|
</v-slider>
|
|
554
461
|
</div>
|
|
@@ -564,14 +471,33 @@
|
|
|
564
471
|
captions.cues &&
|
|
565
472
|
Object.keys(captions.cues).length
|
|
566
473
|
"
|
|
567
|
-
:cols="!
|
|
474
|
+
:cols="!state.expandedCaptions ? 12 : 6"
|
|
475
|
+
class="pt-0 mt-0"
|
|
568
476
|
>
|
|
569
477
|
<CaptionsMenu
|
|
570
478
|
v-model="captions"
|
|
571
479
|
:language="language"
|
|
480
|
+
:expanded.sync="captionsExpandedState"
|
|
481
|
+
:hide-expand="captionsHideExpand"
|
|
482
|
+
:paragraph-view="captionsParagraphView"
|
|
483
|
+
:hide-paragraph-view="captionsHideParagraphView"
|
|
484
|
+
:autoscroll="captionsAutoscroll"
|
|
485
|
+
:visible.sync="captionsVisibleState"
|
|
486
|
+
:hide-autoscroll="captionsHideAutoscroll"
|
|
487
|
+
:hide-close="captionsHideClose"
|
|
488
|
+
:elevation="elevation"
|
|
489
|
+
@update:paragraph-view="
|
|
490
|
+
$emit('update:captions-paragraph-view', $event)
|
|
491
|
+
"
|
|
492
|
+
@update:autoscroll="
|
|
493
|
+
$emit('update:captions-autoscroll', $event)
|
|
494
|
+
"
|
|
495
|
+
@update:close="$emit('update:captions-visible', $event)"
|
|
572
496
|
@click:cue="onCueClick"
|
|
573
497
|
@click:expand="onClickExpandCaptions"
|
|
574
|
-
@click:paragraph="onClickParagraph"
|
|
498
|
+
@click:paragraph-view="onClickParagraph"
|
|
499
|
+
@click:autoscroll="onClickAutoscroll"
|
|
500
|
+
@click:close="onClickCaptionsClose"
|
|
575
501
|
></CaptionsMenu>
|
|
576
502
|
</v-col>
|
|
577
503
|
</v-row>
|
|
@@ -580,12 +506,14 @@
|
|
|
580
506
|
|
|
581
507
|
<script>
|
|
582
508
|
import filters from '../filters'
|
|
509
|
+
import SettingsMenu from './SettingsMenu.vue'
|
|
583
510
|
import CaptionsMenu from './CaptionsMenu.vue'
|
|
584
511
|
import { t } from '../../i18n/i18n'
|
|
585
512
|
|
|
586
513
|
export default {
|
|
587
514
|
name: 'Html5Player',
|
|
588
515
|
components: {
|
|
516
|
+
SettingsMenu,
|
|
589
517
|
CaptionsMenu,
|
|
590
518
|
},
|
|
591
519
|
props: {
|
|
@@ -593,7 +521,7 @@ export default {
|
|
|
593
521
|
type: {
|
|
594
522
|
type: String,
|
|
595
523
|
required: false,
|
|
596
|
-
default: '
|
|
524
|
+
default: 'auto',
|
|
597
525
|
},
|
|
598
526
|
attributes: {
|
|
599
527
|
type: Object,
|
|
@@ -603,8 +531,85 @@ export default {
|
|
|
603
531
|
type: Object,
|
|
604
532
|
required: true,
|
|
605
533
|
},
|
|
534
|
+
captionsExpanded: {
|
|
535
|
+
type: Boolean,
|
|
536
|
+
required: false,
|
|
537
|
+
default: undefined,
|
|
538
|
+
},
|
|
539
|
+
captionsHideExpand: { type: Boolean, required: false, default: true },
|
|
540
|
+
captionsParagraphView: {
|
|
541
|
+
type: Boolean,
|
|
542
|
+
required: false,
|
|
543
|
+
default: undefined,
|
|
544
|
+
},
|
|
545
|
+
captionsHideParagraphView: {
|
|
546
|
+
type: Boolean,
|
|
547
|
+
required: false,
|
|
548
|
+
default: false,
|
|
549
|
+
},
|
|
550
|
+
captionsAutoscroll: {
|
|
551
|
+
type: Boolean,
|
|
552
|
+
required: false,
|
|
553
|
+
default: undefined,
|
|
554
|
+
},
|
|
555
|
+
captionsVisible: {
|
|
556
|
+
type: Boolean,
|
|
557
|
+
required: false,
|
|
558
|
+
default: undefined,
|
|
559
|
+
},
|
|
560
|
+
captionsHideAutoscroll: {
|
|
561
|
+
type: Boolean,
|
|
562
|
+
required: false,
|
|
563
|
+
default: false,
|
|
564
|
+
},
|
|
565
|
+
captionsHideClose: {
|
|
566
|
+
type: Boolean,
|
|
567
|
+
required: false,
|
|
568
|
+
default: false,
|
|
569
|
+
},
|
|
570
|
+
elevation: { type: [Number, String], required: false, default: 2 },
|
|
571
|
+
},
|
|
572
|
+
emits: [
|
|
573
|
+
'error',
|
|
574
|
+
'canplaythrough',
|
|
575
|
+
'emptied',
|
|
576
|
+
'stalled',
|
|
577
|
+
'abort',
|
|
578
|
+
'canplay',
|
|
579
|
+
'waiting',
|
|
580
|
+
'play',
|
|
581
|
+
'pause',
|
|
582
|
+
'load',
|
|
583
|
+
'mouseover',
|
|
584
|
+
'mouseout',
|
|
585
|
+
'ended',
|
|
586
|
+
'trackchange',
|
|
587
|
+
'ratechange',
|
|
588
|
+
'timeupdate',
|
|
589
|
+
'seeking',
|
|
590
|
+
'progress',
|
|
591
|
+
'volumechange',
|
|
592
|
+
'cuechange',
|
|
593
|
+
'loadeddata',
|
|
594
|
+
'loadedmetadata',
|
|
595
|
+
'click:fullscreen',
|
|
596
|
+
'click:pictureinpicture',
|
|
597
|
+
'click:remoteplayback',
|
|
598
|
+
'click:captions-expand',
|
|
599
|
+
'click:captions-paragraph-view',
|
|
600
|
+
'click:captions-autoscroll',
|
|
601
|
+
'click:captions-close',
|
|
602
|
+
'click:captions-cue',
|
|
603
|
+
'update:captions-expanded',
|
|
604
|
+
'update:captions-paragraph-view',
|
|
605
|
+
'update:captions-autoscroll',
|
|
606
|
+
'update:captions-visible',
|
|
607
|
+
],
|
|
608
|
+
watch: {
|
|
609
|
+
'state.controls': function () {
|
|
610
|
+
this.setCuePosition()
|
|
611
|
+
},
|
|
606
612
|
},
|
|
607
|
-
watch: {},
|
|
608
613
|
computed: {
|
|
609
614
|
current() {
|
|
610
615
|
// We're playing an ad currently
|
|
@@ -616,9 +621,98 @@ export default {
|
|
|
616
621
|
}
|
|
617
622
|
},
|
|
618
623
|
playerClass() {
|
|
619
|
-
let classList = 'player-' + this.
|
|
624
|
+
let classList = 'player-' + this.resolvedType
|
|
620
625
|
return classList
|
|
621
626
|
},
|
|
627
|
+
resolvedType() {
|
|
628
|
+
// Default to video if the type can't be resolved
|
|
629
|
+
let type = 'video'
|
|
630
|
+
|
|
631
|
+
// Make sure current is set and valid and has sources
|
|
632
|
+
if (
|
|
633
|
+
this.current &&
|
|
634
|
+
this.current.sources &&
|
|
635
|
+
this.current.sources.length > 0
|
|
636
|
+
) {
|
|
637
|
+
const source = this.current.sources[0]
|
|
638
|
+
|
|
639
|
+
// Determine off the type / mime field first, then check the extensions
|
|
640
|
+
if (source.type && source.type.match(/^video\//i)) {
|
|
641
|
+
type = 'video'
|
|
642
|
+
} else if (source.type && source.type.match(/^audio\//i)) {
|
|
643
|
+
type = 'audio'
|
|
644
|
+
} else if (
|
|
645
|
+
source.src &&
|
|
646
|
+
source.src.match(/(?:mp4|webm|ogg)$/)
|
|
647
|
+
) {
|
|
648
|
+
type = 'video'
|
|
649
|
+
} else if (source.src && source.src.match(/(?:mp3|wav)$/)) {
|
|
650
|
+
type = 'audio'
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
return type
|
|
655
|
+
},
|
|
656
|
+
captionsVisibleState: {
|
|
657
|
+
get() {
|
|
658
|
+
if (typeof this.captionsVisible !== 'undefined') {
|
|
659
|
+
return this.captionsVisible
|
|
660
|
+
} else {
|
|
661
|
+
return this.state.captionsVisible
|
|
662
|
+
}
|
|
663
|
+
},
|
|
664
|
+
set(v) {
|
|
665
|
+
this.$emit('update:captions-visible', v)
|
|
666
|
+
this.state.captionsVisible = v
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
captionsExpandedState: {
|
|
670
|
+
get() {
|
|
671
|
+
if (typeof this.captionsExpanded !== 'undefined') {
|
|
672
|
+
return this.captionsExpanded
|
|
673
|
+
} else {
|
|
674
|
+
return this.state.expandedCaptions
|
|
675
|
+
}
|
|
676
|
+
},
|
|
677
|
+
set(v) {
|
|
678
|
+
this.$emit('update:captions-expanded', v)
|
|
679
|
+
this.state.expandedCaptions = v
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
allowFullscreen() {
|
|
683
|
+
// Determine fullscreen settings
|
|
684
|
+
// If we explicitly disabled fullscreen in the attributes
|
|
685
|
+
// Or the browser doesn't support fullscreen
|
|
686
|
+
// Or we passed the HTML nofullscreen attribute
|
|
687
|
+
if (
|
|
688
|
+
this.attributes.playsinline ||
|
|
689
|
+
!document.fullscreenEnabled ||
|
|
690
|
+
this.state.controlslist.indexOf('nofullscreen') !== -1
|
|
691
|
+
) {
|
|
692
|
+
return false
|
|
693
|
+
} else {
|
|
694
|
+
return true
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
allowRemotePlayback() {
|
|
698
|
+
// Determine remote playback settings
|
|
699
|
+
if (
|
|
700
|
+
this.attributes.disableremoteplayback ||
|
|
701
|
+
this.state.controlslist.indexOf('noremoteplayback') !== -1
|
|
702
|
+
) {
|
|
703
|
+
return false
|
|
704
|
+
} else {
|
|
705
|
+
return true
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
allowDownload() {
|
|
709
|
+
// Determine download settings
|
|
710
|
+
if (this.state.controlslist.indexOf('nodownload') !== -1) {
|
|
711
|
+
return false
|
|
712
|
+
} else {
|
|
713
|
+
return true
|
|
714
|
+
}
|
|
715
|
+
},
|
|
622
716
|
},
|
|
623
717
|
data() {
|
|
624
718
|
return {
|
|
@@ -629,8 +723,8 @@ export default {
|
|
|
629
723
|
currentPercent: 0,
|
|
630
724
|
player: {},
|
|
631
725
|
captions: { nonce: 0 },
|
|
632
|
-
|
|
633
|
-
|
|
726
|
+
state: {
|
|
727
|
+
replay: false,
|
|
634
728
|
cc: true,
|
|
635
729
|
ccLang: this.language,
|
|
636
730
|
controls: true,
|
|
@@ -641,24 +735,22 @@ export default {
|
|
|
641
735
|
playbackRateIndex: 0,
|
|
642
736
|
fullscreen: false,
|
|
643
737
|
expandedCaptions: false,
|
|
644
|
-
|
|
645
|
-
remoteplayback: false,
|
|
738
|
+
captionsVisible: true,
|
|
646
739
|
controlslist: [],
|
|
647
740
|
},
|
|
648
741
|
watchPlayer: 0,
|
|
649
742
|
scrub: { max: 100 },
|
|
650
743
|
buffering: false,
|
|
651
|
-
showReplay: false,
|
|
652
744
|
}
|
|
653
745
|
},
|
|
654
746
|
beforeMount() {
|
|
655
|
-
// Parse the controlslist string
|
|
747
|
+
// Parse the html controlslist attribute string
|
|
656
748
|
if (
|
|
657
749
|
this.attributes.controlslist &&
|
|
658
750
|
typeof this.attributes.controlslist === 'string' &&
|
|
659
751
|
this.attributes.controlslist !== ''
|
|
660
752
|
) {
|
|
661
|
-
this.
|
|
753
|
+
this.state.controlslist = this.attributes.controlslist.split(' ')
|
|
662
754
|
}
|
|
663
755
|
|
|
664
756
|
if (
|
|
@@ -672,12 +764,12 @@ export default {
|
|
|
672
764
|
|
|
673
765
|
// Adjust the playback speed to 1 by default
|
|
674
766
|
if (this.attributes.playbackrates.indexOf(1) !== -1) {
|
|
675
|
-
this.
|
|
767
|
+
this.state.playbackRateIndex =
|
|
676
768
|
this.attributes.playbackrates.indexOf(1)
|
|
677
769
|
} else {
|
|
678
770
|
// 1 aka normal playback not enabled (What monster would do this?!)
|
|
679
771
|
// Set the playback rate to "middle of the road" for whatever is available
|
|
680
|
-
this.
|
|
772
|
+
this.state.playbackRateIndex = Math.floor(
|
|
681
773
|
this.attributes.playbackrates.length / 2
|
|
682
774
|
)
|
|
683
775
|
}
|
|
@@ -690,34 +782,6 @@ export default {
|
|
|
690
782
|
this.ads[ad.play_at_percent].complete = false
|
|
691
783
|
}
|
|
692
784
|
}
|
|
693
|
-
|
|
694
|
-
// Determine fullscreen settings
|
|
695
|
-
if (
|
|
696
|
-
this.attributes.playsinline ||
|
|
697
|
-
!document.fullscreenEnabled ||
|
|
698
|
-
this.options.controlslist.indexOf('nofullscreen') !== -1
|
|
699
|
-
) {
|
|
700
|
-
this.fullscreenEnabled = false
|
|
701
|
-
} else {
|
|
702
|
-
this.fullscreenEnabled = true
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
// Determine remote playback settings
|
|
706
|
-
if (
|
|
707
|
-
this.attributes.disableremoteplayback ||
|
|
708
|
-
this.options.controlslist.indexOf('noremoteplayback') !== -1
|
|
709
|
-
) {
|
|
710
|
-
this.options.remoteplayback = false
|
|
711
|
-
} else {
|
|
712
|
-
this.options.remoteplayback = true
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
// Determine download settings
|
|
716
|
-
if (this.options.controlslist.indexOf('nodownload') !== -1) {
|
|
717
|
-
this.options.download = false
|
|
718
|
-
} else {
|
|
719
|
-
this.options.download = true
|
|
720
|
-
}
|
|
721
785
|
},
|
|
722
786
|
mounted() {
|
|
723
787
|
if (
|
|
@@ -753,34 +817,45 @@ export default {
|
|
|
753
817
|
},
|
|
754
818
|
onCueClick(time) {
|
|
755
819
|
this.setTime(time)
|
|
820
|
+
this.$emit('click:captions-cue', time)
|
|
756
821
|
},
|
|
757
822
|
onClickExpandCaptions(expanded) {
|
|
758
|
-
this.options.expandedCaptions = expanded
|
|
759
823
|
this.$emit('click:captions-expand', expanded)
|
|
760
824
|
},
|
|
761
825
|
onClickParagraph(isParagraph) {
|
|
762
|
-
this.$emit('click:captions-paragraph', isParagraph)
|
|
826
|
+
this.$emit('click:captions-paragraph-view', isParagraph)
|
|
827
|
+
},
|
|
828
|
+
onClickAutoscroll(autoscroll) {
|
|
829
|
+
this.$emit('click:captions-autoscroll', autoscroll)
|
|
830
|
+
},
|
|
831
|
+
onClickCaptionsClose() {
|
|
832
|
+
this.state.captionsVisible = false
|
|
833
|
+
this.$emit('click:captions-close')
|
|
763
834
|
},
|
|
764
835
|
onDownload() {
|
|
765
836
|
window.open(this.src.sources[0].src, '_blank')
|
|
766
837
|
},
|
|
767
|
-
|
|
768
|
-
// Rewind in seconds
|
|
769
|
-
const seconds = 10
|
|
770
|
-
|
|
838
|
+
rewind(seconds = 10) {
|
|
771
839
|
if (this.player.currentTime <= seconds) {
|
|
772
840
|
this.setTime(0)
|
|
773
841
|
} else {
|
|
774
842
|
this.setTime(this.player.currentTime - seconds)
|
|
775
843
|
}
|
|
776
844
|
},
|
|
777
|
-
|
|
778
|
-
this.
|
|
845
|
+
fastForward(seconds = 10) {
|
|
846
|
+
if (this.player.currentTime + seconds >= this.player.duration) {
|
|
847
|
+
this.setTime(this.player.duration)
|
|
848
|
+
} else {
|
|
849
|
+
this.setTime(this.player.currentTime + seconds)
|
|
850
|
+
}
|
|
851
|
+
},
|
|
852
|
+
fullscreenToggle() {
|
|
853
|
+
this.state.fullscreen = !document.fullscreenElement
|
|
779
854
|
// Return the whole element to be fullscreened so the controls come with it
|
|
780
|
-
this.$emit('click:fullscreen', this.$
|
|
855
|
+
this.$emit('click:fullscreen', this.$refs.playerContainer)
|
|
781
856
|
},
|
|
782
857
|
onPictureInPicture() {
|
|
783
|
-
//this.
|
|
858
|
+
//this.state.pip = !document.fullscreenElement;
|
|
784
859
|
// Return the player aka HTMLVideoElement
|
|
785
860
|
this.$emit('click:pictureinpicture', this.$refs.player)
|
|
786
861
|
},
|
|
@@ -788,16 +863,16 @@ export default {
|
|
|
788
863
|
this.$emit('click:remoteplayback', this.$refs.player)
|
|
789
864
|
},
|
|
790
865
|
onVideoHover(e) {
|
|
791
|
-
this.
|
|
792
|
-
clearTimeout(this.
|
|
866
|
+
this.state.controls = true
|
|
867
|
+
clearTimeout(this.state.controlsDebounce)
|
|
793
868
|
this.$emit('mouseover', e)
|
|
794
869
|
},
|
|
795
870
|
onVideoLeave(e) {
|
|
796
871
|
const self = this
|
|
797
872
|
// Clear any existing timeouts before we create one
|
|
798
|
-
clearTimeout(this.
|
|
799
|
-
this.
|
|
800
|
-
self.
|
|
873
|
+
clearTimeout(this.state.controlsDebounce)
|
|
874
|
+
this.state.controlsDebounce = setTimeout(() => {
|
|
875
|
+
self.state.controls = false
|
|
801
876
|
}, 50)
|
|
802
877
|
this.$emit('mouseout', e)
|
|
803
878
|
},
|
|
@@ -828,25 +903,25 @@ export default {
|
|
|
828
903
|
this.activeAd !== null &&
|
|
829
904
|
this.activeAd.play_at_percent === 100
|
|
830
905
|
) {
|
|
831
|
-
this.
|
|
906
|
+
this.state.replay = true
|
|
832
907
|
// Ended but this ad was a postroll
|
|
833
908
|
this.$emit('ended', e)
|
|
834
909
|
} else {
|
|
835
|
-
this.
|
|
910
|
+
this.state.replay = true
|
|
836
911
|
// Ended without an ad
|
|
837
912
|
this.$emit('ended', e)
|
|
838
913
|
}
|
|
839
914
|
},
|
|
840
915
|
onControlsHover() {
|
|
841
|
-
clearTimeout(this.
|
|
842
|
-
this.
|
|
916
|
+
clearTimeout(this.state.controlsDebounce)
|
|
917
|
+
this.state.controls = true
|
|
843
918
|
},
|
|
844
919
|
onControlsLeave() {
|
|
845
920
|
const self = this
|
|
846
921
|
// Clear any existing timeouts before we create one
|
|
847
|
-
clearTimeout(this.
|
|
848
|
-
this.
|
|
849
|
-
self.
|
|
922
|
+
clearTimeout(this.state.controlsDebounce)
|
|
923
|
+
this.state.controlsDebounce = setTimeout(() => {
|
|
924
|
+
self.state.controls = false
|
|
850
925
|
}, 50)
|
|
851
926
|
},
|
|
852
927
|
/**
|
|
@@ -857,25 +932,25 @@ export default {
|
|
|
857
932
|
onSelectTrack(lang = null) {
|
|
858
933
|
if (this.player.textTracks && this.player.textTracks.length > 0) {
|
|
859
934
|
for (let i = 0; i < this.player.textTracks.length; i++) {
|
|
860
|
-
|
|
935
|
+
// Disable all tracks by default
|
|
936
|
+
// We only want to enable the correct active track otherwise track switches / replays will overlay tracks
|
|
937
|
+
this.player.textTracks[i].mode = 'disabled'
|
|
861
938
|
|
|
862
|
-
if (
|
|
863
|
-
this.
|
|
939
|
+
if (this.player.textTracks[i].language === lang) {
|
|
940
|
+
this.state.ccLang = lang
|
|
864
941
|
this.player.textTracks[i].mode = 'showing'
|
|
865
942
|
|
|
866
|
-
this.setCues(
|
|
943
|
+
this.setCues(this.player.textTracks[i])
|
|
867
944
|
|
|
868
945
|
// Emit the current track
|
|
869
|
-
this.$emit('trackchange',
|
|
870
|
-
} else {
|
|
871
|
-
this.player.textTracks[i].mode = 'disabled'
|
|
946
|
+
this.$emit('trackchange', this.player.textTracks[i])
|
|
872
947
|
}
|
|
873
948
|
}
|
|
874
949
|
}
|
|
875
950
|
},
|
|
876
|
-
|
|
951
|
+
onPlaybackSpeedChange(index) {
|
|
877
952
|
this.player.playbackRate = this.attributes.playbackrates[index]
|
|
878
|
-
this.
|
|
953
|
+
this.state.playbackRateIndex = index
|
|
879
954
|
this.$emit('ratechange', this.player.playbackRate)
|
|
880
955
|
},
|
|
881
956
|
onTimeupdate(e) {
|
|
@@ -905,31 +980,15 @@ export default {
|
|
|
905
980
|
onMediaProgress(e) {
|
|
906
981
|
this.$emit('progress', e)
|
|
907
982
|
},
|
|
908
|
-
|
|
909
|
-
this.
|
|
983
|
+
CCToggle() {
|
|
984
|
+
this.state.cc = !this.state.cc
|
|
910
985
|
|
|
911
|
-
if (this.
|
|
912
|
-
this.onSelectTrack(this.
|
|
986
|
+
if (this.state.cc) {
|
|
987
|
+
this.onSelectTrack(this.state.ccLang)
|
|
913
988
|
} else {
|
|
914
989
|
this.onSelectTrack()
|
|
915
990
|
}
|
|
916
991
|
},
|
|
917
|
-
onPlayToggle(e) {
|
|
918
|
-
const self = this
|
|
919
|
-
this.options.controls = true
|
|
920
|
-
|
|
921
|
-
// Clear any existing timeouts and close the controls in 5 seconds
|
|
922
|
-
clearTimeout(this.options.controlsDebounce)
|
|
923
|
-
this.options.controlsDebounce = setTimeout(() => {
|
|
924
|
-
self.options.controls = false
|
|
925
|
-
}, 5000)
|
|
926
|
-
|
|
927
|
-
if (this.player.paused) {
|
|
928
|
-
this.play(e)
|
|
929
|
-
} else {
|
|
930
|
-
this.pause(e)
|
|
931
|
-
}
|
|
932
|
-
},
|
|
933
992
|
onClickReplay(e) {
|
|
934
993
|
// Re-initialize the ads aka pre/post/midroll
|
|
935
994
|
if (this.src.ads && this.src.ads.length) {
|
|
@@ -955,13 +1014,13 @@ export default {
|
|
|
955
1014
|
// Restart from the beginning
|
|
956
1015
|
this.setTime(0)
|
|
957
1016
|
},
|
|
958
|
-
|
|
1017
|
+
muteToggle() {
|
|
959
1018
|
if (this.player.muted) {
|
|
960
|
-
this.
|
|
1019
|
+
this.state.muted = false
|
|
961
1020
|
this.player.muted = false
|
|
962
|
-
this.$emit('volumechange', this.
|
|
1021
|
+
this.$emit('volumechange', this.state.volume)
|
|
963
1022
|
} else {
|
|
964
|
-
this.
|
|
1023
|
+
this.state.muted = true
|
|
965
1024
|
this.player.muted = true
|
|
966
1025
|
this.$emit('volumechange', 0)
|
|
967
1026
|
}
|
|
@@ -994,6 +1053,15 @@ export default {
|
|
|
994
1053
|
if (typeof track.activeCues[0].rawText === 'undefined') {
|
|
995
1054
|
track.activeCues[0].rawText = track.activeCues[0].text
|
|
996
1055
|
}
|
|
1056
|
+
// Retain the original cue display values
|
|
1057
|
+
// This way we can swap between a modified display when the controls are visible
|
|
1058
|
+
if (typeof track.activeCues[0].defaults === 'undefined') {
|
|
1059
|
+
track.activeCues[0].defaults = {
|
|
1060
|
+
line: track.activeCues[0].line,
|
|
1061
|
+
size: track.activeCues[0].size,
|
|
1062
|
+
snapToLines: track.activeCues[0].snapToLines,
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
997
1065
|
|
|
998
1066
|
// Now remove `<c.transcript>` tags
|
|
999
1067
|
const transcriptTagRegex = /<c.transcript>.*?<\/c>/gi
|
|
@@ -1003,6 +1071,8 @@ export default {
|
|
|
1003
1071
|
transcriptTagRegex,
|
|
1004
1072
|
''
|
|
1005
1073
|
)
|
|
1074
|
+
|
|
1075
|
+
this.setCuePosition()
|
|
1006
1076
|
}
|
|
1007
1077
|
|
|
1008
1078
|
this.setCues(track)
|
|
@@ -1032,19 +1102,31 @@ export default {
|
|
|
1032
1102
|
//this.player.media = this.$refs.player;
|
|
1033
1103
|
this.$emit('loadedmetadata', e)
|
|
1034
1104
|
this.player = this.$refs.player
|
|
1035
|
-
this.player.volume = this.
|
|
1036
|
-
this.$emit('volumechange', this.
|
|
1105
|
+
this.player.volume = this.state.volume
|
|
1106
|
+
this.$emit('volumechange', this.state.volume)
|
|
1037
1107
|
},
|
|
1038
|
-
|
|
1039
|
-
|
|
1108
|
+
volumeChange(value) {
|
|
1109
|
+
// Value needs to be a decimal value between 0 and 1
|
|
1110
|
+
if (value > 1) {
|
|
1111
|
+
value = 1
|
|
1112
|
+
} else if (value < 0) {
|
|
1113
|
+
value = 0
|
|
1114
|
+
}
|
|
1115
|
+
this.state.volume = value
|
|
1040
1116
|
this.player.volume = value
|
|
1041
1117
|
this.$emit('volumechange', value)
|
|
1042
1118
|
},
|
|
1119
|
+
volumeAdjust(value) {
|
|
1120
|
+
const newVolume = this.state.volume + value
|
|
1121
|
+
this.volumeChange(newVolume)
|
|
1122
|
+
},
|
|
1043
1123
|
onDurationChange() {
|
|
1044
1124
|
// console.log('onDurationChange');
|
|
1045
1125
|
// console.log(e);
|
|
1046
1126
|
},
|
|
1047
1127
|
setTime(time) {
|
|
1128
|
+
// Scrubbing / manually setting the time should remove the replay button
|
|
1129
|
+
this.state.replay = false
|
|
1048
1130
|
this.player.currentTime = time
|
|
1049
1131
|
},
|
|
1050
1132
|
setCues(track) {
|
|
@@ -1056,19 +1138,76 @@ export default {
|
|
|
1056
1138
|
// Required so the v-model will actually update.
|
|
1057
1139
|
this.captions.nonce = Math.random()
|
|
1058
1140
|
},
|
|
1141
|
+
setCuePosition() {
|
|
1142
|
+
if (
|
|
1143
|
+
this.player &&
|
|
1144
|
+
this.player.textTracks &&
|
|
1145
|
+
this.player.textTracks.length > 0
|
|
1146
|
+
) {
|
|
1147
|
+
for (let i = 0; i < this.player.textTracks.length; i++) {
|
|
1148
|
+
// Only alter the currently showing text track
|
|
1149
|
+
if (this.player.textTracks[i].mode === 'showing') {
|
|
1150
|
+
// If the controls are showing then bump the alignment to the start
|
|
1151
|
+
if (
|
|
1152
|
+
this.state.controls &&
|
|
1153
|
+
this.player.textTracks[i].activeCues &&
|
|
1154
|
+
this.player.textTracks[i].activeCues.length > 0
|
|
1155
|
+
) {
|
|
1156
|
+
// Count the number of line breaks in the cue to figure out our offset from the bottom
|
|
1157
|
+
// VTTCue doesn't have a "margin from bottom" by default
|
|
1158
|
+
const numLines = (
|
|
1159
|
+
this.player.textTracks[
|
|
1160
|
+
i
|
|
1161
|
+
].activeCues[0].text.match(/\n/g) || []
|
|
1162
|
+
).length
|
|
1163
|
+
|
|
1164
|
+
// Limit the cues to 90% of the screen width
|
|
1165
|
+
// If this is left default / set to 100 then the above line
|
|
1166
|
+
// Also set snapToLines to true otherwise if there's a line % in the vtt file the display will be relative and make the lines not aligned properly
|
|
1167
|
+
this.player.textTracks[i].activeCues[0].line =
|
|
1168
|
+
-3 - numLines
|
|
1169
|
+
this.player.textTracks[i].activeCues[0].size = 99
|
|
1170
|
+
this.player.textTracks[
|
|
1171
|
+
i
|
|
1172
|
+
].activeCues[0].snapToLines = true
|
|
1173
|
+
} else if (
|
|
1174
|
+
this.player.textTracks[i].activeCues &&
|
|
1175
|
+
this.player.textTracks[i].activeCues.length > 0 &&
|
|
1176
|
+
typeof this.player.textTracks[i].activeCues[0]
|
|
1177
|
+
.defaults !== 'undefined'
|
|
1178
|
+
) {
|
|
1179
|
+
this.player.textTracks[i].activeCues[0].line =
|
|
1180
|
+
this.player.textTracks[
|
|
1181
|
+
i
|
|
1182
|
+
].activeCues[0].defaults.line
|
|
1183
|
+
this.player.textTracks[i].activeCues[0].size =
|
|
1184
|
+
this.player.textTracks[
|
|
1185
|
+
i
|
|
1186
|
+
].activeCues[0].defaults.size
|
|
1187
|
+
this.player.textTracks[
|
|
1188
|
+
i
|
|
1189
|
+
].activeCues[0].snapToLines =
|
|
1190
|
+
this.player.textTracks[
|
|
1191
|
+
i
|
|
1192
|
+
].activeCues[0].defaults.snapToLines
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
},
|
|
1059
1198
|
load(e = null) {
|
|
1060
1199
|
if (this.player.load) {
|
|
1061
1200
|
// Reload the player to refresh all the sources / tracks
|
|
1062
1201
|
this.player.load()
|
|
1063
1202
|
this.$emit('load', e)
|
|
1064
1203
|
} else {
|
|
1065
|
-
console.
|
|
1204
|
+
console.error('Cannot load player')
|
|
1066
1205
|
}
|
|
1067
1206
|
},
|
|
1068
1207
|
pause(e = null) {
|
|
1069
1208
|
if (this.player.pause) {
|
|
1070
1209
|
this.player.pause()
|
|
1071
|
-
this.
|
|
1210
|
+
this.state.paused = true
|
|
1072
1211
|
this.$emit('pause', e)
|
|
1073
1212
|
} else {
|
|
1074
1213
|
console.log('Cannot pause player')
|
|
@@ -1078,12 +1217,35 @@ export default {
|
|
|
1078
1217
|
if (this.player.play) {
|
|
1079
1218
|
// Start playing the main video
|
|
1080
1219
|
this.player.play()
|
|
1081
|
-
this.
|
|
1220
|
+
this.state.paused = false
|
|
1221
|
+
this.state.replay = false
|
|
1082
1222
|
this.$emit('play', e)
|
|
1083
1223
|
} else {
|
|
1084
1224
|
console.log('Cannot play player')
|
|
1085
1225
|
}
|
|
1086
1226
|
},
|
|
1227
|
+
playToggle(e) {
|
|
1228
|
+
// If the replay button is active then we actually need to call the onClickReplay method instead
|
|
1229
|
+
// Otherwise we'd just end up replaying any postroll ad
|
|
1230
|
+
if (this.state.replay) {
|
|
1231
|
+
this.onClickReplay(e)
|
|
1232
|
+
} else {
|
|
1233
|
+
const self = this
|
|
1234
|
+
this.state.controls = true
|
|
1235
|
+
|
|
1236
|
+
// Clear any existing timeouts and close the controls in 5 seconds
|
|
1237
|
+
clearTimeout(this.state.controlsDebounce)
|
|
1238
|
+
this.state.controlsDebounce = setTimeout(() => {
|
|
1239
|
+
self.state.controls = false
|
|
1240
|
+
}, 5000)
|
|
1241
|
+
|
|
1242
|
+
if (this.player.paused) {
|
|
1243
|
+
this.play(e)
|
|
1244
|
+
} else {
|
|
1245
|
+
this.pause(e)
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
},
|
|
1087
1249
|
},
|
|
1088
1250
|
}
|
|
1089
1251
|
</script>
|
|
@@ -1094,29 +1256,11 @@ export default {
|
|
|
1094
1256
|
position: relative;
|
|
1095
1257
|
top: -50px;
|
|
1096
1258
|
margin-bottom: -40px;
|
|
1097
|
-
overflow: hidden;
|
|
1098
1259
|
}
|
|
1099
1260
|
.controls {
|
|
1100
1261
|
height: 40px;
|
|
1101
1262
|
background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.7));
|
|
1102
1263
|
}
|
|
1103
|
-
.volume-slider {
|
|
1104
|
-
position: relative;
|
|
1105
|
-
right: -50px;
|
|
1106
|
-
top: -180px;
|
|
1107
|
-
height: 180px;
|
|
1108
|
-
width: 50px;
|
|
1109
|
-
margin-left: -50px;
|
|
1110
|
-
padding-bottom: 10px;
|
|
1111
|
-
}
|
|
1112
|
-
.slider-active-area {
|
|
1113
|
-
width: 50px;
|
|
1114
|
-
height: 200px;
|
|
1115
|
-
margin-right: -50px;
|
|
1116
|
-
margin-bottom: -200px;
|
|
1117
|
-
position: relative;
|
|
1118
|
-
top: -160px; /* height of this - controls height */
|
|
1119
|
-
}
|
|
1120
1264
|
.player-audio {
|
|
1121
1265
|
height: 40px;
|
|
1122
1266
|
}
|
|
@@ -1134,12 +1278,18 @@ export default {
|
|
|
1134
1278
|
color: #fff;
|
|
1135
1279
|
left: 25%;
|
|
1136
1280
|
width: 50%;
|
|
1137
|
-
top:
|
|
1281
|
+
top: 35%;
|
|
1138
1282
|
height: 0;
|
|
1139
1283
|
text-align: center;
|
|
1140
1284
|
}
|
|
1141
|
-
.player-overlay
|
|
1285
|
+
.player-overlay--replay-icon {
|
|
1286
|
+
color: #fff;
|
|
1287
|
+
font-size: 5rem;
|
|
1288
|
+
}
|
|
1289
|
+
.player-overlay > .player-overlay--icon {
|
|
1290
|
+
display: inline-block;
|
|
1142
1291
|
background: rgba(0, 0, 0, 0.25);
|
|
1143
1292
|
border-radius: 100%;
|
|
1293
|
+
padding: 1rem;
|
|
1144
1294
|
}
|
|
1145
1295
|
</style>
|