@mindedge/vuetify-player 0.2.0 → 0.3.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 +46 -44
- package/package.json +2 -2
- package/src/components/Media/CaptionsMenu.vue +230 -34
- package/src/components/Media/Html5Player.vue +721 -502
- package/src/components/VuetifyPlayer.vue +45 -2
- package/src/i18n/en-US.js +7 -0
- package/src/i18n/es-ES.js +35 -0
- package/src/i18n/index.js +2 -0
- package/src/i18n/sv-SE.js +7 -0
|
@@ -1,470 +1,580 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-container>
|
|
3
|
-
<
|
|
4
|
-
<v-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<v-tooltip top>
|
|
86
|
-
<template v-slot:activator="{ on, attrs }">
|
|
87
|
-
<v-btn
|
|
88
|
-
small
|
|
89
|
-
text
|
|
90
|
-
v-bind="attrs"
|
|
91
|
-
v-on="on"
|
|
92
|
-
@click="onPlayToggle"
|
|
93
|
-
>
|
|
94
|
-
<v-icon>{{
|
|
95
|
-
options.paused
|
|
96
|
-
? 'mdi-play'
|
|
97
|
-
: 'mdi-pause'
|
|
98
|
-
}}</v-icon>
|
|
99
|
-
<span class="d-sr-only">
|
|
100
|
-
{{
|
|
101
|
-
options.paused
|
|
102
|
-
? t(language, 'player.play')
|
|
103
|
-
: t(
|
|
104
|
-
language,
|
|
105
|
-
'player.pause'
|
|
106
|
-
)
|
|
107
|
-
}}
|
|
108
|
-
</span>
|
|
109
|
-
</v-btn>
|
|
110
|
-
</template>
|
|
111
|
-
<span>{{
|
|
112
|
-
options.paused
|
|
113
|
-
? t(language, 'player.play')
|
|
114
|
-
: t(language, 'player.pause')
|
|
115
|
-
}}</span>
|
|
116
|
-
</v-tooltip>
|
|
117
|
-
|
|
118
|
-
<!-- Rewind Button-->
|
|
119
|
-
<v-tooltip v-if="attributes.rewind" top>
|
|
120
|
-
<template v-slot:activator="{ on, attrs }">
|
|
121
|
-
<v-btn
|
|
122
|
-
small
|
|
123
|
-
text
|
|
124
|
-
v-bind="attrs"
|
|
125
|
-
v-on="on"
|
|
126
|
-
@click="onRewind"
|
|
127
|
-
>
|
|
128
|
-
<v-icon>mdi-rewind-10</v-icon>
|
|
129
|
-
<span class="sr-only">{{
|
|
130
|
-
t(language, 'player.rewind_10')
|
|
131
|
-
}}</span>
|
|
132
|
-
</v-btn>
|
|
133
|
-
</template>
|
|
134
|
-
<span>{{
|
|
135
|
-
t(language, 'player.rewind_10')
|
|
136
|
-
}}</span>
|
|
137
|
-
</v-tooltip>
|
|
138
|
-
</template>
|
|
139
|
-
|
|
140
|
-
<template #append>
|
|
141
|
-
<!-- Closed Captions -->
|
|
142
|
-
<v-menu
|
|
143
|
-
v-if="
|
|
144
|
-
current.tracks && current.tracks.length > 0
|
|
3
|
+
<v-row>
|
|
4
|
+
<v-col :cols="!options.expandedCaptions ? 12 : 6">
|
|
5
|
+
<div v-if="buffering" class="player-overlay">
|
|
6
|
+
<v-progress-circular
|
|
7
|
+
:size="50"
|
|
8
|
+
indeterminate
|
|
9
|
+
></v-progress-circular>
|
|
10
|
+
</div>
|
|
11
|
+
<video
|
|
12
|
+
ref="player"
|
|
13
|
+
tabindex="0"
|
|
14
|
+
:class="'player-' + type"
|
|
15
|
+
:height="attributes.height"
|
|
16
|
+
:width="attributes.width"
|
|
17
|
+
:autoplay="attributes.autoplay"
|
|
18
|
+
:autopictureinpicture="attributes.autopictureinpicture"
|
|
19
|
+
:controlslist="attributes.controlslist"
|
|
20
|
+
:crossorigin="attributes.crossorigin"
|
|
21
|
+
:disablepictureinpicture="
|
|
22
|
+
attributes.disablepictureinpicture
|
|
23
|
+
"
|
|
24
|
+
:disableremoteplayback="attributes.disableremoteplayback"
|
|
25
|
+
:loop="attributes.loop"
|
|
26
|
+
:muted="attributes.muted"
|
|
27
|
+
:playsinline="attributes.playsinline"
|
|
28
|
+
:poster="src.poster || attributes.poster"
|
|
29
|
+
:preload="attributes.preload"
|
|
30
|
+
@click="onPlayToggle"
|
|
31
|
+
@seeking="onSeeking"
|
|
32
|
+
@timeupdate="onTimeupdate"
|
|
33
|
+
@progress="onMediaProgress"
|
|
34
|
+
@loadedmetadata="onLoadedmetadata"
|
|
35
|
+
@loadeddata="onLoadeddata"
|
|
36
|
+
@focus="onVideoHover"
|
|
37
|
+
@mouseover="onVideoHover"
|
|
38
|
+
@mouseout="onVideoLeave"
|
|
39
|
+
@ended="onEnded"
|
|
40
|
+
@error="$emit('error', $event)"
|
|
41
|
+
@canplay="onCanplay"
|
|
42
|
+
@waiting="onWaiting"
|
|
43
|
+
@canplaythrough="$emit('canplaythrough', $event)"
|
|
44
|
+
@emptied="$emit('emptied', $event)"
|
|
45
|
+
@stalled="$emit('stalled', $event)"
|
|
46
|
+
@abort="$emit('abort', $event)"
|
|
47
|
+
>
|
|
48
|
+
<source
|
|
49
|
+
v-for="(source, index) of current.sources"
|
|
50
|
+
:key="index + '_mediasources'"
|
|
51
|
+
:src="source.src"
|
|
52
|
+
:type="source.type"
|
|
53
|
+
:label="source.label"
|
|
54
|
+
/>
|
|
55
|
+
<track
|
|
56
|
+
v-for="(track, index) of current.tracks"
|
|
57
|
+
:key="index + '_mediatracks'"
|
|
58
|
+
:default="track.default"
|
|
59
|
+
:src="track.src"
|
|
60
|
+
:kind="track.kind"
|
|
61
|
+
:srclang="track.srclang"
|
|
62
|
+
@cuechange="onCuechange"
|
|
63
|
+
/>
|
|
64
|
+
{{ t(language, 'player.no_support') }}
|
|
65
|
+
</video>
|
|
66
|
+
|
|
67
|
+
<div
|
|
68
|
+
class="controls-container"
|
|
69
|
+
v-if="attributes.controls"
|
|
70
|
+
@mouseover="onControlsHover"
|
|
71
|
+
>
|
|
72
|
+
<v-slide-y-reverse-transition>
|
|
73
|
+
<div v-if="player && options.controls" class="controls">
|
|
74
|
+
<v-slider
|
|
75
|
+
dark
|
|
76
|
+
v-model="currentPercent"
|
|
77
|
+
:min="0"
|
|
78
|
+
:max="scrub.max"
|
|
79
|
+
:label="
|
|
80
|
+
filters.playerShortDuration(
|
|
81
|
+
percentToTimeSeconds(currentPercent)
|
|
82
|
+
) +
|
|
83
|
+
' / ' +
|
|
84
|
+
filters.playerShortDuration(player.duration)
|
|
145
85
|
"
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
86
|
+
inverse-label
|
|
87
|
+
@mousedown="onPause"
|
|
88
|
+
@change="onScrubTime"
|
|
149
89
|
>
|
|
150
|
-
<template
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
90
|
+
<template #prepend>
|
|
91
|
+
<!-- Play button -->
|
|
92
|
+
<v-tooltip v-if="!showReplay" top>
|
|
93
|
+
<template
|
|
94
|
+
v-slot:activator="{ on, attrs }"
|
|
95
|
+
>
|
|
96
|
+
<v-btn
|
|
97
|
+
small
|
|
98
|
+
text
|
|
99
|
+
v-bind="attrs"
|
|
100
|
+
v-on="on"
|
|
101
|
+
@click="onPlayToggle"
|
|
102
|
+
>
|
|
103
|
+
<v-icon>{{
|
|
104
|
+
options.paused
|
|
105
|
+
? 'mdi-play'
|
|
106
|
+
: 'mdi-pause'
|
|
107
|
+
}}</v-icon>
|
|
108
|
+
<span class="d-sr-only">
|
|
109
|
+
{{
|
|
110
|
+
options.paused
|
|
111
|
+
? t(
|
|
112
|
+
language,
|
|
113
|
+
'player.play'
|
|
114
|
+
)
|
|
115
|
+
: t(
|
|
116
|
+
language,
|
|
117
|
+
'player.pause'
|
|
118
|
+
)
|
|
119
|
+
}}
|
|
120
|
+
</span>
|
|
121
|
+
</v-btn>
|
|
122
|
+
</template>
|
|
123
|
+
<span>{{
|
|
124
|
+
options.paused
|
|
125
|
+
? t(language, 'player.play')
|
|
126
|
+
: t(language, 'player.pause')
|
|
165
127
|
}}</span>
|
|
166
|
-
</v-
|
|
167
|
-
</template>
|
|
128
|
+
</v-tooltip>
|
|
168
129
|
|
|
169
|
-
|
|
170
|
-
<v-
|
|
171
|
-
<
|
|
172
|
-
v-
|
|
173
|
-
:key="track.srclang"
|
|
174
|
-
@click="
|
|
175
|
-
onSelectTrack(track.srclang)
|
|
176
|
-
"
|
|
130
|
+
<!-- Replay button -->
|
|
131
|
+
<v-tooltip v-if="showReplay" top>
|
|
132
|
+
<template
|
|
133
|
+
v-slot:activator="{ on, attrs }"
|
|
177
134
|
>
|
|
178
|
-
<v-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
135
|
+
<v-btn
|
|
136
|
+
small
|
|
137
|
+
text
|
|
138
|
+
v-bind="attrs"
|
|
139
|
+
v-on="on"
|
|
140
|
+
@click="onClickReplay"
|
|
141
|
+
>
|
|
142
|
+
<v-icon>mdi-replay</v-icon>
|
|
143
|
+
<span class="d-sr-only">
|
|
144
|
+
{{
|
|
145
|
+
t(
|
|
146
|
+
language,
|
|
147
|
+
'player.replay'
|
|
148
|
+
)
|
|
149
|
+
}}
|
|
150
|
+
</span>
|
|
151
|
+
</v-btn>
|
|
152
|
+
</template>
|
|
153
|
+
<span>{{
|
|
154
|
+
t(language, 'player.replay')
|
|
155
|
+
}}</span>
|
|
156
|
+
</v-tooltip>
|
|
157
|
+
|
|
158
|
+
<!-- Rewind Button-->
|
|
159
|
+
<v-tooltip
|
|
160
|
+
v-if="attributes.rewind && !activeAd"
|
|
161
|
+
top
|
|
195
162
|
>
|
|
196
|
-
<
|
|
197
|
-
v-
|
|
198
|
-
!options.muted &&
|
|
199
|
-
options.volume > 0.75
|
|
200
|
-
"
|
|
201
|
-
>mdi-volume-high</v-icon
|
|
202
|
-
>
|
|
203
|
-
<v-icon
|
|
204
|
-
v-if="
|
|
205
|
-
!options.muted &&
|
|
206
|
-
options.volume >= 0.25 &&
|
|
207
|
-
options.volume <= 0.75
|
|
208
|
-
"
|
|
209
|
-
>mdi-volume-medium</v-icon
|
|
210
|
-
>
|
|
211
|
-
<v-icon
|
|
212
|
-
v-if="
|
|
213
|
-
!options.muted &&
|
|
214
|
-
options.volume > 0 &&
|
|
215
|
-
options.volume < 0.25
|
|
216
|
-
"
|
|
217
|
-
>mdi-volume-low</v-icon
|
|
163
|
+
<template
|
|
164
|
+
v-slot:activator="{ on, attrs }"
|
|
218
165
|
>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
166
|
+
<v-btn
|
|
167
|
+
small
|
|
168
|
+
text
|
|
169
|
+
v-bind="attrs"
|
|
170
|
+
v-on="on"
|
|
171
|
+
@click="onRewind"
|
|
172
|
+
>
|
|
173
|
+
<v-icon>mdi-rewind-10</v-icon>
|
|
174
|
+
<span class="sr-only">{{
|
|
175
|
+
t(
|
|
176
|
+
language,
|
|
177
|
+
'player.rewind_10'
|
|
178
|
+
)
|
|
179
|
+
}}</span>
|
|
180
|
+
</v-btn>
|
|
181
|
+
</template>
|
|
182
|
+
<span>{{
|
|
183
|
+
t(language, 'player.rewind_10')
|
|
228
184
|
}}</span>
|
|
229
|
-
</v-
|
|
185
|
+
</v-tooltip>
|
|
230
186
|
</template>
|
|
231
187
|
|
|
232
|
-
<
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
vertical
|
|
243
|
-
@change="onVolumeChange"
|
|
244
|
-
></v-slider>
|
|
245
|
-
</v-sheet>
|
|
246
|
-
</v-menu>
|
|
247
|
-
|
|
248
|
-
<!-- Fullscreen -->
|
|
249
|
-
<v-tooltip v-if="fullscreenEnabled" top>
|
|
250
|
-
<template v-slot:activator="{ on, attrs }">
|
|
251
|
-
<v-btn
|
|
252
|
-
small
|
|
253
|
-
text
|
|
254
|
-
v-bind="attrs"
|
|
255
|
-
v-on="on"
|
|
256
|
-
@click="onFullscreen"
|
|
188
|
+
<template #append>
|
|
189
|
+
<!-- Closed Captions -->
|
|
190
|
+
<v-menu
|
|
191
|
+
v-if="
|
|
192
|
+
current.tracks &&
|
|
193
|
+
current.tracks.length > 0
|
|
194
|
+
"
|
|
195
|
+
open-on-hover
|
|
196
|
+
top
|
|
197
|
+
offset-y
|
|
257
198
|
>
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
199
|
+
<template
|
|
200
|
+
v-slot:activator="{ on, attrs }"
|
|
201
|
+
>
|
|
202
|
+
<v-btn
|
|
203
|
+
small
|
|
204
|
+
text
|
|
205
|
+
v-bind="attrs"
|
|
206
|
+
v-on="on"
|
|
207
|
+
@click="onCCToggle"
|
|
208
|
+
>
|
|
209
|
+
<v-icon>{{
|
|
210
|
+
options.cc
|
|
211
|
+
? 'mdi-closed-caption'
|
|
212
|
+
: 'mdi-closed-caption-outline'
|
|
213
|
+
}}</v-icon>
|
|
214
|
+
<span class="d-sr-only">{{
|
|
215
|
+
t(
|
|
216
|
+
language,
|
|
217
|
+
'player.toggle_cc'
|
|
218
|
+
)
|
|
219
|
+
}}</span>
|
|
220
|
+
</v-btn>
|
|
221
|
+
</template>
|
|
222
|
+
|
|
223
|
+
<v-list>
|
|
224
|
+
<v-list-item-group>
|
|
225
|
+
<v-list-item
|
|
226
|
+
v-for="track in current.tracks"
|
|
227
|
+
:key="track.srclang"
|
|
228
|
+
@click="
|
|
229
|
+
onSelectTrack(
|
|
230
|
+
track.srclang
|
|
231
|
+
)
|
|
232
|
+
"
|
|
233
|
+
>
|
|
234
|
+
<v-list-item-title>{{
|
|
235
|
+
track.srclang
|
|
236
|
+
}}</v-list-item-title>
|
|
237
|
+
</v-list-item>
|
|
238
|
+
</v-list-item-group>
|
|
239
|
+
</v-list>
|
|
240
|
+
</v-menu>
|
|
241
|
+
|
|
242
|
+
<!-- Volume -->
|
|
243
|
+
<v-menu open-on-hover top offset-y>
|
|
244
|
+
<template
|
|
245
|
+
v-slot:activator="{ on, attrs }"
|
|
246
|
+
>
|
|
247
|
+
<v-btn
|
|
248
|
+
small
|
|
249
|
+
text
|
|
250
|
+
v-bind="attrs"
|
|
251
|
+
v-on="on"
|
|
252
|
+
@click="onMuteToggle"
|
|
253
|
+
>
|
|
254
|
+
<v-icon
|
|
255
|
+
v-if="
|
|
256
|
+
!options.muted &&
|
|
257
|
+
options.volume > 0.75
|
|
258
|
+
"
|
|
259
|
+
>mdi-volume-high</v-icon
|
|
260
|
+
>
|
|
261
|
+
<v-icon
|
|
262
|
+
v-if="
|
|
263
|
+
!options.muted &&
|
|
264
|
+
options.volume >=
|
|
265
|
+
0.25 &&
|
|
266
|
+
options.volume <= 0.75
|
|
267
|
+
"
|
|
268
|
+
>mdi-volume-medium</v-icon
|
|
269
|
+
>
|
|
270
|
+
<v-icon
|
|
271
|
+
v-if="
|
|
272
|
+
!options.muted &&
|
|
273
|
+
options.volume > 0 &&
|
|
274
|
+
options.volume < 0.25
|
|
275
|
+
"
|
|
276
|
+
>mdi-volume-low</v-icon
|
|
277
|
+
>
|
|
278
|
+
<v-icon
|
|
279
|
+
v-if="
|
|
280
|
+
options.muted ||
|
|
281
|
+
options.volume === 0
|
|
282
|
+
"
|
|
283
|
+
>mdi-volume-off</v-icon
|
|
284
|
+
>
|
|
285
|
+
<span class="d-sr-only">{{
|
|
286
|
+
t(
|
|
287
|
+
language,
|
|
288
|
+
'player.volume_slider'
|
|
289
|
+
)
|
|
290
|
+
}}</span>
|
|
291
|
+
</v-btn>
|
|
292
|
+
</template>
|
|
293
|
+
|
|
294
|
+
<v-sheet class="pa-5">
|
|
295
|
+
<span class="d-sr-only">{{
|
|
296
|
+
t(
|
|
297
|
+
language,
|
|
298
|
+
'player.volume_slider'
|
|
299
|
+
)
|
|
300
|
+
}}</span>
|
|
301
|
+
<v-slider
|
|
302
|
+
v-model="options.volume"
|
|
303
|
+
inverse-label
|
|
304
|
+
:min="0"
|
|
305
|
+
:max="1"
|
|
306
|
+
:step="0.1"
|
|
307
|
+
vertical
|
|
308
|
+
@change="onVolumeChange"
|
|
309
|
+
></v-slider>
|
|
310
|
+
</v-sheet>
|
|
311
|
+
</v-menu>
|
|
312
|
+
|
|
313
|
+
<!-- Fullscreen -->
|
|
314
|
+
<v-tooltip v-if="fullscreenEnabled" top>
|
|
315
|
+
<template
|
|
316
|
+
v-slot:activator="{ on, attrs }"
|
|
317
|
+
>
|
|
318
|
+
<v-btn
|
|
319
|
+
small
|
|
320
|
+
text
|
|
321
|
+
v-bind="attrs"
|
|
322
|
+
v-on="on"
|
|
323
|
+
@click="onFullscreen"
|
|
324
|
+
>
|
|
325
|
+
<v-icon>{{
|
|
326
|
+
!options.fullscreen
|
|
327
|
+
? 'mdi-fullscreen'
|
|
328
|
+
: 'mdi-fullscreen-exit'
|
|
329
|
+
}}</v-icon>
|
|
330
|
+
<span class="d-sr-only">{{
|
|
331
|
+
t(
|
|
332
|
+
language,
|
|
333
|
+
'player.toggle_fullscreen'
|
|
334
|
+
)
|
|
335
|
+
}}</span>
|
|
336
|
+
</v-btn></template
|
|
337
|
+
>
|
|
338
|
+
<span>{{
|
|
264
339
|
t(
|
|
265
340
|
language,
|
|
266
341
|
'player.toggle_fullscreen'
|
|
267
342
|
)
|
|
268
343
|
}}</span>
|
|
269
|
-
</v-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
<v-tooltip
|
|
278
|
-
v-if="!attributes.disablepictureinpicture"
|
|
279
|
-
top
|
|
280
|
-
>
|
|
281
|
-
<template v-slot:activator="{ on, attrs }">
|
|
282
|
-
<v-btn
|
|
283
|
-
small
|
|
284
|
-
text
|
|
285
|
-
v-bind="attrs"
|
|
286
|
-
v-on="on"
|
|
287
|
-
@click="onPictureInPicture"
|
|
344
|
+
</v-tooltip>
|
|
345
|
+
|
|
346
|
+
<!-- Picture in picture -->
|
|
347
|
+
<v-tooltip
|
|
348
|
+
v-if="
|
|
349
|
+
!attributes.disablepictureinpicture
|
|
350
|
+
"
|
|
351
|
+
top
|
|
288
352
|
>
|
|
289
|
-
<
|
|
290
|
-
|
|
353
|
+
<template
|
|
354
|
+
v-slot:activator="{ on, attrs }"
|
|
291
355
|
>
|
|
292
|
-
|
|
356
|
+
<v-btn
|
|
357
|
+
small
|
|
358
|
+
text
|
|
359
|
+
v-bind="attrs"
|
|
360
|
+
v-on="on"
|
|
361
|
+
@click="onPictureInPicture"
|
|
362
|
+
>
|
|
363
|
+
<v-icon
|
|
364
|
+
>mdi-picture-in-picture-bottom-right</v-icon
|
|
365
|
+
>
|
|
366
|
+
<span class="d-sr-only">{{
|
|
367
|
+
t(
|
|
368
|
+
language,
|
|
369
|
+
'player.toggle_picture_in_picture'
|
|
370
|
+
)
|
|
371
|
+
}}</span>
|
|
372
|
+
</v-btn></template
|
|
373
|
+
>
|
|
374
|
+
<span>{{
|
|
293
375
|
t(
|
|
294
376
|
language,
|
|
295
377
|
'player.toggle_picture_in_picture'
|
|
296
378
|
)
|
|
297
379
|
}}</span>
|
|
298
|
-
</v-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
)
|
|
305
|
-
}}</span>
|
|
306
|
-
</v-tooltip>
|
|
307
|
-
|
|
308
|
-
<!-- Remote playback -->
|
|
309
|
-
<v-tooltip v-if="options.remoteplayback" top>
|
|
310
|
-
<template v-slot:activator="{ on, attrs }">
|
|
311
|
-
<v-btn
|
|
312
|
-
small
|
|
313
|
-
text
|
|
314
|
-
v-bind="attrs"
|
|
315
|
-
v-on="on"
|
|
316
|
-
@click="onRemoteplayback"
|
|
380
|
+
</v-tooltip>
|
|
381
|
+
|
|
382
|
+
<!-- Remote playback -->
|
|
383
|
+
<v-tooltip
|
|
384
|
+
v-if="options.remoteplayback"
|
|
385
|
+
top
|
|
317
386
|
>
|
|
318
|
-
<
|
|
319
|
-
|
|
387
|
+
<template
|
|
388
|
+
v-slot:activator="{ on, attrs }"
|
|
389
|
+
>
|
|
390
|
+
<v-btn
|
|
391
|
+
small
|
|
392
|
+
text
|
|
393
|
+
v-bind="attrs"
|
|
394
|
+
v-on="on"
|
|
395
|
+
@click="onRemoteplayback"
|
|
396
|
+
>
|
|
397
|
+
<v-icon>mdi-cast</v-icon>
|
|
398
|
+
<span class="d-sr-only">{{
|
|
399
|
+
t(
|
|
400
|
+
language,
|
|
401
|
+
'player.toggle_remote_playback'
|
|
402
|
+
)
|
|
403
|
+
}}</span>
|
|
404
|
+
</v-btn></template
|
|
405
|
+
>
|
|
406
|
+
<span>{{
|
|
320
407
|
t(
|
|
321
408
|
language,
|
|
322
409
|
'player.toggle_remote_playback'
|
|
323
410
|
)
|
|
324
411
|
}}</span>
|
|
325
|
-
</v-
|
|
326
|
-
>
|
|
327
|
-
<span>{{
|
|
328
|
-
t(language, 'player.toggle_remote_playback')
|
|
329
|
-
}}</span>
|
|
330
|
-
</v-tooltip>
|
|
331
|
-
|
|
332
|
-
<!-- Download -->
|
|
333
|
-
<v-tooltip v-if="options.download" top>
|
|
334
|
-
<template v-slot:activator="{ on, attrs }">
|
|
335
|
-
<v-btn
|
|
336
|
-
small
|
|
337
|
-
text
|
|
338
|
-
v-bind="attrs"
|
|
339
|
-
v-on="on"
|
|
340
|
-
@click="onDownload"
|
|
341
|
-
>
|
|
342
|
-
<v-icon>mdi-download</v-icon>
|
|
343
|
-
<span class="d-sr-only">{{
|
|
344
|
-
t(language, 'player.download')
|
|
345
|
-
}}</span>
|
|
346
|
-
</v-btn></template
|
|
347
|
-
>
|
|
348
|
-
<span>{{
|
|
349
|
-
t(language, 'player.download')
|
|
350
|
-
}}</span>
|
|
351
|
-
</v-tooltip>
|
|
352
|
-
|
|
353
|
-
<!-- Settings -->
|
|
354
|
-
<v-menu
|
|
355
|
-
top
|
|
356
|
-
offset-y
|
|
357
|
-
:close-on-content-click="false"
|
|
358
|
-
nudge-left="100"
|
|
359
|
-
>
|
|
360
|
-
<template v-slot:activator="{ on, attrs }">
|
|
361
|
-
<v-btn small text v-bind="attrs" v-on="on">
|
|
362
|
-
<v-icon>mdi-cog</v-icon>
|
|
363
|
-
<span class="d-sr-only">{{
|
|
364
|
-
t(
|
|
365
|
-
language,
|
|
366
|
-
'player.toggle_settings'
|
|
367
|
-
)
|
|
368
|
-
}}</span>
|
|
369
|
-
</v-btn>
|
|
370
|
-
</template>
|
|
412
|
+
</v-tooltip>
|
|
371
413
|
|
|
372
|
-
|
|
373
|
-
<v-
|
|
374
|
-
<
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
t(
|
|
378
|
-
language,
|
|
379
|
-
'player.playback_speed'
|
|
380
|
-
)
|
|
381
|
-
}}
|
|
382
|
-
</v-list-item-title>
|
|
383
|
-
</v-list-item>
|
|
384
|
-
<v-list-item>
|
|
385
|
-
<v-list-item-title class="text-center">
|
|
414
|
+
<!-- Download -->
|
|
415
|
+
<v-tooltip v-if="options.download" top>
|
|
416
|
+
<template
|
|
417
|
+
v-slot:activator="{ on, attrs }"
|
|
418
|
+
>
|
|
386
419
|
<v-btn
|
|
387
420
|
small
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
"
|
|
392
|
-
@click="
|
|
393
|
-
onPlaybackSpeed(
|
|
394
|
-
options.playbackRateIndex -
|
|
395
|
-
1
|
|
396
|
-
)
|
|
397
|
-
"
|
|
421
|
+
text
|
|
422
|
+
v-bind="attrs"
|
|
423
|
+
v-on="on"
|
|
424
|
+
@click="onDownload"
|
|
398
425
|
>
|
|
399
|
-
<v-icon>
|
|
400
|
-
mdi-clock-minus-outline
|
|
401
|
-
</v-icon>
|
|
426
|
+
<v-icon>mdi-download</v-icon>
|
|
402
427
|
<span class="d-sr-only">{{
|
|
403
428
|
t(
|
|
404
429
|
language,
|
|
405
|
-
'player.
|
|
430
|
+
'player.download'
|
|
406
431
|
)
|
|
407
432
|
}}</span>
|
|
408
|
-
</v-btn
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
433
|
+
</v-btn></template
|
|
434
|
+
>
|
|
435
|
+
<span>{{
|
|
436
|
+
t(language, 'player.download')
|
|
437
|
+
}}</span>
|
|
438
|
+
</v-tooltip>
|
|
439
|
+
|
|
440
|
+
<!-- Settings -->
|
|
441
|
+
<v-menu
|
|
442
|
+
top
|
|
443
|
+
offset-y
|
|
444
|
+
:close-on-content-click="false"
|
|
445
|
+
nudge-left="100"
|
|
446
|
+
>
|
|
447
|
+
<template
|
|
448
|
+
v-slot:activator="{ on, attrs }"
|
|
449
|
+
>
|
|
417
450
|
<v-btn
|
|
418
451
|
small
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
.length -
|
|
423
|
-
1
|
|
424
|
-
"
|
|
425
|
-
@click="
|
|
426
|
-
onPlaybackSpeed(
|
|
427
|
-
options.playbackRateIndex +
|
|
428
|
-
1
|
|
429
|
-
)
|
|
430
|
-
"
|
|
452
|
+
text
|
|
453
|
+
v-bind="attrs"
|
|
454
|
+
v-on="on"
|
|
431
455
|
>
|
|
432
|
-
<v-icon>
|
|
433
|
-
mdi-clock-plus-outline
|
|
434
|
-
</v-icon>
|
|
456
|
+
<v-icon>mdi-cog</v-icon>
|
|
435
457
|
<span class="d-sr-only">{{
|
|
436
458
|
t(
|
|
437
459
|
language,
|
|
438
|
-
'player.
|
|
460
|
+
'player.toggle_settings'
|
|
439
461
|
)
|
|
440
462
|
}}</span>
|
|
441
463
|
</v-btn>
|
|
442
|
-
</
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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>
|
|
552
|
+
</template>
|
|
553
|
+
</v-slider>
|
|
554
|
+
</div>
|
|
555
|
+
</v-slide-y-reverse-transition>
|
|
448
556
|
</div>
|
|
449
|
-
</v-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
557
|
+
</v-col>
|
|
558
|
+
|
|
559
|
+
<v-col
|
|
560
|
+
v-if="
|
|
561
|
+
attributes.captionsmenu &&
|
|
562
|
+
current.tracks &&
|
|
563
|
+
captions &&
|
|
564
|
+
captions.cues &&
|
|
565
|
+
Object.keys(captions.cues).length
|
|
566
|
+
"
|
|
567
|
+
:cols="!options.expandedCaptions ? 12 : 6"
|
|
568
|
+
>
|
|
569
|
+
<CaptionsMenu
|
|
570
|
+
v-model="captions"
|
|
571
|
+
:language="language"
|
|
572
|
+
@click:cue="onCueClick"
|
|
573
|
+
@click:expand="onClickExpandCaptions"
|
|
574
|
+
@click:paragraph="onClickParagraph"
|
|
575
|
+
></CaptionsMenu>
|
|
576
|
+
</v-col>
|
|
577
|
+
</v-row>
|
|
468
578
|
</v-container>
|
|
469
579
|
</template>
|
|
470
580
|
|
|
@@ -500,17 +610,6 @@ export default {
|
|
|
500
610
|
// We're playing an ad currently
|
|
501
611
|
if (this.activeAd) {
|
|
502
612
|
return this.activeAd
|
|
503
|
-
|
|
504
|
-
// We hit an ad spot~ play_at_percent
|
|
505
|
-
} else if (
|
|
506
|
-
!this.activeAd &&
|
|
507
|
-
typeof this.ads[this.currentPercent] !== 'undefined' &&
|
|
508
|
-
this.ads[this.currentPercent].sources &&
|
|
509
|
-
this.ads[this.currentPercent].sources.length &&
|
|
510
|
-
!this.ads[this.currentPercent].complete
|
|
511
|
-
) {
|
|
512
|
-
this.setActiveAd(this.currentPercent)
|
|
513
|
-
return this.ads[this.currentPercent]
|
|
514
613
|
} else {
|
|
515
614
|
// Only change sources if we're not watching an ad or pre/postroll
|
|
516
615
|
return this.src
|
|
@@ -541,6 +640,7 @@ export default {
|
|
|
541
640
|
paused: true,
|
|
542
641
|
playbackRateIndex: 0,
|
|
543
642
|
fullscreen: false,
|
|
643
|
+
expandedCaptions: false,
|
|
544
644
|
download: false,
|
|
545
645
|
remoteplayback: false,
|
|
546
646
|
controlslist: [],
|
|
@@ -548,11 +648,96 @@ export default {
|
|
|
548
648
|
watchPlayer: 0,
|
|
549
649
|
scrub: { max: 100 },
|
|
550
650
|
buffering: false,
|
|
651
|
+
showReplay: false,
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
beforeMount() {
|
|
655
|
+
// Parse the controlslist string
|
|
656
|
+
if (
|
|
657
|
+
this.attributes.controlslist &&
|
|
658
|
+
typeof this.attributes.controlslist === 'string' &&
|
|
659
|
+
this.attributes.controlslist !== ''
|
|
660
|
+
) {
|
|
661
|
+
this.options.controlslist = this.attributes.controlslist.split(' ')
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (
|
|
665
|
+
typeof this.attributes.playbackrates === 'undefined' ||
|
|
666
|
+
this.attributes.playbackrates.length === 0
|
|
667
|
+
) {
|
|
668
|
+
throw new Error(
|
|
669
|
+
'attributes.playbackrates must be defined and an array of numbers!'
|
|
670
|
+
)
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Adjust the playback speed to 1 by default
|
|
674
|
+
if (this.attributes.playbackrates.indexOf(1) !== -1) {
|
|
675
|
+
this.options.playbackRateIndex =
|
|
676
|
+
this.attributes.playbackrates.indexOf(1)
|
|
677
|
+
} else {
|
|
678
|
+
// 1 aka normal playback not enabled (What monster would do this?!)
|
|
679
|
+
// Set the playback rate to "middle of the road" for whatever is available
|
|
680
|
+
this.options.playbackRateIndex = Math.floor(
|
|
681
|
+
this.attributes.playbackrates.length / 2
|
|
682
|
+
)
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Initialize the ads aka pre/post/midroll
|
|
686
|
+
if (this.src.ads && this.src.ads.length) {
|
|
687
|
+
for (const ad of this.src.ads) {
|
|
688
|
+
// Map to a percent so we can avoid dupe timings and have easier lookups
|
|
689
|
+
this.ads[ad.play_at_percent] = ad
|
|
690
|
+
this.ads[ad.play_at_percent].complete = false
|
|
691
|
+
}
|
|
692
|
+
}
|
|
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
|
+
},
|
|
722
|
+
mounted() {
|
|
723
|
+
if (
|
|
724
|
+
!this.activeAd &&
|
|
725
|
+
typeof this.ads[this.currentPercent] !== 'undefined' &&
|
|
726
|
+
this.ads[this.currentPercent].sources &&
|
|
727
|
+
this.ads[this.currentPercent].sources.length &&
|
|
728
|
+
!this.ads[this.currentPercent].complete
|
|
729
|
+
) {
|
|
730
|
+
this.activeAd = this.ads[this.currentPercent]
|
|
551
731
|
}
|
|
552
732
|
},
|
|
553
733
|
methods: {
|
|
554
|
-
setActiveAd(currentPercent) {
|
|
734
|
+
setActiveAd(currentPercent, e = null) {
|
|
555
735
|
this.activeAd = this.ads[currentPercent]
|
|
736
|
+
|
|
737
|
+
// Reload the player to refresh all the sources / tracks
|
|
738
|
+
this.load(e)
|
|
739
|
+
// Start playing the main video
|
|
740
|
+
this.play(e)
|
|
556
741
|
},
|
|
557
742
|
percentToTimeSeconds(percent) {
|
|
558
743
|
const scaleFactor = this.player.duration / this.scrub.max
|
|
@@ -569,6 +754,13 @@ export default {
|
|
|
569
754
|
onCueClick(time) {
|
|
570
755
|
this.setTime(time)
|
|
571
756
|
},
|
|
757
|
+
onClickExpandCaptions(expanded) {
|
|
758
|
+
this.options.expandedCaptions = expanded
|
|
759
|
+
this.$emit('click:captions-expand', expanded)
|
|
760
|
+
},
|
|
761
|
+
onClickParagraph(isParagraph) {
|
|
762
|
+
this.$emit('click:captions-paragraph', isParagraph)
|
|
763
|
+
},
|
|
572
764
|
onDownload() {
|
|
573
765
|
window.open(this.src.sources[0].src, '_blank')
|
|
574
766
|
},
|
|
@@ -610,23 +802,37 @@ export default {
|
|
|
610
802
|
this.$emit('mouseout', e)
|
|
611
803
|
},
|
|
612
804
|
onEnded(e) {
|
|
613
|
-
if
|
|
805
|
+
// Active ad ended but only continue playing if the video didn't just end on a postroll
|
|
806
|
+
if (this.activeAd && this.activeAd.play_at_percent !== 100) {
|
|
614
807
|
this.ads[this.activeAd.play_at_percent].complete = true
|
|
615
808
|
// Go back to the play_at_percent for the main video
|
|
616
809
|
this.currentPercent = this.activeAd.play_at_percent
|
|
810
|
+
|
|
617
811
|
this.activeAd = null
|
|
618
812
|
|
|
619
813
|
// Reload the player to refresh all the sources / tracks
|
|
620
814
|
this.load(e)
|
|
815
|
+
|
|
621
816
|
// Start playing the main video
|
|
622
817
|
this.play(e)
|
|
818
|
+
} else if (
|
|
819
|
+
!this.activeAd &&
|
|
820
|
+
typeof this.ads[this.currentPercent] !== 'undefined' &&
|
|
821
|
+
this.ads[this.currentPercent].sources &&
|
|
822
|
+
this.ads[this.currentPercent].sources.length &&
|
|
823
|
+
!this.ads[this.currentPercent].complete
|
|
824
|
+
) {
|
|
825
|
+
// Video ended but there's an ad (probably 100% ad)
|
|
826
|
+
this.setActiveAd(this.currentPercent, e)
|
|
623
827
|
} else if (
|
|
624
828
|
this.activeAd !== null &&
|
|
625
829
|
this.activeAd.play_at_percent === 100
|
|
626
830
|
) {
|
|
831
|
+
this.showReplay = true
|
|
627
832
|
// Ended but this ad was a postroll
|
|
628
833
|
this.$emit('ended', e)
|
|
629
834
|
} else {
|
|
835
|
+
this.showReplay = true
|
|
630
836
|
// Ended without an ad
|
|
631
837
|
this.$emit('ended', e)
|
|
632
838
|
}
|
|
@@ -677,6 +883,17 @@ export default {
|
|
|
677
883
|
(this.player.currentTime / this.player.duration) * 100
|
|
678
884
|
)
|
|
679
885
|
|
|
886
|
+
// Check if there's an ad that needs to be played
|
|
887
|
+
if (
|
|
888
|
+
!this.activeAd &&
|
|
889
|
+
typeof this.ads[this.currentPercent] !== 'undefined' &&
|
|
890
|
+
this.ads[this.currentPercent].sources &&
|
|
891
|
+
this.ads[this.currentPercent].sources.length &&
|
|
892
|
+
!this.ads[this.currentPercent].complete
|
|
893
|
+
) {
|
|
894
|
+
this.setActiveAd(this.currentPercent, e)
|
|
895
|
+
}
|
|
896
|
+
|
|
680
897
|
this.$emit('timeupdate', {
|
|
681
898
|
event: e,
|
|
682
899
|
current_percent: this.currentPercent,
|
|
@@ -684,11 +901,9 @@ export default {
|
|
|
684
901
|
},
|
|
685
902
|
onSeeking(e) {
|
|
686
903
|
this.$emit('seeking', e)
|
|
687
|
-
// console.log('onSeeking', e)
|
|
688
904
|
},
|
|
689
905
|
onMediaProgress(e) {
|
|
690
906
|
this.$emit('progress', e)
|
|
691
|
-
//console.log('onMediaProgress', e)
|
|
692
907
|
},
|
|
693
908
|
onCCToggle() {
|
|
694
909
|
this.options.cc = !this.options.cc
|
|
@@ -715,6 +930,31 @@ export default {
|
|
|
715
930
|
this.pause(e)
|
|
716
931
|
}
|
|
717
932
|
},
|
|
933
|
+
onClickReplay(e) {
|
|
934
|
+
// Re-initialize the ads aka pre/post/midroll
|
|
935
|
+
if (this.src.ads && this.src.ads.length) {
|
|
936
|
+
for (const ad of this.src.ads) {
|
|
937
|
+
// Map to a percent so we can avoid dupe timings and have easier lookups
|
|
938
|
+
this.ads[ad.play_at_percent] = ad
|
|
939
|
+
this.ads[ad.play_at_percent].complete = false
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// There's a pre-roll / start ad. Reassign as the active
|
|
943
|
+
if (typeof this.ads[0] !== 'undefined') {
|
|
944
|
+
this.activeAd = this.ads[0]
|
|
945
|
+
} else {
|
|
946
|
+
// Clear the active ad otherwise
|
|
947
|
+
this.activeAd = null
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// Reload the player to refresh all the sources / tracks
|
|
952
|
+
this.load(e)
|
|
953
|
+
// Start playing the main video
|
|
954
|
+
this.play(e)
|
|
955
|
+
// Restart from the beginning
|
|
956
|
+
this.setTime(0)
|
|
957
|
+
},
|
|
718
958
|
onMuteToggle() {
|
|
719
959
|
if (this.player.muted) {
|
|
720
960
|
this.options.muted = false
|
|
@@ -743,6 +983,28 @@ export default {
|
|
|
743
983
|
onCuechange(e) {
|
|
744
984
|
if (e && e.srcElement && e.srcElement.track) {
|
|
745
985
|
const track = e.srcElement.track
|
|
986
|
+
|
|
987
|
+
// Remove transcript classes from cues manually
|
|
988
|
+
// This is because Firefox doesn't support ::cue(<selector>) so we can't remove them via css
|
|
989
|
+
if (
|
|
990
|
+
typeof track.activeCues !== 'undefined' &&
|
|
991
|
+
track.activeCues.length > 0
|
|
992
|
+
) {
|
|
993
|
+
// Store the raw version so we can retain it for the CaptionsMenu
|
|
994
|
+
if (typeof track.activeCues[0].rawText === 'undefined') {
|
|
995
|
+
track.activeCues[0].rawText = track.activeCues[0].text
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
// Now remove `<c.transcript>` tags
|
|
999
|
+
const transcriptTagRegex = /<c.transcript>.*?<\/c>/gi
|
|
1000
|
+
|
|
1001
|
+
track.activeCues[0].text =
|
|
1002
|
+
track.activeCues[0].text.replaceAll(
|
|
1003
|
+
transcriptTagRegex,
|
|
1004
|
+
''
|
|
1005
|
+
)
|
|
1006
|
+
}
|
|
1007
|
+
|
|
746
1008
|
this.setCues(track)
|
|
747
1009
|
}
|
|
748
1010
|
|
|
@@ -795,82 +1057,34 @@ export default {
|
|
|
795
1057
|
this.captions.nonce = Math.random()
|
|
796
1058
|
},
|
|
797
1059
|
load(e = null) {
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1060
|
+
if (this.player.load) {
|
|
1061
|
+
// Reload the player to refresh all the sources / tracks
|
|
1062
|
+
this.player.load()
|
|
1063
|
+
this.$emit('load', e)
|
|
1064
|
+
} else {
|
|
1065
|
+
console.log('Cannot load player')
|
|
1066
|
+
}
|
|
801
1067
|
},
|
|
802
1068
|
pause(e = null) {
|
|
803
|
-
this.player.pause
|
|
804
|
-
|
|
805
|
-
|
|
1069
|
+
if (this.player.pause) {
|
|
1070
|
+
this.player.pause()
|
|
1071
|
+
this.options.paused = true
|
|
1072
|
+
this.$emit('pause', e)
|
|
1073
|
+
} else {
|
|
1074
|
+
console.log('Cannot pause player')
|
|
1075
|
+
}
|
|
806
1076
|
},
|
|
807
1077
|
play(e = null) {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
// Parse the controlslist string
|
|
816
|
-
if (
|
|
817
|
-
this.attributes.controlslist &&
|
|
818
|
-
typeof this.attributes.controlslist === 'string' &&
|
|
819
|
-
this.attributes.controlslist !== ''
|
|
820
|
-
) {
|
|
821
|
-
this.options.controlslist = this.attributes.controlslist.split(' ')
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
// Adjust the playback speed to 1 by default
|
|
825
|
-
if (this.attributes.playbackrates.indexOf(1) !== -1) {
|
|
826
|
-
this.options.playbackRateIndex =
|
|
827
|
-
this.attributes.playbackrates.indexOf(1)
|
|
828
|
-
} else {
|
|
829
|
-
// 1 aka normal playback not enabled (What monster would do this?!)
|
|
830
|
-
// Set the playback rate to "middle of the road" for whatever is available
|
|
831
|
-
this.options.playbackRateIndex = Math.floor(
|
|
832
|
-
this.attributes.playbackrates.length / 2
|
|
833
|
-
)
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
// Initialize the ads aka pre/post/midroll
|
|
837
|
-
if (this.src.ads && this.src.ads.length) {
|
|
838
|
-
for (const ad of this.src.ads) {
|
|
839
|
-
// Map to a percent so we can avoid dupe timings and have easier lookups
|
|
840
|
-
this.ads[ad.play_at_percent] = ad
|
|
841
|
-
this.ads[ad.play_at_percent].complete = false
|
|
1078
|
+
if (this.player.play) {
|
|
1079
|
+
// Start playing the main video
|
|
1080
|
+
this.player.play()
|
|
1081
|
+
this.options.paused = false
|
|
1082
|
+
this.$emit('play', e)
|
|
1083
|
+
} else {
|
|
1084
|
+
console.log('Cannot play player')
|
|
842
1085
|
}
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
// Determine fullscreen settings
|
|
846
|
-
if (
|
|
847
|
-
this.attributes.playsinline ||
|
|
848
|
-
!document.fullscreenEnabled ||
|
|
849
|
-
this.options.controlslist.indexOf('nofullscreen') !== -1
|
|
850
|
-
) {
|
|
851
|
-
this.fullscreenEnabled = false
|
|
852
|
-
} else {
|
|
853
|
-
this.fullscreenEnabled = true
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
// Determine remote playback settings
|
|
857
|
-
if (
|
|
858
|
-
this.attributes.disableremoteplayback ||
|
|
859
|
-
this.options.controlslist.indexOf('noremoteplayback') !== -1
|
|
860
|
-
) {
|
|
861
|
-
this.options.remoteplayback = false
|
|
862
|
-
} else {
|
|
863
|
-
this.options.remoteplayback = true
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
// Determine download settings
|
|
867
|
-
if (this.options.controlslist.indexOf('nodownload') !== -1) {
|
|
868
|
-
this.options.download = false
|
|
869
|
-
} else {
|
|
870
|
-
this.options.download = true
|
|
871
|
-
}
|
|
1086
|
+
},
|
|
872
1087
|
},
|
|
873
|
-
mounted() {},
|
|
874
1088
|
}
|
|
875
1089
|
</script>
|
|
876
1090
|
|
|
@@ -910,6 +1124,11 @@ export default {
|
|
|
910
1124
|
max-height: 100%;
|
|
911
1125
|
background: #000;
|
|
912
1126
|
}
|
|
1127
|
+
/* Hide transcript classes from player */
|
|
1128
|
+
.player-video::cue(c.transcript) {
|
|
1129
|
+
visibility: hidden;
|
|
1130
|
+
font-size: 0;
|
|
1131
|
+
}
|
|
913
1132
|
.player-overlay {
|
|
914
1133
|
position: relative;
|
|
915
1134
|
color: #fff;
|