@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 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
- 1. Event, handling the fullscreen action of the player
128
- @video-fullscreen-action="fullScreenAction"
129
- ```
130
- const fullScreenAction = (data) => {
131
- if(isFullscreen.value) {
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', 'video-fullscreen-action'])
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
- enterFullscreen(event)
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, (v) => {
255
- prepareVideoPlayer();
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
- isFullscreen.value = !!document.fullscreenElement
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
- function enterFullscreen(event) {
290
- emit('video-fullscreen-action', event)
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', 'video-fullscreen-action'])
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 oVideoFullscreenAction(data) {
95
- emit('video-fullscreen-action', data)
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 oVideoFullscreenAction(data) {
101
- emit('video-fullscreen-action', data)
107
+ function startFullscreen() {
108
+ childRef.value.startFullscreen();
102
109
  }
103
110
  </script>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@grfzhl/vue-hls-player",
3
3
  "private": false,
4
- "version": "1.0.20",
4
+ "version": "1.1.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"