@grfzhl/vue-hls-player 1.1.3 → 1.1.5
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.
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
</div>
|
|
59
59
|
<slot name="before-transcripts"></slot>
|
|
60
60
|
<SubtitleBlock
|
|
61
|
+
ref="transcriptRef"
|
|
61
62
|
:subtitle="currentSubtitle"
|
|
62
63
|
:cursor="videoCursor"
|
|
63
64
|
:showTranscriptBlock="showTranscriptBlock"
|
|
@@ -143,20 +144,17 @@ const isFullscreen = ref(false);
|
|
|
143
144
|
const orientation = ref(null)
|
|
144
145
|
const autoHideIntroTitle = ref(false);
|
|
145
146
|
const initialPlayButton = ref(false);
|
|
146
|
-
const hideInitialPlayButton = ref(false)
|
|
147
|
-
const
|
|
147
|
+
const hideInitialPlayButton = ref(false);
|
|
148
|
+
const transcriptRef = ref(null);
|
|
148
149
|
const previewImageLink = toRef(props, 'previewImageLink');
|
|
150
|
+
const link = toRef(props, 'link');
|
|
149
151
|
let currentTime = 0
|
|
150
152
|
let hls = null
|
|
151
153
|
|
|
152
154
|
const videoElement = defineModel()
|
|
153
155
|
|
|
154
156
|
onMounted(() => {
|
|
155
|
-
prepareVideoPlayer()
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
onUpdated(() => {
|
|
159
|
-
|
|
157
|
+
prepareVideoPlayer(props.link)
|
|
160
158
|
})
|
|
161
159
|
|
|
162
160
|
onUnmounted(() => {
|
|
@@ -176,8 +174,13 @@ const mutedAttr = computed(() => {
|
|
|
176
174
|
const currentSubtitle = computed(() => {
|
|
177
175
|
if(props.subtitles) {
|
|
178
176
|
const current = props.subtitles.filter((subt) => {
|
|
179
|
-
|
|
177
|
+
if(currentSubtitleLang.value) {
|
|
178
|
+
return subt.lang === currentSubtitleLang.value
|
|
179
|
+
} else {
|
|
180
|
+
return subt.lang === "en"
|
|
181
|
+
}
|
|
180
182
|
})
|
|
183
|
+
console.log("current", currentSubtitleLang)
|
|
181
184
|
return current.length ? current[0] : null
|
|
182
185
|
}
|
|
183
186
|
return null
|
|
@@ -193,10 +196,11 @@ watch([props, videoElement], (a) => {
|
|
|
193
196
|
}
|
|
194
197
|
})
|
|
195
198
|
|
|
196
|
-
watch(
|
|
199
|
+
watch(
|
|
200
|
+
() => props.link,
|
|
201
|
+
(newLink, oldLink) => {
|
|
197
202
|
if (newLink !== oldLink) {
|
|
198
|
-
|
|
199
|
-
prepareVideoPlayer();
|
|
203
|
+
prepareVideoPlayer(newLink);
|
|
200
204
|
}
|
|
201
205
|
})
|
|
202
206
|
|
|
@@ -289,6 +293,11 @@ function updateCurrentTime() {
|
|
|
289
293
|
if(!video.value.paused) {
|
|
290
294
|
initialPlayButton.value = false;
|
|
291
295
|
}
|
|
296
|
+
|
|
297
|
+
// update transcripts
|
|
298
|
+
if(transcriptRef && video) {
|
|
299
|
+
transcriptRef.value.onTimeUpdate(video.value)
|
|
300
|
+
}
|
|
292
301
|
}
|
|
293
302
|
|
|
294
303
|
function toggleTranscript() {
|
|
@@ -300,15 +309,29 @@ function seekVideo(time) {
|
|
|
300
309
|
video.value.play()
|
|
301
310
|
}
|
|
302
311
|
|
|
303
|
-
function prepareVideoPlayer() {
|
|
312
|
+
function prepareVideoPlayer(link) {
|
|
313
|
+
let initiallyLoaded = true;
|
|
304
314
|
if (video.value) {
|
|
315
|
+
console.log("start hls gtest2 ", hls)
|
|
316
|
+
// video.value.src = link;
|
|
317
|
+
// video.value.load()
|
|
318
|
+
|
|
305
319
|
if (hls) {
|
|
306
320
|
hls.destroy();
|
|
321
|
+
initiallyLoaded = false;
|
|
307
322
|
}
|
|
323
|
+
console.log("a")
|
|
308
324
|
hls = new Hls();
|
|
309
|
-
|
|
310
|
-
hls.loadSource(
|
|
311
|
-
|
|
325
|
+
console.log("b")
|
|
326
|
+
hls.loadSource(link)
|
|
327
|
+
console.log("c", video.value)
|
|
328
|
+
// const shadowRoot = video.value?.shadowRoot;
|
|
329
|
+
// const videoElement = shadowRoot?.querySelector("video");
|
|
330
|
+
// const videoElement = document.querySelector("video.hls-player")[0]
|
|
331
|
+
// if(initiallyLoaded) {
|
|
332
|
+
hls.attachMedia(video.value)
|
|
333
|
+
// }
|
|
334
|
+
console.log("attach to ", video.value)
|
|
312
335
|
|
|
313
336
|
video.value.muted = props.isMuted
|
|
314
337
|
video.value.currentTime = props.progress
|
|
@@ -350,8 +373,10 @@ function prepareVideoPlayer() {
|
|
|
350
373
|
}
|
|
351
374
|
});
|
|
352
375
|
}
|
|
353
|
-
|
|
354
|
-
|
|
376
|
+
// if(!initiallyLoaded) {
|
|
377
|
+
setInterval(checkTrackModeChanges, 100);
|
|
378
|
+
initVideo();
|
|
379
|
+
// }
|
|
355
380
|
}
|
|
356
381
|
}
|
|
357
382
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<span
|
|
29
29
|
v-for="(word, wordIndex) in txtCue.dialog[0].text.split('')"
|
|
30
30
|
:key="wordIndex"
|
|
31
|
-
:class="{ 'active-word': isWordActive(txtCue, word, wordIndex, index) && isTxtCueActive(txtCue) }"
|
|
31
|
+
:class="{ 'active-word': isWordActive(txtCue, word, wordIndex, index, currentCue) && isTxtCueActive(txtCue) }"
|
|
32
32
|
>
|
|
33
33
|
{{ word }}
|
|
34
34
|
</span>
|
|
@@ -141,9 +141,9 @@ const currentCue = ref(null);
|
|
|
141
141
|
|
|
142
142
|
const loadCues = async () => {
|
|
143
143
|
if (props.subtitle) {
|
|
144
|
+
console.log("load subtittles", props.subtitle.link)
|
|
144
145
|
const vttPath = props.subtitle.link;
|
|
145
146
|
const txtPath = vttPath.replace(/\.vtt$/, '.txt');
|
|
146
|
-
|
|
147
147
|
vttCues.value = await parseVTT(vttPath);
|
|
148
148
|
txtCues.value = await parseTXT(txtPath);
|
|
149
149
|
}
|
|
@@ -158,14 +158,14 @@ watch(
|
|
|
158
158
|
}
|
|
159
159
|
);
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
()
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
const onTimeUpdate = (video) => {
|
|
162
|
+
if (video) {
|
|
163
|
+
const currentTime = video.currentTime;
|
|
164
|
+
props.cursor = currentTime;
|
|
165
165
|
highlightActiveCue(currentTime);
|
|
166
|
-
checkCurrentCue(currentTime)
|
|
166
|
+
checkCurrentCue(currentTime);
|
|
167
167
|
}
|
|
168
|
-
|
|
168
|
+
};
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
171
|
* highlgiht the current transcript part
|
|
@@ -207,14 +207,12 @@ function isTxtCueActive(txtCue) {
|
|
|
207
207
|
* @param wordIndex
|
|
208
208
|
* @param txtIndex
|
|
209
209
|
*/
|
|
210
|
-
function isWordActive(txtCue, word, wordIndex, txtIndex) {
|
|
211
|
-
|
|
212
|
-
if(!currentCue.value || !word || !txtCue) {
|
|
210
|
+
function isWordActive(txtCue, word, wordIndex, txtIndex, currentCue) {
|
|
211
|
+
if(!currentCue || !word || !txtCue) {
|
|
213
212
|
return false
|
|
214
213
|
}
|
|
215
|
-
const startPos = txtCue.dialog[0].text.indexOf(currentCue
|
|
216
|
-
const endPos = startPos + currentCue.
|
|
217
|
-
console.log("can word marked", startPos, endPos, wordIndex)
|
|
214
|
+
const startPos = txtCue.dialog[0].text.indexOf(currentCue)
|
|
215
|
+
const endPos = startPos + currentCue.length
|
|
218
216
|
if(wordIndex >= startPos && wordIndex < endPos) {
|
|
219
217
|
return true;
|
|
220
218
|
}
|
|
@@ -223,7 +221,6 @@ function isWordActive(txtCue, word, wordIndex, txtIndex) {
|
|
|
223
221
|
|
|
224
222
|
function checkCurrentCue(currentCursor) {
|
|
225
223
|
Array.from(vttCues.value).forEach((a, index) => {
|
|
226
|
-
console.log("current cue", a)
|
|
227
224
|
if(currentCursor >= a.start && currentCursor <= a.end) {
|
|
228
225
|
currentCue.value = a.text
|
|
229
226
|
}
|
|
@@ -322,4 +319,6 @@ function secondsToTime(seconds) {
|
|
|
322
319
|
const pad = (num) => String(num).padStart(2, '0');
|
|
323
320
|
return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
|
|
324
321
|
}
|
|
322
|
+
|
|
323
|
+
defineExpose({ onTimeUpdate });
|
|
325
324
|
</script>
|