feat(train): marked playlists kept on the phone, their tempo worked out (ADR 0030, D47)

Music's second part: the marked playlists' tracks are downloaded as
Jellyfin keeps them, on unmetered networks only, while the app is open
or resumes, and deleted once no marked playlist holds them. Each
track's tempo is worked out once on the phone: a BPM tag where the file
has one, else a minute decoded with MediaCodec and its spectral flux
autocorrelated (Tempo.kt, tested on the JVM). The music screen shows
what is kept and deletes it after asking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-29 12:48:53 +01:00
commit 7f18f001f4
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -1039,6 +1039,28 @@ Strava. What was found, 27 Oct:
on the phone too. Signing out ends the token on the server where it answers. The
person's playlists of music are listed (a playlist naming no type counts as one,
one of videos doesn't) and marked, the marked ones by ID and name in `music.json`.
Built: 10b. The marked playlists' tracks are kept in the person's `music/`, each
once whatever the playlists holding it, as Jellyfin keeps the file (`/Audio/…/stream`
with `static`, no transcoding; a smaller copy on request is left for when a library
shows the need), through a part file renamed once whole. Downloading is the app's
own, while it is open or resumed, where Android calls the network unmetered (its own
verdict, not merely Wi-Fi: a phone's hotspot is metered): the token is in the app's
keyring, which a background job of Android's couldn't read without a copy outside
it. What no marked playlist holds any more is deleted at once, offline too; a track
taken out of its playlist on the server goes at the next sync, a playlist that
can't be read keeps its tracks, a track that fails to download is tried again at
the next. Each track's tempo is worked out once after its download, on the phone
(`MusicBridge.kt`): an ID3v2 `TBPM` frame or a FLAC `BPM` comment where the file has
one (`BpmTag.kt`; from 40 to 250 only), else a minute from the middle decoded by
Android's MediaCodec, mixed down to mono, its spectral flux (about 86 frames a
second) autocorrelated over 50 to 220 beats per minute and weighed towards 120 by
an octave either side (`Tempo.kt`), none where the beat repeats too weakly; tested
on the JVM with kicks of known tempo (within a beat a minute, hi-hats on the
off-beat not doubling it), noise and silence having none, and tags cut short. The
music screen shows what the phone keeps (tracks, size, how many have a tempo, the
wait for an unmetered network) and *Delete*, which after asking unmarks every
playlist. Not tried on a phone yet: decoding real files, how often the analysis
lands an octave off (10c counts half and double as fitting).
## Consequences