fix: server-side elapsed tracking via frame count, periodic sync, playlist respects play mode

Progress/lyrics sync:
- AudioPlayer tracks framesPlayed (ground truth: frames * 20ms + seekOffset)
- BotStatus.elapsed is the real elapsed from server
- Frontend polls GET /elapsed every 3s for ground truth
- Client interpolates between syncs (serverElapsed + timeSinceSync)
- Pause freezes at interpolated value, resume resyncs from server
- No more client-side timestamp drift

Playlist play all:
- Stops current playback before loading
- Respects play mode: random/rloop picks random first song, seq plays first

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
saopig1andClaude Opus 4.6 committed 2026-03-30 03:27:16 +08:00
1 parent 1cdface33c
commit 0439bd047f
6 files changed
+131 -109

No files matched your search

+9 -1
View File
@@ -9,7 +9,7 @@
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue';
import { computed, onMounted, onUnmounted } from 'vue';
import { usePlayerStore } from './stores/player.js';
import { useWebSocket } from './composables/useWebSocket.js';
import Navbar from './components/Navbar.vue';
@@ -19,10 +19,18 @@ const playerStore = usePlayerStore();
const theme = computed(() => playerStore.theme);
const { connect } = useWebSocket();
let syncTimer: ReturnType<typeof setInterval> | null = null;
onMounted(() => {
playerStore.loadTheme();
connect();
playerStore.fetchBots();
// Periodically sync elapsed time from server (ground truth)
syncTimer = setInterval(() => playerStore.syncElapsed(), 3000);
});
onUnmounted(() => {
if (syncTimer) clearInterval(syncTimer);
});
</script>