@grfzhl/vue-hls-player 1.0.13 → 1.0.15

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 - v1.0.14
187
+ - Fixes
188
+ - Small styling improvements
189
+
186
190
  v1.0.9
187
191
  - Fix sizes in fullscreen mode for video
188
192
  - Hide transcript block completely when hidden
@@ -7,7 +7,7 @@
7
7
  </div>
8
8
  </div>
9
9
  <div class="media-overlay" v-if="initialPlayButton">
10
- <div class="initial-play">
10
+ <div class="initial-play" :class="{'hide-playbutton': hideInitialPlayButton}">
11
11
  <media-play-button mediapaused="" class="media-button" aria-label="play" tabindex="0" role="button" @click="video.play()">
12
12
  <svg slot="icon" viewBox="0 0 32 32">
13
13
  <g>
@@ -122,6 +122,10 @@ const props = defineProps({
122
122
  isFullscreen: {
123
123
  type: Boolean,
124
124
  default: false
125
+ },
126
+ hideInitialPlayButton: {
127
+ type: Boolean,
128
+ default: false
125
129
  }
126
130
  })
127
131
 
@@ -134,6 +138,7 @@ const isFullscreen = ref(false);
134
138
  const orientation = ref(null)
135
139
  const autoHideIntroTitle = ref(false);
136
140
  const initialPlayButton = ref(false);
141
+ const hideInitialPlayButton = ref(false)
137
142
 
138
143
  const videoElement = defineModel()
139
144
 
