The fallback playlist probed every file in /cache, including .gitkeep and
in-progress .part downloads, logging ffmpeg "Invalid data" warnings at startup.
Filter candidates with check_next to keep only real audio files and skip hidden
ones, removing the noise.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Insert a 3s crossfade after the fallback so it applies to both
daemon-driven transitions and cache fallbacks, before mksafe.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the Python `ingest` container exposing `GET /next`, which returns the
next track as an annotated Liquidsoap URI (or an empty body when nothing is
ready). Liquidsoap switches from a static playlist to a `request.dynamic`
source pulling from the daemon, with the local cache as fallback and mksafe
for guaranteed continuous output.
For now the daemon just cycles through the files already in the cache; the
download providers (Navidrome, yt-dlp, ListenBrainz) come in later milestones.
Also commit the implementation plan (PLAN.md).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Liquidsoap (v2.4.5) container that plays the /cache directory in random
order and broadcasts it over HTTP at :8000/radio.mp3 (MP3 192 kbps).
mksafe guarantees a continuous stream (silence when the cache is empty).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>