@grfzhl/vue-hls-player 1.0.20 → 1.1.0
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 +16 -11
- package/dist/VideoPlayer/BasePlayer.vue +69 -10
- package/dist/VideoPlayer/VDefaultVideoPlayer.vue +11 -4
- package/dist/VideoPlayer/index.vue +10 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,6 +73,17 @@ For **nuxt 3**, try to wrap this component in ClientOnly, images for previewImag
|
|
|
73
73
|
</ClientOnly>
|
|
74
74
|
```
|
|
75
75
|
### Props:
|
|
76
|
+
**fullScreenElement**:
|
|
77
|
+
1. value: 'hls-player-media-container', type: String
|
|
78
|
+
|
|
79
|
+
If you need to provide additional UI in fullscreen mode
|
|
80
|
+
you can input a parent wrapper of your player to show
|
|
81
|
+
in fullscreen
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
fullScreenElement="demo"
|
|
85
|
+
```
|
|
86
|
+
|
|
76
87
|
**type**:
|
|
77
88
|
1. value: 'default', type: String
|
|
78
89
|
|
|
@@ -124,17 +135,11 @@ const fullScreenAction = (fullScreenElement) => {
|
|
|
124
135
|
```
|
|
125
136
|
|
|
126
137
|
**@video-fullscreen-action**:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
document.exitFullscreen();
|
|
133
|
-
} else {
|
|
134
|
-
document.getElementById("video-container").requestFullscreen()
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
+
Removed in the 1.1.0 version.
|
|
139
|
+
It caused too much problems with mobile devices.
|
|
140
|
+
Now you can pass the desired element id to open
|
|
141
|
+
fullscreen with prop: fullScreenElement
|
|
142
|
+
|
|
138
143
|
**showTranscriptBlock**:
|
|
139
144
|
1. value: true or false, type: Boolean
|
|
140
145
|
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
<video
|
|
23
23
|
class="hls-player"
|
|
24
24
|
slot="media"
|
|
25
|
+
:key="link"
|
|
25
26
|
@pause="pause"
|
|
26
27
|
@keyup="changeSpeed"
|
|
27
28
|
@ended="onVideoEnd"
|
|
@@ -127,10 +128,14 @@ const props = defineProps({
|
|
|
127
128
|
hideInitialPlayButton: {
|
|
128
129
|
type: Boolean,
|
|
129
130
|
default: false
|
|
131
|
+
},
|
|
132
|
+
fullScreenElement: {
|
|
133
|
+
type: String,
|
|
134
|
+
default: 'hls-player-media-container'
|
|
130
135
|
}
|
|
131
136
|
})
|
|
132
137
|
|
|
133
|
-
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change'
|
|
138
|
+
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change'])
|
|
134
139
|
const video = ref(null)
|
|
135
140
|
const subtitlesContainer = ref(null)
|
|
136
141
|
const currentSubtitleLang = ref(null)
|
|
@@ -142,6 +147,7 @@ const initialPlayButton = ref(false);
|
|
|
142
147
|
const hideInitialPlayButton = ref(false)
|
|
143
148
|
const link = toRef(props, 'link');
|
|
144
149
|
const previewImageLink = toRef(props, 'previewImageLink');
|
|
150
|
+
let currentTime = 0
|
|
145
151
|
let hls = new Hls()
|
|
146
152
|
|
|
147
153
|
const videoElement = defineModel()
|
|
@@ -199,7 +205,7 @@ onMounted(() => {
|
|
|
199
205
|
event.preventDefault();
|
|
200
206
|
event.stopPropagation();
|
|
201
207
|
event.stopImmediatePropagation();
|
|
202
|
-
|
|
208
|
+
startFullscreen();
|
|
203
209
|
}
|
|
204
210
|
observer.disconnect();
|
|
205
211
|
} else {
|
|
@@ -251,17 +257,60 @@ watch([props, videoElement], (a) => {
|
|
|
251
257
|
}
|
|
252
258
|
})
|
|
253
259
|
|
|
254
|
-
watch(link, (
|
|
255
|
-
|
|
260
|
+
watch(link, (newLink, oldLink) => {
|
|
261
|
+
if (newLink !== oldLink) {
|
|
262
|
+
prepareVideoPlayer();
|
|
263
|
+
}
|
|
256
264
|
})
|
|
257
265
|
|
|
266
|
+
async function startFullscreen() {
|
|
267
|
+
let vpVideoBlock = document.getElementById(props.fullScreenElement);
|
|
268
|
+
if(video.value) {
|
|
269
|
+
currentTime = video.value.currentTime
|
|
270
|
+
}
|
|
271
|
+
if (document.fullscreenElement) {
|
|
272
|
+
if (screen.orientation && screen.orientation.unlock) {
|
|
273
|
+
screen.orientation.unlock();
|
|
274
|
+
}
|
|
275
|
+
await document.exitFullscreen();
|
|
276
|
+
isFullscreen.value = false;
|
|
277
|
+
} else {
|
|
278
|
+
isFullscreen.value = true;
|
|
279
|
+
try {
|
|
280
|
+
if (vpVideoBlock.requestFullscreen) {
|
|
281
|
+
await vpVideoBlock.requestFullscreen();
|
|
282
|
+
} else if (vpVideoBlock.webkitRequestFullscreen) {
|
|
283
|
+
vpVideoBlock = document.querySelector('video');
|
|
284
|
+
await vpVideoBlock.webkitRequestFullscreen(); // Safari
|
|
285
|
+
} else if (vpVideoBlock.mozRequestFullScreen) {
|
|
286
|
+
await vpVideoBlock.mozRequestFullScreen(); // Firefox
|
|
287
|
+
} else if (vpVideoBlock.msRequestFullscreen) {
|
|
288
|
+
await vpVideoBlock.msRequestFullscreen(); // IE/Edge
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (screen.orientation && screen.orientation.lock) {
|
|
292
|
+
try {
|
|
293
|
+
await screen.orientation.lock("landscape");
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.warn("Orientation lock failed", error);
|
|
296
|
+
}
|
|
297
|
+
} else {
|
|
298
|
+
console.warn("Orientation lock not supported.");
|
|
299
|
+
}
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error("Fullscreen could not be activated", error);
|
|
302
|
+
isFullscreen.value = false;
|
|
303
|
+
}
|
|
304
|
+
video.value.currentTime = currentTime;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
258
308
|
function onSubtitleError(link) {
|
|
259
309
|
console.error(`Error on loading subtitles: ${link}`);
|
|
260
310
|
}
|
|
261
311
|
|
|
262
|
-
function onFullscreenChange() {
|
|
263
|
-
|
|
264
|
-
emit('video-fullscreen-change', document.fullscreenElement)
|
|
312
|
+
function onFullscreenChange(e) {
|
|
313
|
+
e.preventDefault();
|
|
265
314
|
|
|
266
315
|
// hide intro title after x seconds
|
|
267
316
|
if(isFullscreen.value === true) {
|
|
@@ -271,6 +320,7 @@ function onFullscreenChange() {
|
|
|
271
320
|
} else {
|
|
272
321
|
autoHideIntroTitle.value = false;
|
|
273
322
|
}
|
|
323
|
+
isFullscreen.value = !!document.fullscreenElement;
|
|
274
324
|
};
|
|
275
325
|
|
|
276
326
|
function onOrientationChange(e) {
|
|
@@ -284,10 +334,17 @@ function onOrientationChange(e) {
|
|
|
284
334
|
orientation.value = angle === 0 || angle === 180
|
|
285
335
|
? "portrait"
|
|
286
336
|
: "landscape";
|
|
287
|
-
}
|
|
288
337
|
|
|
289
|
-
|
|
290
|
-
|
|
338
|
+
let isPortrait = angle === 0 || angle === 180;
|
|
339
|
+
let isLandscape = angle === 90 || angle === -90;
|
|
340
|
+
|
|
341
|
+
if (isFullscreen.value && isPortrait) {
|
|
342
|
+
setTimeout(async () => {
|
|
343
|
+
if (!document.fullscreenElement) {
|
|
344
|
+
startFullscreen();
|
|
345
|
+
}
|
|
346
|
+
}, 700);
|
|
347
|
+
}
|
|
291
348
|
}
|
|
292
349
|
|
|
293
350
|
function updateCurrentTime() {
|
|
@@ -375,6 +432,8 @@ function changeSpeed(e) {
|
|
|
375
432
|
video.value.playbackRate = video.value.playbackRate - 0.25
|
|
376
433
|
}
|
|
377
434
|
}
|
|
435
|
+
defineExpose({ startFullscreen });
|
|
436
|
+
|
|
378
437
|
</script>
|
|
379
438
|
<style>
|
|
380
439
|
video::cue {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
@pause="pause"
|
|
15
15
|
@video-ended="onVideoEnd"
|
|
16
16
|
@video-fullscreen-change="onFullscreenChange"
|
|
17
|
-
@video-fullscreen-action="oVideoFullscreenAction"
|
|
18
17
|
v-model="videoElement"
|
|
18
|
+
ref="childRef"
|
|
19
19
|
>
|
|
20
20
|
<template v-slot:before-media><slot name="before-media"></slot></template>
|
|
21
21
|
<template v-slot:after-media><slot name="after-media"></slot></template>
|
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
import BasePlayer from './BasePlayer.vue'
|
|
29
29
|
import { ref, toRef } from 'vue'
|
|
30
30
|
|
|
31
|
-
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change'
|
|
31
|
+
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change'])
|
|
32
32
|
|
|
33
33
|
const videoElement = ref(null);
|
|
34
|
+
const childRef = ref(null)
|
|
34
35
|
|
|
35
36
|
const props = defineProps({
|
|
36
37
|
previewImageLink: {
|
|
@@ -72,12 +73,18 @@ const props = defineProps({
|
|
|
72
73
|
hideInitialPlayButton: {
|
|
73
74
|
type: Boolean,
|
|
74
75
|
default: false
|
|
76
|
+
},
|
|
77
|
+
fullScreenElement: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: 'hls-player-media-container'
|
|
75
80
|
}
|
|
76
81
|
})
|
|
77
82
|
|
|
78
83
|
const link = toRef(props, 'link');
|
|
79
84
|
const previewImageLink = toRef(props, 'previewImageLink');
|
|
80
85
|
|
|
86
|
+
defineExpose({ startFullscreen });
|
|
87
|
+
|
|
81
88
|
function pause(currentTime) {
|
|
82
89
|
emit('pause', currentTime)
|
|
83
90
|
}
|
|
@@ -91,7 +98,7 @@ function onFullscreenChange(data) {
|
|
|
91
98
|
emit('video-fullscreen-change', data);
|
|
92
99
|
}
|
|
93
100
|
|
|
94
|
-
function
|
|
95
|
-
|
|
101
|
+
function startFullscreen() {
|
|
102
|
+
childRef.value.startFullscreen();
|
|
96
103
|
}
|
|
97
104
|
</script>
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
@pause="pause"
|
|
5
5
|
@video-fullscreen-change="onVideoFullScreenChange"
|
|
6
6
|
@video-ended="onVideoEnd"
|
|
7
|
-
@video-fullscreen-action="oVideoFullscreenAction"
|
|
8
7
|
:introTitle="introTitle"
|
|
9
8
|
:previewImageLink="previewImageLink"
|
|
10
9
|
:showTranscriptBlock="showTranscriptBlock"
|
|
@@ -14,6 +13,7 @@
|
|
|
14
13
|
:isMuted="isMuted"
|
|
15
14
|
:autoplay="autoplay"
|
|
16
15
|
v-model="videoElement"
|
|
16
|
+
ref="childRef"
|
|
17
17
|
:hideInitialPlayButton="hideInitialPlayButton"
|
|
18
18
|
>
|
|
19
19
|
<template v-slot:before-media><slot name="before-media"></slot></template>
|
|
@@ -37,6 +37,7 @@ import { ref, toRef } from 'vue'
|
|
|
37
37
|
const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change', 'video-fullscreen-action'])
|
|
38
38
|
|
|
39
39
|
const videoElement = ref(null);
|
|
40
|
+
const childRef = ref(null)
|
|
40
41
|
|
|
41
42
|
const props = defineProps({
|
|
42
43
|
previewImageLink: {
|
|
@@ -82,12 +83,18 @@ const props = defineProps({
|
|
|
82
83
|
hideInitialPlayButton: {
|
|
83
84
|
type: Boolean,
|
|
84
85
|
default: false
|
|
86
|
+
},
|
|
87
|
+
fullScreenElement: {
|
|
88
|
+
type: String,
|
|
89
|
+
default: 'hls-player-media-container'
|
|
85
90
|
}
|
|
86
91
|
})
|
|
87
92
|
|
|
88
93
|
const link = toRef(props, 'link');
|
|
89
94
|
const previewImageLink = toRef(props, 'previewImageLink');
|
|
90
95
|
|
|
96
|
+
defineExpose({ startFullscreen });
|
|
97
|
+
|
|
91
98
|
function pause(currentTime) {
|
|
92
99
|
emit('pause', currentTime)
|
|
93
100
|
}
|
|
@@ -97,7 +104,7 @@ function onVideoFullScreenChange(data) {
|
|
|
97
104
|
function onVideoEnd(data) {
|
|
98
105
|
emit('video-ended', data);
|
|
99
106
|
}
|
|
100
|
-
function
|
|
101
|
-
|
|
107
|
+
function startFullscreen() {
|
|
108
|
+
childRef.value.startFullscreen();
|
|
102
109
|
}
|
|
103
110
|
</script>
|