@@ -153,6 +158,12 @@ onMounted(() => {
153
158
 
154
159
  if(video.value.paused || video.value.currentTime === 0) {
155
160
  initialPlayButton.value = true
161
+
162
+ if(props.hideInitialPlayButton) {
163
+ setTimeout(() => {
164
+ hideInitialPlayButton.value = true
165
+ }, 1200)
166
+ }
156
167
  }
157
168
 
158
169
  /**
@@ -173,24 +184,24 @@ onMounted(() => {
173
184
  * to inject own fullscreen logic
174
185
  */
175
186
  const observer = new MutationObserver((mutationsList, observer) => {
176
- const mediaTheme = document.querySelector('.video-player-theme-container');
177
-
178
- if (mediaTheme && mediaTheme.shadowRoot) {
179
- const fullscreenButton = mediaTheme.shadowRoot.querySelector('media-fullscreen-button');
180
- if (fullscreenButton) {
181
- fullscreenButton.handleClick = async (event) => {
182
- event.preventDefault();
183
- event.stopPropagation();
184
- event.stopImmediatePropagation();
185
- enterFullscreen(event)
187
+ const mediaTheme = document.querySelector('.video-player-theme-container');
188
+
189
+ if (mediaTheme && mediaTheme.shadowRoot) {
190
+ const fullscreenButton = mediaTheme.shadowRoot.querySelector('media-fullscreen-button');
191
+ if (fullscreenButton) {
192
+ fullscreenButton.handleClick = async (event) => {
193
+ event.preventDefault();
194
+ event.stopPropagation();
195
+ event.stopImmediatePropagation();
196
+ enterFullscreen(event)
197
+ }
198
+ observer.disconnect();
199
+ } else {
200
+ console.error('Button not found in Shadow DOM!');
186
201
  }
187
- observer.disconnect();
188
202
  } else {
189
- console.error('Button not found in Shadow DOM!');
203
+ console.error('Shadow Root not found!');
190
204
  }
191
- } else {
192
- console.error('Shadow Root not found!');
193
- }
194
205
  })
195
206
  observer.observe(document.body, { childList: true, subtree: true });
196
207
  }
@@ -370,6 +381,7 @@ function changeSpeed(e) {
370
381
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
371
382
  transform: translate(-50%) translateY(calc(-100% - 60px));
372
383
  }
384
+
373
385
  .custom-subtitles .subtitle-text {
374
386
  color: white;
375
387
  font-size: 14px;
@@ -381,12 +393,18 @@ function changeSpeed(e) {
381
393
  .video-player-theme-container, .hls-player {
382
394
  width: 100%;
383
395
  height: 100%;
396
+ margin: 0;
397
+ }
398
+
399
+ .video-player-theme-container video {
400
+ object-fit: cover;
384
401
  }
385
402
 
386
403
  .video-container {
387
404
  position: relative;
388
405
  line-height: 0;
389
406
  }
407
+
390
408
  .media-overlay {
391
409
  position: absolute;
392
410
  height: calc(100% - 50px);
@@ -394,6 +412,9 @@ function changeSpeed(e) {
394
412
  width: 100%;
395
413
  z-index: 99;
396
414
  background: linear-gradient(180deg, rgba(2,0,36,1) 0%, rgba(0,0,0,0) 100%);
415
+ -webkit-transition: 1.5s ease-in-out;
416
+ -moz-transition: 1.5s ease-in-out;
417
+ transition: 1.5s ease-in-out;
397
418
  }
398
419
  .media-overlay .initial-play {
399
420
  display: flex;
@@ -401,6 +422,15 @@ function changeSpeed(e) {
401
422
  align-content: center;
402
423
  align-items: center;
403
424
  height: 100%;
425
+ -webkit-transition: 0.6s ease-in-out;
426
+ -moz-transition: 0.6s ease-in-out;
427
+ transition: 0.6s ease-in-out;
428
+ }
429
+ .media-overlay .initial-play.hide-playbutton {
430
+ opacity: 0;
431
+ }
432
+ .vp-vpvideo-block:hover .media-overlay .initial-play.hide-playbutton {
433
+ opacity: 1;
404
434
  }
405
435
  .media-overlay .initial-play media-play-button {
406
436
  width: 80px;
@@ -3,13 +3,13 @@
3
3
  <div class="transcript-toggle">
4
4
  <button data-headlessui-state="open" @click="toggleTranscript()">
5
5
  <div class="icon">
6
- <svg v-if="!showTranscriptBlock" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon duration-200 h-4 w-4 text-gray-900 stroke-1"><path d="m9 18 6-6-6-6"></path></svg>
7
- <svg v-if="showTranscriptBlock" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon rotate-90 transform duration-200 h-4 w-4 text-gray-900 stroke-1"><path d="m9 18 6-6-6-6"></path></svg>
6
+ <svg v-if="!toggleTranscriptBlock" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon duration-200 h-4 w-4 text-gray-900 stroke-1"><path d="m9 18 6-6-6-6"></path></svg>
7
+ <svg v-if="toggleTranscriptBlock" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right-icon rotate-90 transform duration-200 h-4 w-4 text-gray-900 stroke-1"><path d="m9 18 6-6-6-6"></path></svg>
8
8
  </div>
9
9
  Transcript
10
10
  </button>
11
11
  </div>
12
- <ul v-if="txtCues.length && showTranscriptBlock" class="subtitles">
12
+ <ul v-if="txtCues.length && toggleTranscriptBlock" class="subtitles">
13
13
  <li
14
14
  v-for="(txtCue, index) in txtCues"
15
15
  :key="index"
@@ -56,6 +56,7 @@
56
56
  border: 1px solid var(--outline-gray-1);
57
57
  padding: 10px;
58
58
  font-family: Arial, sans-serif;
59
+ margin-top: 20px;
59
60
  }
60
61
 
61
62
  .subtitles {
@@ -75,6 +76,10 @@
75
76
  padding-top: 4px;
76
77
  }
77
78
 
79
+ .subtitles li .content {
80
+ max-width: 800px;
81
+ }
82
+
78
83
  .subtitles li .content .meta {
79
84
  display: flex;
80
85
  padding-bottom: 4px;
@@ -120,6 +125,10 @@ const props = defineProps({
120
125
  showTranscriptBlock: {
121
126
  type: Boolean,
122
127
  default: true
128
+ },
129
+ toggleTranscriptBlock: {
130
+ type: Boolean,
131
+ default: true
123
132
  }
124
133
  });
125
134
 
@@ -173,7 +182,7 @@ function highlightActiveCue(currentTime) {
173
182
  }
174
183
 
175
184
  function toggleTranscript() {
176
- emit('toggleTranscript', null)
185
+ props.toggleTranscriptBlock = !props.toggleTranscriptBlock
177
186
  }
178
187
 
179
188
  function seekTo(time) {
@@ -295,6 +304,9 @@ async function parseTXT(fileUrl) {
295
304
 
296
305
  // Hilfsfunktionen
297
306
  function timeToSeconds(timestamp) {
307
+ if(!timestamp) {
308
+ return 0
309
+ }
298
310
  const [hours, minutes, seconds] = timestamp.split(':').map(parseFloat);
299
311
  return hours * 3600 + minutes * 60 + seconds;
300
312
  }
@@ -10,6 +10,7 @@
10
10
  :onVideoEnd="onVideoEnd"
11
11
  :isFullscreen="isFullscreen"
12
12
  :showTranscriptBlock="showTranscriptBlock"
13
+ :hideInitialPlayButton="hideInitialPlayButton"
13
14
  @pause="pause"
14
15
  @video-ended="onVideoEnd"
15
16
  @video-fullscreen-change="onFullscreenChange"
@@ -67,6 +68,10 @@ defineProps({
67
68
  showTranscriptBlock: {
68
69
  type: Boolean,
69
70
  default: true
71
+ },
72
+ hideInitialPlayButton: {
73
+ type: Boolean,
74
+ default: false
70
75
  }
71
76
  })
72
77
 
@@ -14,6 +14,7 @@
14
14
  :isMuted="isMuted"
15
15
  :autoplay="autoplay"
16
16
  v-model="videoElement"
17
+ :hideInitialPlayButton="hideInitialPlayButton"
17
18
  >
18
19
  <template v-slot:before-media><slot name="before-media"></slot></template>
19
20
  <template v-slot:after-media><slot name="after-media"></slot></template>
@@ -77,6 +78,10 @@ defineProps({
77
78
  showTranscriptBlock: {
78
79
  type: Boolean,
79
80
  default: true
81
+ },
82
+ hideInitialPlayButton: {
83
+ type: Boolean,
84
+ default: false
80
85
  }
81
86
  })
82
87
 
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.13",
4
+ "version": "1.0.15",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"