@grfzhl/vue-hls-player 1.0.9 → 1.0.11
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,11 @@
|
|
|
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>
|
|
4
9
|
<slot name="before-media"></slot>
|
|
5
10
|
<media-theme-sutro class="video-player-theme-container" :class="{'is-fullscreen': isFullscreen}">
|
|
6
11
|
<video
|
|
@@ -58,6 +63,10 @@ import 'player.style/sutro';
|
|
|
58
63
|
import SubtitleBlock from './SubtitleBlock.vue';
|
|
59
64
|
|
|
60
65
|
const props = defineProps({
|
|
66
|
+
introTitle: {
|
|
67
|
+
type: String,
|
|
68
|
+
default: ''
|
|
69
|
+
},
|
|
61
70
|
previewImageLink: {
|
|
62
71
|
type: String,
|
|
63
72
|
default: ''
|
|
@@ -111,6 +120,8 @@ const subtitlesContainer = ref(null)
|
|
|
111
120
|
const currentSubtitleLang = ref(null)
|
|
112
121
|
const videoCursor = ref(0)
|
|
113
122
|
const isFullscreen = ref(false);
|
|
123
|
+
const orientation = ref(null)
|
|
124
|
+
const autoHideIntroTitle = ref(false);
|
|
114
125
|
|
|
115
126
|
const videoElement = defineModel()
|
|
116
127
|
|
|
@@ -125,6 +136,21 @@ onMounted(() => {
|
|
|
125
136
|
|
|
126
137
|
video.value.addEventListener('timeupdate', updateCurrentTime);
|
|
127
138
|
document.addEventListener('fullscreenchange', onFullscreenChange);
|
|
139
|
+
document.addEventListener('orientationchange', onOrientationChange);
|
|
140
|
+
window.screen.orientation.addEventListener("change", onOrientationChange);
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* detect initial display orientation
|
|
144
|
+
*/
|
|
145
|
+
if (typeof window.orientation === "undefined") {
|
|
146
|
+
orientation.value = window.screen.orientation.angle === 0 || window.screen.orientation.angle === 180
|
|
147
|
+
? "portrait"
|
|
148
|
+
: "landscape";
|
|
149
|
+
} else {
|
|
150
|
+
orientation.value = window.orientation === 0 || window.orientation === 180
|
|
151
|
+
? "portrait"
|
|
152
|
+
: "landscape"; // for safari
|
|
153
|
+
}
|
|
128
154
|
|
|
129
155
|
/**
|
|
130
156
|
* overwrite player.style video fullscreen button
|
|
@@ -136,11 +162,11 @@ onMounted(() => {
|
|
|
136
162
|
if (mediaTheme && mediaTheme.shadowRoot) {
|
|
137
163
|
const fullscreenButton = mediaTheme.shadowRoot.querySelector('media-fullscreen-button');
|
|
138
164
|
if (fullscreenButton) {
|
|
139
|
-
fullscreenButton.handleClick = (event) => {
|
|
165
|
+
fullscreenButton.handleClick = async (event) => {
|
|
140
166
|
event.preventDefault();
|
|
141
167
|
event.stopPropagation();
|
|
142
168
|
event.stopImmediatePropagation();
|
|
143
|
-
|
|
169
|
+
enterFullscreen(event)
|
|
144
170
|
}
|
|
145
171
|
observer.disconnect();
|
|
146
172
|
} else {
|
|
@@ -162,6 +188,8 @@ onUnmounted(() => {
|
|
|
162
188
|
if (video.value) {
|
|
163
189
|
video.value.removeEventListener('timeupdate', updateCurrentTime);
|
|
164
190
|
document.removeEventListener('fullscreenchange', onFullscreenChange);
|
|
191
|
+
document.removeEventListener('orientationchange', onOrientationChange);
|
|
192
|
+
window.screen.orientation.addEventListener("change", onOrientationChange);
|
|
165
193
|
}
|
|
166
194
|
});
|
|
167
195
|
|
|
@@ -193,8 +221,33 @@ watch([props, videoElement], (a) => {
|
|
|
193
221
|
function onFullscreenChange() {
|
|
194
222
|
isFullscreen.value = !!document.fullscreenElement
|
|
195
223
|
emit('video-fullscreen-change', document.fullscreenElement)
|
|
224
|
+
|
|
225
|
+
// hide intro title after x seconds
|
|
226
|
+
if(isFullscreen.value === true) {
|
|
227
|
+
setTimeout(() => {
|
|
228
|
+
autoHideIntroTitle.value = true;
|
|
229
|
+
}, 5000)
|
|
230
|
+
} else {
|
|
231
|
+
autoHideIntroTitle.value = false;
|
|
232
|
+
}
|
|
196
233
|
};
|
|
197
234
|
|
|
235
|
+
function onOrientationChange(e) {
|
|
236
|
+
let angle;
|
|
237
|
+
if (e.target && e.target.screen && e.target.screen.orientation) {
|
|
238
|
+
angle = e.target.screen.orientation.angle;
|
|
239
|
+
} else if (typeof window.orientation !== "undefined") {
|
|
240
|
+
// extra sausage for safari
|
|
241
|
+
angle = window.orientation;
|
|
242
|
+
}
|
|
243
|
+
orientation.value = angle === 0 || angle === 180
|
|
244
|
+
? "portrait"
|
|
245
|
+
: "landscape";
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function enterFullscreen(event) {
|
|
249
|
+
emit('video-fullscreen-action', event)
|
|
250
|
+
}
|
|
198
251
|
|
|
199
252
|
function updateCurrentTime() {
|
|
200
253
|
videoCursor.value = video.value.currentTime;
|
|
@@ -315,7 +368,25 @@ function changeSpeed(e) {
|
|
|
315
368
|
position: relative;
|
|
316
369
|
line-height: 0;
|
|
317
370
|
}
|
|
318
|
-
|
|
371
|
+
.media-fullscreen-overlay {
|
|
372
|
+
display: none;
|
|
373
|
+
position: fixed;
|
|
374
|
+
top: 0;
|
|
375
|
+
left: 0;
|
|
376
|
+
width: 100vw;
|
|
377
|
+
z-index: 9999999;
|
|
378
|
+
padding: 2rem 5rem;
|
|
379
|
+
}
|
|
380
|
+
.is-fullscreen .media-fullscreen-overlay {
|
|
381
|
+
display: block!important;
|
|
382
|
+
}
|
|
383
|
+
.intro-title h2 {
|
|
384
|
+
font-size: 23px;
|
|
385
|
+
color: white;
|
|
386
|
+
opacity: 1;
|
|
387
|
+
}
|
|
388
|
+
.fullscreen-video .media-container {
|
|
389
|
+
}
|
|
319
390
|
.video-player-theme-container.is-fullscreen {
|
|
320
391
|
width: 100vw;
|
|
321
392
|
height: 100vh;
|
|
@@ -326,4 +397,11 @@ function changeSpeed(e) {
|
|
|
326
397
|
height: 100vh;
|
|
327
398
|
object-fit: cover;
|
|
328
399
|
}
|
|
400
|
+
|
|
401
|
+
.auto-hide {
|
|
402
|
+
opacity: 0;
|
|
403
|
+
-webkit-transition: opacity 1.5s ease-in-out;
|
|
404
|
+
-moz-transition: opacity 1.5s ease-in-out;
|
|
405
|
+
transition: opacity 1.5s ease-in-out;
|
|
406
|
+
}
|
|
329
407
|
</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
|