@grfzhl/vue-hls-player 1.0.9 → 1.0.12
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.
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="video-container">
|
|
3
|
-
<div class="media-container" id="hls-player-media-container">
|
|
3
|
+
<div class="media-container" id="hls-player-media-container" :class="{'is-fullscreen': isFullscreen}">
|
|
4
|
+
<div class="media-fullscreen-overlay" v-if="introTitle">
|
|
5
|
+
<div class="intro-title" :class="{ 'auto-hide': autoHideIntroTitle }">
|
|
6
|
+
<h2>{{ introTitle }}</h2>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
<div class="media-overlay" v-if="initialPlayButton">
|
|
10
|
+
<div class="initial-play">
|
|
11
|
+
<media-play-button mediapaused="" class="media-button" aria-label="play" tabindex="0" role="button" @click="video.play()">
|
|
12
|
+
<svg slot="icon" viewBox="0 0 32 32">
|
|
13
|
+
<g>
|
|
14
|
+
<path id="icon-play" d="M20.7131 14.6976C21.7208 15.2735 21.7208 16.7265 20.7131 17.3024L12.7442 21.856C11.7442 22.4274 10.5 21.7054 10.5 20.5536L10.5 11.4464C10.5 10.2946 11.7442 9.57257 12.7442 10.144L20.7131 14.6976Z"></path>
|
|
15
|
+
</g>
|
|
16
|
+
</svg>
|
|
17
|
+
</media-play-button>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
4
20
|
<slot name="before-media"></slot>
|
|
5
21
|
<media-theme-sutro class="video-player-theme-container" :class="{'is-fullscreen': isFullscreen}">
|
|
6
22
|
<video
|
|
@@ -58,6 +74,10 @@ import 'player.style/sutro';
|
|
|
58
74
|
import SubtitleBlock from './SubtitleBlock.vue';
|
|
59
75
|
|
|
60
76
|
const props = defineProps({
|
|
77
|
+
introTitle: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: ''
|
|
80
|
+
},
|
|
61
81
|
previewImageLink: {
|
|
62
82
|
type: String,
|
|
63
83
|
default: ''
|
|
@@ -111,6 +131,9 @@ const subtitlesContainer = ref(null)
|
|
|
111
131
|
const currentSubtitleLang = ref(null)
|
|
112
132
|
const videoCursor = ref(0)
|
|
113
133
|
const isFullscreen = ref(false);
|
|
134
|
+
const orientation = ref(null)
|
|
135
|
+
const autoHideIntroTitle = ref(false);
|
|
136
|
+
const initialPlayButton = ref(false);
|
|
114
137
|
|
|
115
138
|
const videoElement = defineModel()
|
|
116
139
|
|
|
@@ -125,6 +148,25 @@ onMounted(() => {
|
|
|
125
148
|
|
|
126
149
|
video.value.addEventListener('timeupdate', updateCurrentTime);
|
|
127
150
|
document.addEventListener('fullscreenchange', onFullscreenChange);
|
|
151
|
+
document.addEventListener('orientationchange', onOrientationChange);
|
|
152
|
+
window.screen.orientation.addEventListener("change", onOrientationChange);
|
|
153
|
+
|
|
154
|
+
if(video.value.paused || video.value.currentTime === 0) {
|
|
155
|
+
initialPlayButton.value = true
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* detect initial display orientation
|
|
160
|
+
*/
|
|
161
|
+
if (typeof window.orientation === "undefined") {
|
|
162
|
+
orientation.value = window.screen.orientation.angle === 0 || window.screen.orientation.angle === 180
|
|
163
|
+
? "portrait"
|
|
164
|
+
: "landscape";
|
|
165
|
+
} else {
|
|
166
|
+
orientation.value = window.orientation === 0 || window.orientation === 180
|
|
167
|
+
? "portrait"
|
|
168
|
+
: "landscape"; // for safari
|
|
169
|
+
}
|
|
128
170
|
|
|
129
171
|
/**
|
|
130
172
|
* overwrite player.style video fullscreen button
|
|
@@ -136,11 +178,11 @@ onMounted(() => {
|
|
|
136
178
|
if (mediaTheme && mediaTheme.shadowRoot) {
|
|
137
179
|
const fullscreenButton = mediaTheme.shadowRoot.querySelector('media-fullscreen-button');
|
|
138
180
|
if (fullscreenButton) {
|
|
139
|
-
fullscreenButton.handleClick = (event) => {
|
|
181
|
+
fullscreenButton.handleClick = async (event) => {
|
|
140
182
|
event.preventDefault();
|
|
141
183
|
event.stopPropagation();
|
|
142
184
|
event.stopImmediatePropagation();
|
|
143
|
-
|
|
185
|
+
enterFullscreen(event)
|
|
144
186
|
}
|
|
145
187
|
observer.disconnect();
|
|
146
188
|
} else {
|
|
@@ -162,6 +204,8 @@ onUnmounted(() => {
|
|
|
162
204
|
if (video.value) {
|
|
163
205
|
video.value.removeEventListener('timeupdate', updateCurrentTime);
|
|
164
206
|
document.removeEventListener('fullscreenchange', onFullscreenChange);
|
|
207
|
+
document.removeEventListener('orientationchange', onOrientationChange);
|
|
208
|
+
window.screen.orientation.addEventListener("change", onOrientationChange);
|
|
165
209
|
}
|
|
166
210
|
});
|
|
167
211
|
|
|
@@ -193,11 +237,39 @@ watch([props, videoElement], (a) => {
|
|
|
193
237
|
function onFullscreenChange() {
|
|
194
238
|
isFullscreen.value = !!document.fullscreenElement
|
|
195
239
|
emit('video-fullscreen-change', document.fullscreenElement)
|
|
240
|
+
|
|
241
|
+
// hide intro title after x seconds
|
|
242
|
+
if(isFullscreen.value === true) {
|
|
243
|
+
setTimeout(() => {
|
|
244
|
+
autoHideIntroTitle.value = true;
|
|
245
|
+
}, 5000)
|
|
246
|
+
} else {
|
|
247
|
+
autoHideIntroTitle.value = false;
|
|
248
|
+
}
|
|
196
249
|
};
|
|
197
250
|
|
|
251
|
+
function onOrientationChange(e) {
|
|
252
|
+
let angle;
|
|
253
|
+
if (e.target && e.target.screen && e.target.screen.orientation) {
|
|
254
|
+
angle = e.target.screen.orientation.angle;
|
|
255
|
+
} else if (typeof window.orientation !== "undefined") {
|
|
256
|
+
// extra sausage for safari
|
|
257
|
+
angle = window.orientation;
|
|
258
|
+
}
|
|
259
|
+
orientation.value = angle === 0 || angle === 180
|
|
260
|
+
? "portrait"
|
|
261
|
+
: "landscape";
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function enterFullscreen(event) {
|
|
265
|
+
emit('video-fullscreen-action', event)
|
|
266
|
+
}
|
|
198
267
|
|
|
199
268
|
function updateCurrentTime() {
|
|
200
269
|
videoCursor.value = video.value.currentTime;
|
|
270
|
+
if(!video.value.paused) {
|
|
271
|
+
initialPlayButton.value = false;
|
|
272
|
+
}
|
|
201
273
|
}
|
|
202
274
|
|
|
203
275
|
function toggleTranscript() {
|
|
@@ -315,7 +387,49 @@ function changeSpeed(e) {
|
|
|
315
387
|
position: relative;
|
|
316
388
|
line-height: 0;
|
|
317
389
|
}
|
|
318
|
-
|
|
390
|
+
.media-overlay {
|
|
391
|
+
position: absolute;
|
|
392
|
+
height: calc(100% - 50px);
|
|
393
|
+
top: 0;
|
|
394
|
+
width: 100%;
|
|
395
|
+
z-index: 99;
|
|
396
|
+
background: linear-gradient(180deg, rgba(2,0,36,1) 0%, rgba(0,0,0,0) 100%);
|
|
397
|
+
}
|
|
398
|
+
.media-overlay .initial-play {
|
|
399
|
+
display: flex;
|
|
400
|
+
justify-content: center;
|
|
401
|
+
align-content: center;
|
|
402
|
+
align-items: center;
|
|
403
|
+
height: 100%;
|
|
404
|
+
}
|
|
405
|
+
.media-overlay .initial-play media-play-button {
|
|
406
|
+
width: 80px;
|
|
407
|
+
height: 80px;
|
|
408
|
+
border-radius: 10px;
|
|
409
|
+
}
|
|
410
|
+
.media-overlay .initial-play media-play-button svg {
|
|
411
|
+
width: 100%;
|
|
412
|
+
height: 100%;
|
|
413
|
+
}
|
|
414
|
+
.media-fullscreen-overlay {
|
|
415
|
+
display: none;
|
|
416
|
+
position: fixed;
|
|
417
|
+
top: 0;
|
|
418
|
+
left: 0;
|
|
419
|
+
width: 100vw;
|
|
420
|
+
z-index: 9999999;
|
|
421
|
+
padding: 2rem 5rem;
|
|
422
|
+
}
|
|
423
|
+
.is-fullscreen .media-fullscreen-overlay {
|
|
424
|
+
display: block!important;
|
|
425
|
+
}
|
|
426
|
+
.intro-title h2 {
|
|
427
|
+
font-size: 23px;
|
|
428
|
+
color: white;
|
|
429
|
+
opacity: 1;
|
|
430
|
+
}
|
|
431
|
+
.fullscreen-video .media-container {
|
|
432
|
+
}
|
|
319
433
|
.video-player-theme-container.is-fullscreen {
|
|
320
434
|
width: 100vw;
|
|
321
435
|
height: 100vh;
|
|
@@ -326,4 +440,11 @@ function changeSpeed(e) {
|
|
|
326
440
|
height: 100vh;
|
|
327
441
|
object-fit: cover;
|
|
328
442
|
}
|
|
443
|
+
|
|
444
|
+
.auto-hide {
|
|
445
|
+
opacity: 0;
|
|
446
|
+
-webkit-transition: opacity 1.5s ease-in-out;
|
|
447
|
+
-moz-transition: opacity 1.5s ease-in-out;
|
|
448
|
+
transition: opacity 1.5s ease-in-out;
|
|
449
|
+
}
|
|
329
450
|
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<BasePlayer
|
|
3
|
+
:introTitle="introTitle"
|
|
3
4
|
:previewImageLink="previewImageLink"
|
|
4
5
|
:link="link"
|
|
5
6
|
:progress="progress"
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
import BasePlayer from './BasePlayer.vue'
|
|
27
28
|
import { ref } from 'vue'
|
|
28
29
|
|
|
29
|
-
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change'])
|
|
30
|
+
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change', 'video-fullscreen-action'])
|
|
30
31
|
|
|
31
32
|
const videoElement = ref(null);
|
|
32
33
|
|
|
@@ -59,6 +60,10 @@ defineProps({
|
|
|
59
60
|
type: Boolean,
|
|
60
61
|
default: false
|
|
61
62
|
},
|
|
63
|
+
introTitle: {
|
|
64
|
+
type: String,
|
|
65
|
+
default: ''
|
|
66
|
+
},
|
|
62
67
|
showTranscriptBlock: {
|
|
63
68
|
type: Boolean,
|
|
64
69
|
default: true
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
@video-fullscreen-change="onVideoFullScreenChange"
|
|
6
6
|
@video-ended="onVideoEnd"
|
|
7
7
|
@video-fullscreen-action="oVideoFullscreenAction"
|
|
8
|
+
:introTitle="introTitle"
|
|
8
9
|
:previewImageLink="previewImageLink"
|
|
9
10
|
:showTranscriptBlock="showTranscriptBlock"
|
|
10
11
|
:isFullscreen="isFullscreen"
|
|
@@ -69,6 +70,10 @@ defineProps({
|
|
|
69
70
|
type: Boolean,
|
|
70
71
|
default: false
|
|
71
72
|
},
|
|
73
|
+
introTitle: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: ''
|
|
76
|
+
},
|
|
72
77
|
showTranscriptBlock: {
|
|
73
78
|
type: Boolean,
|
|
74
79
|
default: true
|