mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
5aac4d4ed0
Reworks the manual streaming-start path so playback is seekable from the first frame and hot-cache hits start without a multi-hundred-MB pre-read. Why - The legacy AudioStreamReader was a non-seekable ring buffer. Forward seeks during streaming let Symphonia consume the buffer through to EOF (next song), and backward seeks were silently broken. - fetch_data() loaded `psysonic-local://` files via tokio::fs::read, blocking playback for seconds on hot-cache or offline files (e.g. a 100+ MB hi-res FLAC) and producing ALSA underruns when the new sink swap arrived too late. What changed - New RangedHttpSource MediaSource: pre-allocates a Vec<u8> in track size, background ranged_download_task fills linearly from offset 0 with HTTP Range reconnects. is_seekable=true; reads block on data, seeks update the cursor only. Picked when the server response carries Accept-Ranges: bytes + Content-Length. - New LocalFileSource MediaSource: thin std::fs::File wrapper used for every `psysonic-local://` URL — Symphonia probes the first ~64 KB and starts playback before the rest is read. - audio_play wires both paths through a generic PlayInput::SeekableMedia variant so the build_streaming_source pipeline stays single-shape. - current_is_seekable AtomicBool on AudioEngine: audio_seek short-circuits with `not seekable` for the legacy fallback so the frontend restart- fallback (playerStore seek catch) engages instead of letting a forward seek consume the ring buffer. - Dev-only [stream] / [seek] eprintln logs (cfg(debug_assertions)) so source selection, codec resolution (codec name + lossless flag + bit depth + rate + channels), download progress and seek targets are visible in the terminal during testing. - content_type_to_hint now covers wav/wave/opus; URL-derived format hints strip the query string first and only accept known audio extensions (Subsonic stream URLs have no extension — would otherwise latch onto query-param fragments). Compatibility - Servers without Accept-Ranges fall back to the existing AudioStreamReader path; seek is rejected up-front so the existing restart-fallback runs. - Radio + audio_chain_preload paths untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>