fixes lol
All checks were successful
Build and Push / build-all (push) Successful in 1m48s

This commit is contained in:
doomtube 2026-01-10 03:00:41 -05:00
parent 33624d3b02
commit 896a3b77d7
5 changed files with 293 additions and 85 deletions

View file

@ -22,8 +22,11 @@
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
let restartInProgress = false; // Track when video restart is in progress (prevents drift detection)
let restartStartedAt = 0; // When restart started
const SYNC_CHECK_INTERVAL = 1000; // Check sync every second (matches server sync interval)
const RESTART_GRACE_PERIOD = 3000; // 3 seconds grace period during video restart
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
@ -122,6 +125,9 @@
// YT.PlayerState: UNSTARTED (-1), ENDED (0), PLAYING (1), PAUSED (2), BUFFERING (3), CUED (5)
// Always handle ENDED state - crucial for playlist advancement
if (state === window.YT.PlayerState.ENDED) {
// Set restart flag to prevent drift detection during transition
restartInProgress = true;
restartStartedAt = Date.now();
dispatch('ended');
// Also notify server directly - this is a fallback for when duration-based detection fails
watchSync.videoEnded();
@ -187,10 +193,29 @@
const shouldBePlaying = storeState.playbackState === 'playing';
const hasVideoEnded = playerState === window.YT.PlayerState.ENDED;
// During restart transition (video ended, waiting for server response), skip drift detection
// This prevents false "Controller seek detected" when video loops/restarts
if (restartInProgress) {
if (now - restartStartedAt >= RESTART_GRACE_PERIOD) {
// Grace period expired, reset flag
restartInProgress = false;
} else {
// Still in grace period - only ensure video starts playing if needed, no sync
if (shouldBePlaying && !isPlayerPlaying && !isBuffering && !hasVideoEnded) {
ignoreStateChange = true;
player.playVideo();
setTimeout(() => { ignoreStateChange = false; }, 1500);
}
return;
}
}
// During lead-in period, let video buffer without seeking
// Server sends leadIn=true for 3 seconds after play starts
if (storeState.leadIn) {
wasInLeadIn = true;
// Lead-in started, clear restart flag since server has responded
restartInProgress = false;
// 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) {
@ -266,6 +291,7 @@
$: if (playerReady && $watchSync.currentVideo?.id !== currentPlaylistItemId) {
currentPlaylistItemId = $watchSync.currentVideo?.id;
durationReportedForItemId = null; // Reset so we report duration for new video
restartInProgress = false; // Video changed, clear restart flag
const newVideoId = $watchSync.currentVideo?.youtubeVideoId;
if (newVideoId && player) {
videoId = newVideoId;
@ -302,13 +328,18 @@
} else if (action === 'seek' && currentTime !== undefined) {
player.seekTo(currentTime, true);
} else if (action === 'skip' || action === 'video_changed') {
// Server has responded, clear restart flag
restartInProgress = false;
// Video change will be handled by the reactive statement above
setTimeout(() => checkAndSync(true), 1000);
} else if (action === 'locked_restart' || action === 'repeat') {
// Server has responded with restart, clear the restart flag
restartInProgress = false;
// Locked video loop - seek to beginning and play
player.seekTo(0, true);
player.playVideo();
setTimeout(() => checkAndSync(true), 1000);
// Delay sync check longer to allow player to stabilize
setTimeout(() => checkAndSync(true), 2000);
}
setTimeout(() => { ignoreStateChange = false; }, 1000);