fix: autoplay video instantly on watch page load
This commit is contained in:
@@ -209,7 +209,7 @@ export const setupControls = (): void => {
|
|||||||
// mouse move in container shows controls
|
// mouse move in container shows controls
|
||||||
state.container.addEventListener('mousemove', showControls);
|
state.container.addEventListener('mousemove', showControls);
|
||||||
|
|
||||||
// initial sync
|
// initial sync — check actual video state since inline script may have started playback
|
||||||
updatePlayPauseIcons(false);
|
updatePlayPauseIcons(!state.video.paused);
|
||||||
syncVolumeUI();
|
syncVolumeUI();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -66,9 +66,10 @@ const initPlayer = (): void => {
|
|||||||
const progressWrap = container.querySelector('[data-progress-wrap]') as HTMLElement | null;
|
const progressWrap = container.querySelector('[data-progress-wrap]') as HTMLElement | null;
|
||||||
|
|
||||||
// build video src from mode, token, and saved quality preference
|
// build video src from mode, token, and saved quality preference
|
||||||
|
// Only set if not already provided by the inline script during HTML parsing
|
||||||
const preferredQuality = localStorage.getItem('mal:preferred-quality') || 'best';
|
const preferredQuality = localStorage.getItem('mal:preferred-quality') || 'best';
|
||||||
const streamToken = state.modeSources[state.currentMode]?.token;
|
const streamToken = state.modeSources[state.currentMode]?.token;
|
||||||
if (streamToken) {
|
if (!state.video.src && streamToken) {
|
||||||
state.video.src = `${state.streamURL}?mode=${encodeURIComponent(state.currentMode)}&token=${encodeURIComponent(streamToken)}${preferredQuality !== 'best' ? `&quality=${encodeURIComponent(preferredQuality)}` : ''}`;
|
state.video.src = `${state.streamURL}?mode=${encodeURIComponent(state.currentMode)}&token=${encodeURIComponent(streamToken)}${preferredQuality !== 'best' ? `&quality=${encodeURIComponent(preferredQuality)}` : ''}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ const initPlayer = (): void => {
|
|||||||
updateAutoSkipButton();
|
updateAutoSkipButton();
|
||||||
showControls();
|
showControls();
|
||||||
|
|
||||||
state.video.addEventListener('loadedmetadata', () => {
|
const onLoadedMetadata = (): void => {
|
||||||
loading && (loading.style.display = 'none');
|
loading && (loading.style.display = 'none');
|
||||||
invalidateBounds();
|
invalidateBounds();
|
||||||
|
|
||||||
@@ -104,11 +105,19 @@ const initPlayer = (): void => {
|
|||||||
state.video.currentTime = state.pendingSeekTime;
|
state.video.currentTime = state.pendingSeekTime;
|
||||||
state.pendingSeekTime = null;
|
state.pendingSeekTime = null;
|
||||||
}
|
}
|
||||||
if (state.shouldAutoPlay) state.video.play().catch(() => {});
|
// autoplay if not already playing (inline script may have already called play())
|
||||||
|
if (state.shouldAutoPlay || state.video.paused) state.video.play().catch(() => {});
|
||||||
|
|
||||||
updateTimeline(state.video.currentTime);
|
updateTimeline(state.video.currentTime);
|
||||||
updateSkipButton(state.video.currentTime);
|
updateSkipButton(state.video.currentTime);
|
||||||
});
|
};
|
||||||
|
|
||||||
|
state.video.addEventListener('loadedmetadata', onLoadedMetadata);
|
||||||
|
// inline script runs during HTML parsing before initPlayer; if metadata
|
||||||
|
// already loaded, fire the handler immediately
|
||||||
|
if (state.video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
|
||||||
|
onLoadedMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
state.video.addEventListener('waiting', () => {
|
state.video.addEventListener('waiting', () => {
|
||||||
loading && (loading.style.display = 'flex');
|
loading && (loading.style.display = 'flex');
|
||||||
|
|||||||
@@ -14,7 +14,27 @@
|
|||||||
class="group relative aspect-video w-full overflow-hidden bg-black">
|
class="group relative aspect-video w-full overflow-hidden bg-black">
|
||||||
|
|
||||||
|
|
||||||
<video class="h-full w-full cursor-pointer" preload="metadata" playsinline autoplay></video>
|
<video class="h-full w-full cursor-pointer" preload="metadata" playsinline></video>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var p = document.currentScript.closest('[data-video-player]');
|
||||||
|
var v = p.querySelector('video');
|
||||||
|
var sources = JSON.parse(p.getAttribute('data-mode-sources') || '{}');
|
||||||
|
var mode = p.getAttribute('data-initial-mode') || 'dub';
|
||||||
|
var stored = localStorage.getItem('player-audio-mode');
|
||||||
|
if (stored && sources[stored] && sources[stored].token) mode = stored;
|
||||||
|
var src = sources[mode];
|
||||||
|
if (!src || !src.token) {
|
||||||
|
for (var k in sources) {
|
||||||
|
if (sources[k] && sources[k].token) { src = sources[k]; mode = k; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (src && src.token) {
|
||||||
|
v.src = '/watch/proxy/stream?mode=' + encodeURIComponent(mode) + '&token=' + encodeURIComponent(src.token);
|
||||||
|
v.play().catch(function() {});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
<div data-loading class="absolute inset-0 flex items-center justify-center bg-black/60 hidden z-50">
|
<div data-loading class="absolute inset-0 flex items-center justify-center bg-black/60 hidden z-50">
|
||||||
<div class="border-accent size-10 animate-spin rounded-full border-4 border-t-transparent"></div>
|
<div class="border-accent size-10 animate-spin rounded-full border-4 border-t-transparent"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user