@grfzhl/vue-hls-player 1.1.24 → 1.1.25
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 +4 -0
- package/dist/VideoPlayer/BasePlayer.vue +41 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -207,6 +207,10 @@ At the moment the following attribute are supported:
|
|
|
207
207
|
```
|
|
208
208
|
|
|
209
209
|
### Last release:
|
|
210
|
+
v1.1.25
|
|
211
|
+
- Decouple audio language switching from subtitle selection.
|
|
212
|
+
- Preserve user-selected subtitle language across audio changes and HLS source reloads.
|
|
213
|
+
- Prevent unintended subtitle resets caused by audio language updates.
|
|
210
214
|
v1.1.24
|
|
211
215
|
- Add user-initiated language-changed emit.
|
|
212
216
|
- Fix unwanted language re-sync on player init.
|
|
@@ -185,35 +185,50 @@ let currentTime = 0
|
|
|
185
185
|
let hls = null
|
|
186
186
|
let buttonElement = null
|
|
187
187
|
// --- lang switcher ---
|
|
188
|
-
const
|
|
188
|
+
const currentAudioLang = ref(props.defaultLang || 'en')
|
|
189
|
+
|
|
190
|
+
const sessionSubtitleLang = 'vp_subtitle_lang'
|
|
191
|
+
function initSubtitleLang() {
|
|
192
|
+
const stored = sessionStorage.getItem(sessionSubtitleLang)
|
|
193
|
+
|
|
194
|
+
if (stored && props.subtitles.some(s => s.lang === stored)) {
|
|
195
|
+
currentSubtitleLang.value = stored
|
|
196
|
+
} else {
|
|
197
|
+
currentSubtitleLang.value =
|
|
198
|
+
props.subtitles.find(s => s.lang === props.defaultLang)?.lang
|
|
199
|
+
|| props.subtitles[0]?.lang
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
applySubtitleTrack(currentSubtitleLang.value)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function applySubtitleTrack(lang) {
|
|
206
|
+
Array.from(video.value?.textTracks || []).forEach(track => {
|
|
207
|
+
const tLang = (track.language || track.srclang || '').toLowerCase()
|
|
208
|
+
track.mode = tLang === lang.toLowerCase() ? 'showing' : 'disabled'
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
189
214
|
const isUserInitiatedLangChange = ref(false)
|
|
190
215
|
|
|
191
216
|
let initialLoad = true;
|
|
217
|
+
let defaultApplied = false
|
|
192
218
|
|
|
193
219
|
watch(
|
|
194
220
|
() => props.defaultLang,
|
|
195
|
-
(
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (newLang && newLang !== oldLang && newLang !== currentLang.value) {
|
|
202
|
-
const hasSub = props.subtitles?.find(s => s.lang === newLang);
|
|
203
|
-
if (hasSub) {
|
|
204
|
-
currentSubtitleLang.value = newLang;
|
|
205
|
-
Array.from(video.value?.textTracks || []).forEach(track => {
|
|
206
|
-
const tLang = (track.language || track.srclang || '').toLowerCase();
|
|
207
|
-
track.mode = tLang === newLang.toLowerCase() ? 'showing' : 'disabled';
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
}
|
|
221
|
+
(lang) => {
|
|
222
|
+
if (defaultApplied) return
|
|
223
|
+
currentAudioLang.value = lang
|
|
224
|
+
defaultApplied = true
|
|
211
225
|
}
|
|
212
226
|
)
|
|
227
|
+
|
|
213
228
|
// --- Remember and restore last subtitle language ---
|
|
214
229
|
async function selectLang(lang) {
|
|
215
230
|
if (!video.value || !hls) return;
|
|
216
|
-
if (lang ===
|
|
231
|
+
if (lang === currentAudioLang.value) return;
|
|
217
232
|
|
|
218
233
|
const newSource = props.multiLangSources?.find(s => s.lang === lang);
|
|
219
234
|
if (!newSource?.file_url) {
|
|
@@ -227,7 +242,7 @@ async function selectLang(lang) {
|
|
|
227
242
|
const wasMuted = video.value.muted;
|
|
228
243
|
const rate = video.value.playbackRate;
|
|
229
244
|
|
|
230
|
-
|
|
245
|
+
currentAudioLang.value = lang;
|
|
231
246
|
// Switching to ${lang}...
|
|
232
247
|
|
|
233
248
|
try {
|
|
@@ -284,7 +299,7 @@ function updateLangMenuState() {
|
|
|
284
299
|
const langElement = li.querySelector('span[data-lang]')
|
|
285
300
|
const liLang = langElement?.dataset?.lang;
|
|
286
301
|
// const liLang = li.textContent.trim().toLowerCase();
|
|
287
|
-
li.classList.toggle('active', liLang ===
|
|
302
|
+
li.classList.toggle('active', liLang === currentAudioLang.value.toLowerCase());
|
|
288
303
|
});
|
|
289
304
|
|
|
290
305
|
// --- Subtitles ---
|
|
@@ -589,14 +604,7 @@ function prepareVideoPlayer(link) {
|
|
|
589
604
|
|
|
590
605
|
// Initialize subtitles
|
|
591
606
|
if (props.subtitles?.length > 0) {
|
|
592
|
-
|
|
593
|
-
currentSubtitleLang.value = defaultSub ? props.defaultLang : props.subtitles[0].lang;
|
|
594
|
-
Array.from(video.value?.textTracks || []).forEach(track => {
|
|
595
|
-
const tLang = (track.language || track.srclang || '').toLowerCase();
|
|
596
|
-
const shouldShow = tLang === currentSubtitleLang.value.toLowerCase();
|
|
597
|
-
track.mode = shouldShow ? 'showing' : 'disabled';
|
|
598
|
-
// console.log('[SubtitleInit] Track found:', tLang, '->', shouldShow ? 'showing' : 'disabled');
|
|
599
|
-
});
|
|
607
|
+
initSubtitleLang();
|
|
600
608
|
}
|
|
601
609
|
|
|
602
610
|
selectLang(props.defaultLang);
|
|
@@ -875,7 +883,7 @@ const mutationObserver = (mutationsList, observer) => {
|
|
|
875
883
|
<span data-lang="${ src.lang }">${src.label || src.lang.toUpperCase()}</span>
|
|
876
884
|
<span class="icon">${renderIcon()}</span>
|
|
877
885
|
`;
|
|
878
|
-
if (src.lang ===
|
|
886
|
+
if (src.lang === currentAudioLang.value) li.classList.add('active');
|
|
879
887
|
li.addEventListener('click', () => {
|
|
880
888
|
audioCol.querySelectorAll('li').forEach(el => el.classList.remove('active'));
|
|
881
889
|
li.classList.add('active');
|
|
@@ -894,14 +902,10 @@ const mutationObserver = (mutationsList, observer) => {
|
|
|
894
902
|
|
|
895
903
|
if (sub.lang === currentSubtitleLang.value) li.classList.add('active');
|
|
896
904
|
li.addEventListener('click', () => {
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
subCol.querySelectorAll('li').forEach(el => el.classList.remove('active'));
|
|
902
|
-
li.classList.add('active');
|
|
903
|
-
menu.style.display = 'none';
|
|
904
|
-
currentSubtitleLang.value = sub.lang;
|
|
905
|
+
currentSubtitleLang.value = sub.lang
|
|
906
|
+
sessionStorage.setItem(sessionSubtitleLang, sub.lang)
|
|
907
|
+
applySubtitleTrack(sub.lang)
|
|
908
|
+
menu.style.display = 'none'
|
|
905
909
|
});
|
|
906
910
|
subCol.appendChild(li);
|
|
907
911
|
});
|