Monochrome's search kept answering while every download trickled in at
12 KB/s and got cut off 38 seconds in, so the health check (a search)
waved it through and every track wasted half a minute there first. The
probe now pulls the first megabyte of a real FLAC against a wall clock.
The workers also announced their own failures before the fallback cycle
had fetched the track from somewhere else, so "FAILED" pings went out for
songs already sitting in the library. Failures inside a cycle are held;
one notice goes out if every source genuinely lets you down.
Built with a human and a grumpy-AI combo, both unimpressed by 12 KB/s.
India's biggest streaming service, asked directly through the api.php its
own web player uses. Most tracks are 320 kbps AAC (saved as .m4a), some
160, and results declare which, so the quality filter and upgrade scanner
know what they're getting. Stream links arrive DES-encrypted with a key
that has been public for years, hence pycryptodome in the image.
Found via Hayasaka, which reaches the same catalogue through someone's
proxy; we skip the middleman so there is nothing to vanish. Catch:
JioSaavn filters search by IP, so outside India the Western catalogue has
holes. The Indian catalogue, which the other sources are thin on, is the
point.
Wired in wherever its siblings live: registry, download routing (.m4a
staging), health probe, URL allowlist, quality tiers, provenance, settings
toggle (on by default), and the frontend badge, stats, quips and preview.
Assembled by one human and one AI who now know far too much about DES.
- MP3Phoenix retired again: source, toggle, preview snippets, curl_cffi.
DB migration v20 removes its setting and the Monochrome hifi-api URL.
- Monochrome search tops up a thin Deezer page from the tracks API.
- /api/download refuses unknown sources rather than misrouting them to
YouTube and failing on a "truncated YouTube ID".
- Deno 2.9.5 -> 2.9.7.
- Live tests draw downloads from a shuffled pool of short clips and
searches from ten songs (tests/live_media.py), instead of fetching
"Me at the zoo" a dozen times a run. Fast tests wait for their download
before deleting it, so nothing is left in the library.
- The MusicBrainz routing tests never routed anything: 186 of 195 Thriller
jobs were dupe hits. They now use Blitzkrieg Bop, and a dupe hit fails
loudly. Doing so exposed playlist album routing not happening; logged.
Built by a human and an AI who now know more about Keyboard Cat's
discography than either of them wanted to.
qbdlx's shared Qobuz token host stopped answering entirely, so every
lookup through it was a long, patient wait for nothing. Removed: the
download fallback, the Qobuz search fallback, the settings toggle (DB
migration v19 tidies it away) and the QBDLX_* knobs. Parked at tag
archive/qbdlx.
Its quieter job was confirming Monochrome search results could actually
be downloaded. With it dead, everything had gone "unverified" and Bulk
Import's exact-ISRC match had stopped matching anything at all. That
check now asks the tracks API, by artist, title and ISRC, so search only
offers what Monochrome can deliver (karaoke and lullaby covers it does
not stock quietly fall away) and exact matches work again. When Deezer
comes back empty, the tracks API is searched directly instead.
Qobuz no longer appears in settings, search copy or the README, having
left the building some time ago without telling anyone.
Built with a human and a grumpy-AI combo, with a moment's silence for the token pool.
Use Selenium only for Cloudflare clearance, then hand search and downloads to curl_cffi with bounded refresh and fallback handling. Add container child reaping, source controls, tests, and Rise of the Phoenix documentation.\n\nBuilt with a human and a grumpy-AI combo.
Add adaptive source balancing, persistent health, targeted retries, automated search caching, source journeys, bounded provider calls, and the shared lossless Monochrome preview resolver. Built with a human and a grumpy-AI combo.
Health probes no longer hold every search hostage (async, parallel, and
deduplicated, with the proxy sweep done in parallel too); the Monochrome
download ladder gives up on dead proxies in about a minute instead of a
quarter of an hour (failure marks honoured, timeouts park on first offence,
tier walk bails when nobody answers); jobs carry a progress heartbeat so the
stale reaper only takes the actually-dead; three search timeouts bench a
limping source before it can tax a whole bulk import; and Soulseek results
stop changing their name every search, so blacklists finally stick.
Built with a human and a grumpy-AI combo, fuelled by tea and a deep
resentment of 30-second spinners.
MP3Phoenix is gone (mp3phoenix.py deleted) after Cloudflare bricked its
downloads for good; strips out its wiring across search, downloads,
settings, quips, the UI and the tests, plus assorted dead-weight cleanup.
zvu4no and FreeMp3Cloud domain fixes carried in from the last round.
Release notes and CHANGELOG populated for v3.0.1.
Built with a human and a suitably grumpy AI, MP3Phoenix mourned by no one.
A sixth web source joins the lossy-MP3 fallback ranks: g2.freemp3cloud.com,
backed by the meln.top CDN. Server-rendered ASP.NET, so search is a landing-page
token harvest followed by a form POST; the download URL carries its own
session_key + hash so it streams fine later from the download thread.
The trick is that the site labels its good results "HQ", and those genuinely are
320 kbps (verified by download, some even ship cover art) while the un-tagged ones
are a sad 128 kbps. So we read the tag: HQ scores at the MP3Phoenix 320 tier,
the rest get demoted to only ever win when nothing better exists. Lossless still
always wins, as it should.
Wired in everywhere its siblings live: SOURCE_REGISTRY + per-source cap, settings
toggle (on by default), Pydantic model, download routing, health check, the
upgrade scanner's quality tiering, preview/URL source sets, and the frontend
badge/label/stats/settings. Smoke test now asserts the source is registered.
built with a human and a grumpy-AI combo
Sources that fall over now get parked instead of clogging search with dead
results. New servicecheck.py probes each source with the cheapest check that
proves it can actually deliver (Monochrome gated on its flaky Qobuz download
leg, not just the search API), hides parked sources for a configurable
cooldown, and tells the UI which ones got skipped. Cross-source fallback is
now a proper toggle, and watched playlists that vanish upstream get
auto-paused with a note after three strikes rather than failing forever.
Release chores: VERSION 2.9.0, CHANGELOG dated 2026-05-30, README and
release-notes updated. Fast test suite green (143 passed, 3 skipped).
built with a human and a grumpy-AI combo