@grfzhl/vue-hls-player 1.1.16 → 1.1.18

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
@@ -207,10 +207,16 @@ At the moment the following attribute are supported:
207
207
  ```
208
208
 
209
209
  ### Last release:
210
+ v1.1.18
211
+ - Added new slot `between-video-and-transcript` to `BasePlayer.vue`, `VDefaultVideoPlayer.vue` and `index.vue`
212
+ to allow injection of custom UI between video and transcript.
213
+ - Introduced a continuous **Frame Pointer Loop** that emits a `pointer-update` event with the current playback time and calculated frame number (30 fps) for real-time frame tracking.
214
+ v1.1.17
215
+ - Keep query params for transcription when getting from .vtt file to .txt
210
216
  v1.1.16
211
217
  - Add the options prop to both index.vue and VpDefaultVideoPlayer.vue to pass fullscreen label settings to the BasePlayer component.
212
218
  - Update fullscreen toggle logic: adjust aria-label, add or remove mediaIsFullscreen attribute, and safely access media-tooltip via shadowRoot to ensure proper icon and tooltip state handling.
213
- v1.1.13 - v1.0.15
219
+ v1.1.13 - v1.1.15
214
220
  - Update the hls.js package
215
221
  - Fixes
216
222
 
@@ -67,6 +67,7 @@
67
67
  <slot name="after-media"></slot>
68
68
  </div>
69
69
  </div>
70
+ <slot name="between-video-and-transcript"></slot>
70
71
  <slot name="before-transcripts"></slot>
71
72
  <SubtitleBlock
72
73
  ref="transcriptRef"
@@ -155,7 +156,7 @@ const props = defineProps({
155
156
  }
156
157
  })
157
158
 
158
- const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change'])
159
+ const emit = defineEmits(['pause', 'video-ended', 'video-fullscreen-change', 'pointer-update'])
159
160
  const video = ref(null)
160
161
  const subtitlesContainer = ref(null)
161
162
  const currentSubtitleLang = ref(null)
@@ -172,6 +173,19 @@ let currentTime = 0
172
173
  let hls = null
173
174
  let buttonElement = null
174
175
 
176
+ // --- Frame Pointer Loop ---
177
+ let rafId = null
178
+ const FPS = 30
179
+
180
+ function emitPointerUpdate() {
181
+ if (video.value) {
182
+ const t = video.value.currentTime || 0
183
+ const frame = Math.floor(t * FPS)
184
+ emit('pointer-update', { currentTime: t, frame })
185
+ }
186
+ rafId = requestAnimationFrame(emitPointerUpdate)
187
+ }
188
+
175
189
  const videoElement = defineModel()
176
190
 
177
191
  onMounted(() => {
@@ -185,6 +199,8 @@ onUnmounted(() => {
185
199
  document.removeEventListener('fullscreenchange', onFullscreenChange);
186
200
  document.removeEventListener('orientationchange', onOrientationChange);
187
201
  window.screen.orientation.removeEventListener("change", onOrientationChange);
202
+ // --- Stop pointer-update loop ---
203
+ if (rafId) cancelAnimationFrame(rafId)
188
204
  });
189
205
 
190
206
  const mutedAttr = computed(() => {
@@ -516,6 +532,10 @@ function initVideo() {
516
532
  console.error('Shadow Root not found!');
517
533
  }
518
534
  })
535
+ // --- Start pointer-update loop ---
536
+ if (!rafId) {
537
+ emitPointerUpdate()
538
+ }
519
539
  observer.observe(document.body, { childList: true, subtree: true });
520
540
  }
521
541
  }
@@ -143,7 +143,7 @@ const videoCursor = ref(0);
143
143
  const loadCues = async () => {
144
144
  if (props.subtitle) {
145
145
  const vttPath = props.subtitle.link;
146
- const txtPath = vttPath.replace(/\.vtt$/, '.txt');
146
+ const txtPath = vttPath.replace(/\.vtt(?=\?|$)/, '.txt');
147
147
  vttCues.value = await parseVTT(vttPath);
148
148
  txtCues.value = await parseTXT(txtPath);
149
149
  }
@@ -21,6 +21,7 @@
21
21
  >
22
22
  <template v-slot:before-media><slot name="before-media"></slot></template>
23
23
  <template v-slot:after-media><slot name="after-media"></slot></template>
24
+ <template v-slot:between-video-and-transcript><slot name="between-video-and-transcript"></slot></template>
24
25
  <template v-slot:before-transcripts><slot name="before-transcripts"></slot></template>
25
26
  <template v-slot:after-transcripts><slot name="after-transcripts"></slot></template>
26
27
  </BasePlayer>
@@ -20,6 +20,7 @@
20
20
  >
21
21
  <template v-slot:before-media><slot name="before-media"></slot></template>
22
22
  <template v-slot:after-media><slot name="after-media"></slot></template>
23
+ <template v-slot:between-video-and-transcript><slot name="between-video-and-transcript"></slot></template>
23
24
  <template v-slot:before-transcripts><slot name="before-transcripts"></slot></template>
24
25
  <template v-slot:after-transcripts><slot name="after-transcripts"></slot></template>
25
26
  </VDefaultVideoPlayer>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@grfzhl/vue-hls-player",
3
3
  "private": false,
4
- "version": "1.1.16",
4
+ "version": "1.1.18",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"