All AOSP
Choir app icon

Choir

The music on your device, and nothing else.

Choir plays the music you own. No accounts, no streaming, no recommendations, no telemetry, and no record of what you listen to. It is monochrome on purpose — hierarchy comes from type, never colour — and it holds exactly one optional network feature, which is off until you turn it on.

Version
0.3.0
Platform
Android 10 and up
Licence
GPL-3.0-or-later
Network
Offline by default

Choir holds the internet permission for one optional feature — fetching lyrics for tracks whose files have none — and while it is off nothing in the app opens a connection. Switch it on and what leaves the device is a track's title, artist and length, sent to the service you picked.

Free software, and any modified version has to stay that way — source included.

Why GPL-3.0-or-later?

Choir is GPL because a local music player is precisely the thing that gets forked, wrapped in a feed and an ad slot, and sold back to you as the same app with a subscription. MIT would let that happen quietly. GPL means whoever does it has to hand you the source, which is usually enough to make it not worth doing.

In 0.3.0 · August 2026

Lyrics, liked songs and editable playlists — and a library that stops hiding what it could not read.

  • Lyrics read from .lrc sidecars and from ID3v2, Vorbis, MP4 and WAV tags, scrolled in time with the song, down to the word where the file says so. Optionally fetched from LRCLIB, NetEase, Musixmatch or your own service — off by default, and in an order you set.
  • Liked songs and editable playlists, both re-linked if Android renumbers your library, with .m3u import and export.
  • FFmpeg decoding for ALAC and Dolby, an AIFF reader written from scratch, and files the media scanner could not parse listed rather than hidden — a track that will not play now says why.
  • 201 unit tests, weighted where the bugs are: parsing other people's files, and deciding what a file is. Tag parsing runs against byte fixtures built inside the tests, so a fixture cannot drift from the format it claims.

Lyric lookup is the one thing that opens a connection

Choir holds the internet permission for it and nothing else, and while it is off nothing in the app touches the network. Switch it on and what leaves the device is a track's title, artist and length, sent to the service you picked — nothing about you, and nothing about the rest of your library.

Screens

What it looks like

Real screens from a real phone. Tap any of them to see it full size.

  • The library

  • Albums

  • Inside an album

  • Now playing

  • Search, instantly

Features

What it does

Your library, as it actually is

Tracks, albums, artists and playlists read from MediaStore. Files the scanner could not parse are listed rather than quietly dropped, and a track that will not play tells you what stopped it.

Lyrics, in time with the song

Read from .lrc sidecars and from the tags inside the file — ID3v2, Vorbis, MP4, WAV — and scrolled line by line, or word by word where the file carries that. Fetching them online is opt-in and off by default.

A queue that survives a restart

Playing from an album, an artist or a search result queues that list, and it is still there when you come back. Gapless-capable ExoPlayer underneath, with audio focus, becoming-noisy handling, a media notification, lock-screen and Bluetooth controls.

Playlists you can actually edit

Create, rename, reorder by dragging, import and export .m3u. Liked songs are a manual list kept in Room — no algorithm decided any of it. Both are re-linked if Android renumbers your library underneath them.

Formats, honestly stated

Everything Android guarantees, plus ALAC and Dolby where the FFmpeg decoder is built in. The format table was written after pushing files in each format to a real phone and reading back what the scanner made of them, not copied out of documentation.

Monochrome, on purpose

Ink on paper throughout, EB Garamond for content and Inter for chrome. Nothing is colour-coded, because nothing needs to be — the hierarchy is in the type.

Limits

What it does not do yet

Said here rather than discovered later. Everything below is known, deliberate, and on the list.

  • The library is what MediaStore reports. Browsing your own folders through SAF is 0.4.0.
  • APE, WavPack and WMA need demuxers Media3 does not ship — a decoder alone is not enough, and they are on the 0.4.0 list.
  • This is a working interface, not the final one. The iPod-style hierarchy, the paper-grain overlay and the sketched icon set land in 0.5.0.
  • Nothing is shared between devices yet. Peer-to-peer over Bluetooth or Wi-Fi Direct is 0.6.0.

Files

The files it reads and writes

.m3u

playlists, in and out — the format every other player already reads

.lrc

timed lyrics, read from a sidecar next to the audio file

Both are plain text, written by half the software on your computer and readable by the other half. Nothing here is a format only Choir can open.