fixes lol
Some checks failed
Build and Push / build-all (push) Failing after 2m22s

This commit is contained in:
doomtube 2026-01-09 21:27:30 -05:00
parent 6bbfc671b3
commit 2e376269c2
28 changed files with 389 additions and 332 deletions

View file

@ -19,11 +19,16 @@
let currentPlaylistItemId = null; // Track playlist item ID to detect changes even with same video
let durationReportedForItemId = null; // Track which playlist item we've reported duration for
let lastControllerSeekTime = 0; // Debounce controller seek updates
let lastSeekTime = 0; // Track last seek time for rate-limiting
let leadInEndedAt = 0; // Track when lead-in ended for grace period
let wasInLeadIn = false; // Track previous lead-in state
const SYNC_CHECK_INTERVAL = 1000; // Check sync every second (matches server sync interval)
const DRIFT_THRESHOLD = 2; // Seek if drift > 2 seconds (CyTube-style tight sync)
const MIN_SYNC_INTERVAL = 1000; // Minimum 1 second between sync checks (server pushes every 1s)
const CONTROLLER_SEEK_DEBOUNCE = 2000; // Debounce controller seeks by 2 seconds
const SEEK_RATE_LIMIT = 2000; // Minimum 2 seconds between seeks
const POST_LEAD_IN_GRACE = 500; // 500ms grace period after lead-in ends
// Load YouTube IFrame API
function loadYouTubeAPI() {
@ -171,16 +176,28 @@
// During lead-in period, let video buffer without seeking
// Server sends leadIn=true for 3 seconds after play starts
if (storeState.leadIn) {
wasInLeadIn = true;
// During lead-in, just ensure video is loading/buffering
// Don't seek or sync position - wait for lead-in to complete
if (shouldBePlaying && !isPlayerPlaying && !isBuffering && !hasVideoEnded) {
ignoreStateChange = true;
player.playVideo();
setTimeout(() => { ignoreStateChange = false; }, 500);
setTimeout(() => { ignoreStateChange = false; }, 1500);
}
return;
}
// Track when lead-in ends for grace period
if (wasInLeadIn && !storeState.leadIn) {
wasInLeadIn = false;
leadInEndedAt = now;
}
// Apply grace period after lead-in ends - don't seek immediately
if (leadInEndedAt > 0 && (now - leadInEndedAt) < POST_LEAD_IN_GRACE) {
return;
}
const expectedTime = watchSync.getExpectedTime();
const currentTime = player.getCurrentTime();
const drift = Math.abs(currentTime - expectedTime);
@ -205,10 +222,15 @@
}
} else {
// Non-controller - sync back to server time
// Rate-limit seeks to prevent stuttering from consecutive seeks
if (now - lastSeekTime < SEEK_RATE_LIMIT) {
return; // Skip this seek, wait for rate limit
}
console.log(`Sync drift detected: ${drift.toFixed(2)}s, seeking to ${expectedTime.toFixed(2)}s`);
ignoreStateChange = true;
player.seekTo(expectedTime, true);
setTimeout(() => { ignoreStateChange = false; }, 500);
lastSeekTime = now;
setTimeout(() => { ignoreStateChange = false; }, 1500);
}
}
@ -217,11 +239,11 @@
if (shouldBePlaying && !isPlayerPlaying && !isBuffering && !hasVideoEnded) {
ignoreStateChange = true;
player.playVideo();
setTimeout(() => { ignoreStateChange = false; }, 500);
setTimeout(() => { ignoreStateChange = false; }, 1500);
} else if (!shouldBePlaying && isPlayerPlaying) {
ignoreStateChange = true;
player.pauseVideo();
setTimeout(() => { ignoreStateChange = false; }, 500);
setTimeout(() => { ignoreStateChange = false; }, 1500);
}
}
@ -245,11 +267,9 @@
}
}
// React to state changes from the store
$: if (playerReady && player && $watchSync.serverTime > lastSyncTime) {
lastSyncTime = $watchSync.serverTime;
checkAndSync();
}
// Note: Sync is handled by the interval at onPlayerReady (line 99)
// We don't trigger sync on every serverTime update to avoid double-syncing
// which causes stuttering. The interval runs every 1 second which is sufficient.
// Handle window event for state changes from other users
function handleStateChange(event) {
@ -270,6 +290,11 @@
} else if (action === 'skip' || action === 'video_changed') {
// Video change will be handled by the reactive statement above
setTimeout(() => checkAndSync(true), 1000);
} else if (action === 'locked_restart' || action === 'repeat') {
// Locked video loop - seek to beginning and play
player.seekTo(0, true);
player.playVideo();
setTimeout(() => checkAndSync(true), 1000);
}
setTimeout(() => { ignoreStateChange = false; }, 1000);
@ -280,7 +305,7 @@
if (playerReady && player) {
ignoreStateChange = true;
player.seekTo(time, true);
setTimeout(() => { ignoreStateChange = false; }, 500);
setTimeout(() => { ignoreStateChange = false; }, 1500);
}
}