@grfzhl/vue-hls-player 1.0.8 → 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.
package/README.md
CHANGED
|
@@ -183,6 +183,10 @@ it makes the video muted
|
|
|
183
183
|
it will set the native <video> autoplay property
|
|
184
184
|
|
|
185
185
|
### Last release:
|
|
186
|
+
v1.0.9
|
|
187
|
+
- Fix sizes in fullscreen mode for video
|
|
188
|
+
- Hide transcript block completely when hidden
|
|
189
|
+
|
|
186
190
|
v1.0.8
|
|
187
191
|
- Add slots to inject own elements nearby video element
|
|
188
192
|
- Add prop for autoplay video
|
|
@@ -1,8 +1,13 @@
|
|
|
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
|
-
<media-theme-sutro class="video-player-theme-container">
|
|
10
|
+
<media-theme-sutro class="video-player-theme-container" :class="{'is-fullscreen': isFullscreen}">
|
|
6
11
|
<video
|
|
7
12
|
class="hls-player"
|
|
8
13
|
slot="media"
|
|
@@ -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
|
|
|
@@ -191,9 +219,35 @@ watch([props, videoElement], (a) => {
|
|
|
191
219
|
})
|
|
192
220
|
|
|
193
221
|
function onFullscreenChange() {
|
|
222
|
+
isFullscreen.value = !!document.fullscreenElement
|
|
194
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
|
+
}
|
|
195
233
|
};
|
|
196
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
|
+
}
|
|
197
251
|
|
|
198
252
|
function updateCurrentTime() {
|
|
199
253
|
videoCursor.value = video.value.currentTime;
|
|
@@ -307,9 +361,47 @@ function changeSpeed(e) {
|
|
|
307
361
|
|
|
308
362
|
.video-player-theme-container, .hls-player {
|
|
309
363
|
width: 100%;
|
|
364
|
+
height: 100%;
|
|
310
365
|
}
|
|
311
366
|
|
|
312
367
|
.video-container {
|
|
313
368
|
position: relative;
|
|
369
|
+
line-height: 0;
|
|
370
|
+
}
|
|
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
|
+
}
|
|
390
|
+
.video-player-theme-container.is-fullscreen {
|
|
391
|
+
width: 100vw;
|
|
392
|
+
height: 100vh;
|
|
393
|
+
object-fit: cover;
|
|
394
|
+
}
|
|
395
|
+
.video-player-theme-container.is-fullscreen .hls-player {
|
|
396
|
+
width: 100vw;
|
|
397
|
+
height: 100vh;
|
|
398
|
+
object-fit: cover;
|
|
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;
|
|
314
406
|
}
|
|
315
407
|
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="transcript-container" ref="subtitlesContainer">
|
|
2
|
+
<div class="transcript-container" ref="subtitlesContainer" v-if="showTranscriptBlock">
|
|
3
3
|
<div class="transcript-toggle">
|
|
4
4
|
<button data-headlessui-state="open" @click="toggleTranscript()">
|
|
5
5
|
<div class="icon">
|
|
@@ -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
|