From d69c44eff9d4f1ec369f60ec8365747ab860167e Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 20 Oct 2026 15:09:12 -0700 Subject: [PATCH] README: make it generic (no host paths, IPs or personal examples) Co-Authored-By: Claude Sonnet 5.5 --- README.md | 70 +++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 2c6a964..721e266 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ It runs on iPhone (with CarPlay), Android (with Android Auto) and Linux desktop. ## How it works -The stems folder mirrors the music folder. If a song lives at `Kansas/Leftoverture/01 Carry On.flac`, its stems live in `Stems/Kansas/Leftoverture/01 Carry On/`. +The stems folder mirrors the music folder. If a song lives at `Artist/Album/01 Song.flac`, its stems live in `Stems/Artist/Album/01 Song/`. ``` your server @@ -63,48 +63,48 @@ Mix presets are Full, Karaoke, A Cappella, No Drums, Rhythm, No Guitar and No Ba ## Setup -Set up the server first, then the apps. The examples use Unraid paths and `192.168.86.2` for the server; use your own. +Set up the server first, then the apps. The examples use `/srv/stemify` for app data, `/srv/music/library` for your music, `/srv/music/stems` for the output and `SERVER_IP` for the machine running the containers. Change them to match your setup. ### Server -You need Docker, and an NVIDIA GPU for stemd (on Unraid, install the Nvidia-Driver plugin). A CPU build exists for testing, but it's far too slow for a whole library. +You need Docker, and an NVIDIA GPU for stemd (with the NVIDIA container toolkit installed). A CPU build exists for testing, but it's far too slow for a whole library. -Make the folders, owned by `99:100` (Unraid's nobody:users): +Make the folders, owned by whatever user the containers run as (`1000:1000` here): ```sh -mkdir -p /mnt/user/appdata/stemserve/cache \ - /mnt/user/appdata/stemd/models \ - /mnt/user/appdata/stemd/state/queue -chown -R 99:100 /mnt/user/appdata/stemserve /mnt/user/appdata/stemd +mkdir -p /srv/stemify/stemserve/cache \ + /srv/stemify/stemd/models \ + /srv/stemify/stemd/state/queue +chown -R 1000:1000 /srv/stemify/stemserve /srv/stemify/stemd ``` -**stemd** builds from the repo root because it uses the `stemify` package. Copy the repo (at least `stemify/`, `server/` and `.dockerignore`) to `/mnt/user/appdata/stemd/src`, then: +**stemd** builds from the repo root because it uses the `stemify` package. Copy the repo (at least `stemify/`, `server/` and `.dockerignore`) to `/srv/stemify/stemd/src`, then: ```sh -docker build -f /mnt/user/appdata/stemd/src/server/stemd.Dockerfile -t stemd /mnt/user/appdata/stemd/src +docker build -f /srv/stemify/stemd/src/server/stemd.Dockerfile -t stemd /srv/stemify/stemd/src docker run -d --name stemd --restart unless-stopped --stop-timeout 60 \ --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \ - -v "/mnt/user/Music/Actual music/Flacs":/music:ro \ - -v /mnt/user/Music/Stems:/stems \ - -v /mnt/user/appdata/stemd/models:/models \ - -v /mnt/user/appdata/stemd/state:/state \ + -v /srv/music/library:/music:ro \ + -v /srv/music/stems:/stems \ + -v /srv/stemify/stemd/models:/models \ + -v /srv/stemify/stemd/state:/state \ stemd ``` The first song downloads the model (about 700 MB). After that the log shows what's left, what it's on, and how fast it's going. -**stemserve** is one Python file using only the standard library. It also serves the web player from `web/`. Copy the repo's `server/` and `web/` folders to `/mnt/user/appdata/stemserve` and run `docker compose up -d --build` in `server/`, or by hand: +**stemserve** is one Python file using only the standard library. It also serves the web player from `web/`. Copy the repo's `server/` and `web/` folders to `/srv/stemify/stemserve` and run `docker compose up -d --build` in `server/`, or by hand: ```sh -docker build -f /mnt/user/appdata/stemserve/server/Dockerfile -t stemserve /mnt/user/appdata/stemserve +docker build -f /srv/stemify/stemserve/server/Dockerfile -t stemserve /srv/stemify/stemserve docker run -d --name stemserve --restart unless-stopped -p 8765:8765 \ - -v /mnt/user/Music/Stems:/stems:ro \ - -v /mnt/user/appdata/stemserve/cache:/cache \ - -v /mnt/user/appdata/stemd/state/queue:/queue \ + -v /srv/music/stems:/stems:ro \ + -v /srv/stemify/stemserve/cache:/cache \ + -v /srv/stemify/stemd/state/queue:/queue \ stemserve ``` -`curl http://192.168.86.2:8765/api/info` should return JSON with a track count. +`curl http://SERVER_IP:8765/api/info` should return JSON with a track count. To update, copy the new files, rebuild, `docker rm -f` the container and run it again. Everything that matters lives in the mounted folders. Update stemd before stemserve. @@ -155,14 +155,14 @@ The apps check stemserve for newly separated songs every minute, so the library ## iOS -A SwiftUI app for iOS 17 or newer, with CarPlay and Siri ("play Paranoid in Stemify"). +A SwiftUI app for iOS 17 or newer, with CarPlay and Siri ("play in Stemify"). ### Install -Grab `stemify-.ipa` from [Releases](https://git.iamchrisama.com/cdnutter/stemify/releases) and sideload it with AltStore, SideStore, Sideloadly or Feather. To get updates in AltStore, SideStore or Feather, add this source: +Grab `stemify-.ipa` from the repo's Releases page and sideload it with AltStore, SideStore, Sideloadly or Feather. `ios/source.json` is an AltStore-style source. Add its raw URL to AltStore, SideStore or Feather for updates: ``` -https://git.iamchrisama.com/cdnutter/stemify/raw/branch/main/ios/source.json +https:////stemify/raw/branch/main/ios/source.json ``` CarPlay and Siri need the `carplay-audio` and `siri` entitlements, which a free Apple ID can't sign. On a free sideload the app works on the phone but not in CarPlay or Siri. A paid developer account covers Siri; CarPlay audio also needs Apple to approve the entitlement for your team. @@ -186,7 +186,7 @@ CarPlay and Siri need the `carplay-audio` and `siri` entitlements, which a free ## Android -Kotlin and Jetpack Compose, built and tested on a OnePlus 15. Grab `Stemify.apk` from Releases (or [build it](#building-and-testing)) and `adb install -r Stemify.apk`. +Kotlin and Jetpack Compose, [build it](#building-and-testing) or grab `Stemify.apk` from Releases if one is attached, and `adb install -r Stemify.apk`. ### Using it @@ -194,7 +194,7 @@ Kotlin and Jetpack Compose, built and tested on a OnePlus 15. Grab `Stemify.apk` - **Badges:** songs without stems yet say NO STEMS, and albums and artists show NO STEMS or a count like 7/10 STEMS. They still play from the original file. - **Now Playing:** waveform seek bar (drag sideways to seek, up and down for volume), mixer, meters and queue. Your mix can carry over between songs or reset. - **Stem Quality:** lossless FLAC, or Opus at a bitrate you choose (about an eighth of the size, transcoded and cached on the server). -- **Streaming** needs your home network, since Plex and stemserve are plain HTTP on the LAN. Downloads and already-streamed songs play anywhere. +- **Streaming** works anywhere you can reach Plex and stemserve. Both are plain HTTP by default, so use HTTPS or a VPN away from home. Downloads and already-streamed songs play anywhere. ### Equalizer @@ -209,12 +209,12 @@ Profiles are tied to outputs (speaker, wired, each Bluetooth device, USB DACs) a ### Android Auto -Built for a 2016 Mazda MX-5 with Mazda Connect: 800×480, no touch, knob and wheel buttons only. +Designed for small non-touch head units (800×480, knob and wheel buttons only), and it works the same on larger screens. - Tabs for Playlists, Albums, Artists and Downloads (Downloads first when you're away from home). - Every song list starts with Shuffle all, and lists over 40 items split into A to Z folders. -- Now Playing has a Vocals on/off button and a Mix button that cycles presets. The mix shows on the artist line, like "Black Sabbath · Karaoke". -- Voice: "play Paranoid on Stemify" works for playlists, artists, albums and songs. +- Now Playing has a Vocals on/off button and a Mix button that cycles presets. The mix shows on the artist line, like "Artist · Karaoke". +- Voice: "play on Stemify" works for playlists, artists, albums and songs. - Away from home it notices the server is gone and only lists songs that will play. Android Auto hides sideloaded apps until you allow them: in the phone's Android Auto settings, tap Version ten times, then ⋮ → Developer settings → Unknown sources. @@ -279,11 +279,11 @@ Requests run oldest first and survive restarts. stemd matches Plex's paths to it ### Folder layout ``` -Music/Kansas/Leftoverture/01 Carry On Wayward Son.flac -Stems/Kansas/Leftoverture/01 Carry On Wayward Son/ +Music/Artist/Album/01 Song.flac +Stems/Artist/Album/01 Song/ .stemify.json done marker - 01 Carry On Wayward Son - vocals.flac - 01 Carry On Wayward Son - drums.flac + 01 Song - vocals.flac + 01 Song - drums.flac ... ``` @@ -303,7 +303,7 @@ Stems/Kansas/Leftoverture/01 Carry On Wayward Son/ | `GET /file/K/.flac[?fmt=opus&br=256]` | The stem, with range support | | `GET /` | The web player from `web/` (or `WEB_DIR`), no token needed | -`K` is the song's folder under the stems root, like `Kansas/Leftoverture/01 Carry On Wayward Son`. Outside Docker: +`K` is the song's folder under the stems root, like `Artist/Album/01 Song`. Outside Docker: ```sh STEMS_DIR=/path/to/Stems CACHE_DIR=~/.cache/stemserve python3 server/stemserve.py @@ -358,7 +358,7 @@ QT_QPA_PLATFORM=offscreen uv run stemify-player --no-mpris --screenshot /tmp/p.p **A song says NO STEMS.** Hold it and choose Stem Now. -**Stem Now says "stemserve needs updating" or "queue folder isn't mounted".** stemserve is older than the app or is missing the `/queue` mount. The queue folder has to be owned by `99:100` before the container first starts, or Docker creates it as root. +**Stem Now says "stemserve needs updating" or "queue folder isn't mounted".** stemserve is older than the app or is missing the `/queue` mount. The queue folder has to be writable by the container user before the container first starts, or Docker creates it as root. **stemd is separating on the CPU.** The container can't see the GPU. Run it with `--runtime=nvidia` and the NVIDIA variables above. @@ -381,7 +381,7 @@ QT_QPA_PLATFORM=offscreen uv run stemify-player --no-mpris --screenshot /tmp/p.p - [LRCLIB](https://lrclib.net) for synced lyrics - Inter, Selawik and Carlito fonts (licenses included alongside them) -Stemify isn't affiliated with Plex, Apple, Google, Microsoft or Mazda. +Stemify isn't affiliated with Plex, Apple, Google or Microsoft. ## License