The mp32 audioformat is not reliably provisioned for the streaming
audio URL — Jamendo returns an empty audio field for many tracks — so
mp32 as the default made playback fail with track is not streamable
even though metadata resolved. Default to mp31 (the freely streamable
MP3), and have track_stream retry without a forced format when the
configured one yields no audio, so a Pro-only format degrades to a
playable stream instead of skipping the track. Live-verified: default
config resolves a stream URL, and an explicit mp32 now falls back.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jamendo API v3.0 answers HTTP 200 success with an empty result set to
any request that carries no User-Agent header. reqwest sends none by
default, so every search/detail/stream call came back empty and tracks
would not resolve or play (jamendo resource not found). Set a UA on the
JamApi client, like the SoundCloud provider does. Live-verified against
the API: search, track detail, and stream-URL resolution all return data
with the header present.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New jamendody crate implementing ProviderClient, mounted at /jamendo:
search the Jamendo catalogue and play tracks, browse an album a track
belongs to, with captures/downloads for free.
Unlike the SoundCloud provider this is the simple case — Jamendo has a
stable official API (api.jamendo.com/v3.0), so there is no client_id
scraping, no OAuth, and no HLS: a track streams via its direct audio MP3
URL on the existing windowed-HTTP path, and duration is already in
seconds (matching Track.duration). A registered client_id in jamendo.toml
is required; missing it disables /jamendo only, non-fatally.
Ran the full dev-flow pipeline; artifacts under architecture/, quality/,
and plan/. 16 jamendody unit tests over a faked Jam network seam; server
wired with the standard owns/provider/build/dispatch pattern and a
jamendo toggle in ALL_PROVIDERS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>