github rawnaldclark/Stash v0.9.10
Stash v0.9.10

latest releases: v0.9.94, v0.9.93, v0.9.92...
3 months ago

feat: 0.9.10 — Tidal/Qobuz fallback via qobuz.kennyy.com.br + perf wins

Adds qobuz.kennyy.com.br as a second LosslessSource alongside
qobuz.squid.wtf. When squid is down (captcha-required 403s, operator
account issues, etc.), the registry now falls over to a different
operator's Qobuz proxy automatically — both deliver lossless FLAC.

The original v0.9.10 design (committed as MonochromeSource hitting
api.monochrome.tf) was based on a wrong assumption: Tidal's API
returns Widevine-encrypted DASH for all tracks, and account-banning
across the squid.wtf/hifi-api ecosystem made the Tidal-side path
non-functional. After probing Monochrome's web UI flow, we
discovered Monochrome internally routes downloads through Qobuz
proxies via ISRC lookup. The user's configured Qobuz instance is
qobuz.kennyy.com.br — a near-clone of qobuz.squid.wtf's Qobuz-DL
codebase running under a different operator with NO captcha gate.

This release:

  • KennyyApiClient: HTTP client for qobuz.kennyy.com.br. Same
    /api/get-music + /api/download-music endpoints as squid.wtf,
    same {success, data} response envelope. No captcha interceptor
    (this instance is unauthenticated).
  • KennyySource: implements LosslessSource. id="kennyy_qobuz".
    Reuses QobuzModels (identical JSON shape across Qobuz-DL
    deployments) and QobuzSource's scoring helpers.
  • KennyyModule: Hilt @IntoSet binding.
  • LosslessSourcePreferences.DEFAULT_PRIORITY = [squid_qobuz,
    kennyy_qobuz] for fresh installs. Existing users with explicit
    priority preserved.

Performance optimizations (~3x speedup vs original baseline):

  • QobuzSource: track lastKnownBadCookie. isEnabled() returns false
    when (a) circuit-broken, (b) cookie blank, (c) cookie matches the
    last value that returned a captcha-required 403. Implicit reset
    when user pastes a fresh cookie. Saves ~16s/track for users
    with squid down or no captcha set.
  • AggregatorRateLimiter: kennyy_qobuz pre-configured to 1 token /
    3 seconds, burst 4 (3x default). Auto-backoff: if a source hits
    5+ 429s in 60 seconds, halve its tokensPerSecond (floor 1/min).
    Self-tunes toward operator's actual threshold instead of
    hardcoding our guess.
  • TrackDownloadWorker: PerfSummary log line at end of doWork
    with tracks/seconds/tracks-per-minute. Greppable for empirical
    before/after measurement.
  • QueueTrace diagnostic logs on download_queue inserts (DiffWorker)
    and consume-time duplicate detection (TrackDownloadWorker) for
    future debugging if duplicate-queueing recurs.

Measured on a real sync: 70 tracks in 8m 1s = 8.7 tracks/min,
vs prior ~2.7 tracks/min baseline. ~3.2x faster.

Specs: docs/superpowers/specs/2026-05-03-monochrome-source-design.md
(historical — describes the original Tidal-side design before the
pivot)

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com


Install

Download the .apk below and open it on your Android device. If you've got a previous Stash release installed, this upgrades in place — your library, sync history, and settings are preserved.

Requires: Android 8.0 (API 26) or newer.

See the README for first-time setup.

Full Changelog: v0.9.9...v0.9.10

Don't miss a new Stash release

NewReleases is sending notifications on new releases.