mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-01 20:42:50 +08:00
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:
1 parent
1cdface33c
commit
0439bd047f
6 files changed
+131
-109
No files matched your search
@@ -74,7 +74,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, onMounted, onUnmounted } from 'vue';
|
||||
import { Icon } from '@iconify/vue';
|
||||
import axios from 'axios';
|
||||
import { usePlayerStore } from '../stores/player.js';
|
||||
import CoverArt from './CoverArt.vue';
|
||||
import Queue from './Queue.vue';
|
||||
@@ -102,13 +101,8 @@ function formatTime(seconds: number): string {
|
||||
}
|
||||
|
||||
function updateProgress() {
|
||||
const bot = store.activeBot;
|
||||
const seekOff = store.seekOffset;
|
||||
if (bot?.playing && !bot.paused && store.playStartedAt > 0) {
|
||||
currentElapsed.value = seekOff + (Date.now() - store.playStartedAt) / 1000;
|
||||
} else if (bot?.paused) {
|
||||
currentElapsed.value = store.pausedElapsed;
|
||||
}
|
||||
// Use store.elapsed which interpolates from server ground truth
|
||||
currentElapsed.value = store.elapsed;
|
||||
|
||||
const duration = currentSong.value?.duration ?? 0;
|
||||
progressPercent.value = duration > 0
|
||||
@@ -120,20 +114,12 @@ function updateProgress() {
|
||||
|
||||
async function onProgressClick(e: MouseEvent) {
|
||||
const bar = progressBarRef.value;
|
||||
if (!bar || !store.activeBotId) return;
|
||||
if (!bar) return;
|
||||
const rect = bar.getBoundingClientRect();
|
||||
const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
||||
const duration = currentSong.value?.duration ?? 0;
|
||||
const seekTime = ratio * duration;
|
||||
|
||||
try {
|
||||
await axios.post(`/api/player/${store.activeBotId}/seek`, { position: seekTime });
|
||||
store.seekOffset = seekTime;
|
||||
store.playStartedAt = Date.now();
|
||||
store.pausedElapsed = 0;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
await store.seek(seekTime);
|
||||
}
|
||||
|
||||
function onProgressHover(e: MouseEvent) {
|
||||
|
||||
Reference in new issue
Block a user