mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
fix(preview): sync audio start, ring animation, and download timeout (#423)
* fix(preview): sync audio start, ring animation, and download timeout Three coupled fixes for the track-preview engine: 1. Audio sync. `Sink::try_seek` was running on a worker thread after `sink.append(source)`, so the sink began playing position 0 while the seek was still iterating to the mid-track target. With the 30 s `take_duration` cap counting wall-clock from append, audio could only become audible ~25% into the preview window. The seek now runs on the bare source before append, then `take_duration` wraps it — playback starts at the seek position with the cap measured from there. 2. Ring animation gating. The CSS progress-ring animation was bound to `is-previewing` (set on click), so the ring sprinted ahead of any download/decode/seek warmup and didn't reset cleanly when switching from one preview to another. Added an `audioStarted` flag in `previewStore` that flips on `audio:preview-start` from the engine; CSS animation is now gated on `audio-started` instead. `is-previewing` still drives tooltip/icon for instant click feedback. Same SVG is reused for a 25%-arc rotating loading spinner while waiting for audio, with a 150 ms delay so cached/short previews don't flash. 3. Download timeout. The shared `audio_http_client` caps at 30 s, which aborts mid-download on multi-hundred-MB uncompressed files (e.g. 18-min Hi-Res WAV ~600 MB). The preview engine now builds a dedicated client with a 5 min timeout for the bytes fetch. Watchdog still bounds the playback window at 30 s once the audio actually starts. Touches `audio/preview.rs`, `previewStore.ts`, `components.css` plus the eight tracklist/player-bar components that render the preview button. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(changelog): add preview audio sync fix for PR #423 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
9cc74a7f88
commit
297c9f1125
@@ -40,6 +40,7 @@ export default function RandomMix() {
|
||||
const currentTrack = usePlayerStore(s => s.currentTrack);
|
||||
const isPlaying = usePlayerStore(s => s.isPlaying);
|
||||
const previewingId = usePreviewStore(s => s.previewingId);
|
||||
const previewAudioStarted = usePreviewStore(s => s.audioStarted);
|
||||
const starredOverrides = usePlayerStore(s => s.starredOverrides);
|
||||
const setStarredOverride = usePlayerStore(s => s.setStarredOverride);
|
||||
const [contextMenuSongId, setContextMenuSongId] = useState<string | null>(null);
|
||||
@@ -470,7 +471,7 @@ export default function RandomMix() {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`playlist-suggestion-preview-btn${previewingId === song.id ? ' is-previewing' : ''}`}
|
||||
className={`playlist-suggestion-preview-btn${previewingId === song.id ? ' is-previewing' : ''}${previewingId === song.id && previewAudioStarted ? ' audio-started' : ''}`}
|
||||
onClick={e => { e.stopPropagation(); usePreviewStore.getState().startPreview({ id: song.id, title: song.title, artist: song.artist, coverArt: song.coverArt, duration: song.duration }, 'randomMix'); }}
|
||||
data-tooltip={previewingId === song.id ? t('playlists.previewStop') : t('playlists.preview')}
|
||||
aria-label={previewingId === song.id ? t('playlists.previewStop') : t('playlists.preview')}
|
||||
@@ -603,7 +604,7 @@ export default function RandomMix() {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`playlist-suggestion-preview-btn${previewingId === song.id ? ' is-previewing' : ''}`}
|
||||
className={`playlist-suggestion-preview-btn${previewingId === song.id ? ' is-previewing' : ''}${previewingId === song.id && previewAudioStarted ? ' audio-started' : ''}`}
|
||||
onClick={e => { e.stopPropagation(); usePreviewStore.getState().startPreview({ id: song.id, title: song.title, artist: song.artist, coverArt: song.coverArt, duration: song.duration }, 'randomMix'); }}
|
||||
data-tooltip={previewingId === song.id ? t('playlists.previewStop') : t('playlists.preview')}
|
||||
aria-label={previewingId === song.id ? t('playlists.previewStop') : t('playlists.preview')}
|
||||
|
||||
Reference in New Issue
Block a user