Skip to content

Stash v0.5.4

Choose a tag to compare

@github-actions github-actions released this 22 Apr 22:59
· 1601 commits to master since this release

feat: 0.5.4 — Track duration for Stash Discover downloads

Companion to 0.5.3's art fix. Same cohort of 20 Stash Discover tracks
that had no album art also had duration_ms = 0 in the tracks table —
so the playlist row rendered a blank duration even though ExoPlayer
showed the correct length at play-time. The root cause is the same:
persistMatchMetadata was the only code path writing these fields,
and when the YT match surfaced no duration (yt-dlp-direct fallback,
or UGC uploads returning plain video renderers), fillMissingMetadata
wrote zero and left the row effectively un-filled.

Picked MediaMetadataRetriever on the local file as the source of
truth because (a) the file is already on disk with real encoded audio,
(b) it's the same mechanism ExoPlayer uses at playback time so the
playlist UI now agrees with the progress bar by construction, (c) no
network, no rate-limit, no metadata drift. Considered and rejected
Last.fm track.getInfo (drifts from actual file duration for tracks
that had label metadata re-entered) and falling back to match-result
duration (already the primary source, this only runs when it was
zero).

Three changes:

AudioDurationExtractor — thin MediaMetadataRetriever wrapper that
handles both plain java.io.File paths and SAF-backed content://
URIs, same dispatch pattern as the SAF-aware delete helper from 0.5.2.
Returns null on corrupt / missing files so a batch caller can continue.

Primary-path fix — TrackDownloadWorker now extracts duration from the
freshly-committed file right after markAsDownloaded and writes via
the new fillMissingDuration DAO method. Guarded by duration_ms = 0
in both the Kotlin gate and the SQL WHERE so known-good Spotify
durations are never overwritten.

Backfill — ArtBackfillWorker gained a second pass for duration. Purely
local, no rate-limit, completes in single-digit milliseconds per track.
Verified on device: all 20 historical Discovery tracks picked up real
durations (3-8 minutes) in ~400ms; overall duration_ms = 0 AND is_downloaded = 1 count is now 0 across the library.

Known-incomplete:

  • Belleville (Laurel Halo): art still null. Last.fm has no entry for
    the track, and youtube_id is null (never populated by the match),
    so both fallbacks produce nothing. Will self-heal the next time
    Discovery re-matches it through a different resolve path.
  • The Piano Drop (Tim Hecker): is_downloaded = 0, still a Discovery
    stub waiting for its download to drain from the queue. Will
    self-heal when the download completes — it'll go through the v0.5.3
    art fix + v0.5.4 duration fix in the same pass.

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.5.3...v0.5.4