README: make it generic (no host paths, IPs or personal examples)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1cf9341cda
commit
d69c44eff9
1 file changed
+35
-35
@@ -20,7 +20,7 @@ It runs on iPhone (with CarPlay), Android (with Android Auto) and Linux desktop.
|
|||||||
|
|
||||||
## How it works
|
## 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
|
your server
|
||||||
@@ -63,48 +63,48 @@ Mix presets are Full, Karaoke, A Cappella, No Drums, Rhythm, No Guitar and No Ba
|
|||||||
|
|
||||||
## Setup
|
## 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
|
### 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
|
```sh
|
||||||
mkdir -p /mnt/user/appdata/stemserve/cache \
|
mkdir -p /srv/stemify/stemserve/cache \
|
||||||
/mnt/user/appdata/stemd/models \
|
/srv/stemify/stemd/models \
|
||||||
/mnt/user/appdata/stemd/state/queue
|
/srv/stemify/stemd/state/queue
|
||||||
chown -R 99:100 /mnt/user/appdata/stemserve /mnt/user/appdata/stemd
|
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
|
```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 \
|
docker run -d --name stemd --restart unless-stopped --stop-timeout 60 \
|
||||||
--runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \
|
--runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility \
|
||||||
-v "/mnt/user/Music/Actual music/Flacs":/music:ro \
|
-v /srv/music/library:/music:ro \
|
||||||
-v /mnt/user/Music/Stems:/stems \
|
-v /srv/music/stems:/stems \
|
||||||
-v /mnt/user/appdata/stemd/models:/models \
|
-v /srv/stemify/stemd/models:/models \
|
||||||
-v /mnt/user/appdata/stemd/state:/state \
|
-v /srv/stemify/stemd/state:/state \
|
||||||
stemd
|
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.
|
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
|
```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 \
|
docker run -d --name stemserve --restart unless-stopped -p 8765:8765 \
|
||||||
-v /mnt/user/Music/Stems:/stems:ro \
|
-v /srv/music/stems:/stems:ro \
|
||||||
-v /mnt/user/appdata/stemserve/cache:/cache \
|
-v /srv/stemify/stemserve/cache:/cache \
|
||||||
-v /mnt/user/appdata/stemd/state/queue:/queue \
|
-v /srv/stemify/stemd/state/queue:/queue \
|
||||||
stemserve
|
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.
|
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
|
## 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 <song> in Stemify").
|
||||||
|
|
||||||
### Install
|
### Install
|
||||||
|
|
||||||
Grab `stemify-<version>.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-<version>.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://<your-git-host>/<owner>/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.
|
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
|
## 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
|
### 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.
|
- **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.
|
- **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).
|
- **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
|
### Equalizer
|
||||||
|
|
||||||
@@ -209,12 +209,12 @@ Profiles are tied to outputs (speaker, wired, each Bluetooth device, USB DACs) a
|
|||||||
|
|
||||||
### Android Auto
|
### 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).
|
- 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.
|
- 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".
|
- 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 Paranoid on Stemify" works for playlists, artists, albums and songs.
|
- Voice: "play <song> 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.
|
- 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.
|
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
|
### Folder layout
|
||||||
|
|
||||||
```
|
```
|
||||||
Music/Kansas/Leftoverture/01 Carry On Wayward Son.flac
|
Music/Artist/Album/01 Song.flac
|
||||||
Stems/Kansas/Leftoverture/01 Carry On Wayward Son/
|
Stems/Artist/Album/01 Song/
|
||||||
.stemify.json done marker
|
.stemify.json done marker
|
||||||
01 Carry On Wayward Son - vocals.flac
|
01 Song - vocals.flac
|
||||||
01 Carry On Wayward Son - drums.flac
|
01 Song - drums.flac
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ Stems/Kansas/Leftoverture/01 Carry On Wayward Son/
|
|||||||
| `GET /file/K/<file>.flac[?fmt=opus&br=256]` | The stem, with range support |
|
| `GET /file/K/<file>.flac[?fmt=opus&br=256]` | The stem, with range support |
|
||||||
| `GET /` | The web player from `web/` (or `WEB_DIR`), no token needed |
|
| `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
|
```sh
|
||||||
STEMS_DIR=/path/to/Stems CACHE_DIR=~/.cache/stemserve python3 server/stemserve.py
|
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.
|
**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.
|
**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
|
- [LRCLIB](https://lrclib.net) for synced lyrics
|
||||||
- Inter, Selawik and Carlito fonts (licenses included alongside them)
|
- 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
|
## License
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user