docs(readme): document distro install path and demote NixOS to optional aside

This commit is contained in:
beefcarver committed 2026-10-30 04:24:53 +00:00
1 parent 3866f0277c
commit 44cc36a470
1 file changed
+86 -62
+86 -62
View File
@@ -9,33 +9,6 @@ No existing SomaFM client is used: the station list, playlists, song history,
audio control, spectrum visualiser and MPRIS service are all implemented here from
the public SomaFM endpoints and open protocols.
```
▄▀▀▀ ▄▀▀▄ █▄ ▄█ ▄▀▀▄ SOMA FM RADIO 14:32:07
▀▀▀▄ █ █ █ █ █ █▀▀█ LISTENER SUPPORTED Sat 15 Nov
▄▄▄▀ ▀▄▄▀ █ █ █ █ SAN FRANCISCO vol 70%
● PLAYING Groove Salad · Jens Buchert — Rauschebart
┌ STATIONS ───────────────┐┌ ON AIR ────────────────────────────────────┐
│ ★ ▶ Groove Salad 1.9k ││ ▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄ GROOVE SALAD ● PLAYING│
│ ▶ Drone Zone 812 ││ ▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀ A nicely chilled plate│
│ Secret Agent 420 ││ │
│ Indie Pop Rocks 901 ││ NOW PLAYING 12s ago │
│ … ││ Jens Buchert │
│ ││ Rauschebart │
│ ││ Gravity dj Rusty Hodge │
│ ││ ♪ 1.9k listeners · mp3 · 128k │
│ ││ │
│ ││ LAST PLAYED │
│ ││ 14:29 Alex Cortiz — Room 505 │
│ ││ 14:24 Tosca — Amber November │
└─────────────────────────┘└────────────────────────────────────────────┘
┌ SPECTRUM · MIRROR · SYNC ─────────────────────────────────────────────┐
│ ▁▃▅▇█▇▅▃▁ ▂▄▆█▆▄▂ │
│ ▁▂▄▆██████████████████▆▄▂▁▂▄▆█████████▆▄▂▁ │
│ ▀▄▂▁▂▄▆██████████████████▆▄▂▁▂▄▆█████████▆▄▂▁ │
└───────────────────────────────────────────────────────────────────────┘
space pause · ↑↓ station · enter tune · +/- vol · f ★ · / filter · ? help
```
## Features
- **Live spectrum analyser** — 72 log-spaced bands with peak caps, a moving
@@ -71,41 +44,77 @@ space pause · ↑↓ station · enter tune · +/- vol · f ★ · / filter · ?
## Requirements
Python **3.10+**, plus the tools below. This is a minimum, not a pin: there
is no `.python-version`, and `uv` can install a compatible interpreter if your
distro ships something older. `shell.nix` provides everything inside an
**FHS environment** (needed because uv installs manylinux wheels such as
NumPy, which expect `libstdc++.so.6` in the standard FHS paths):
`somafm-tui` is a normal Python application: there is nothing to compile and
no distro-specific packaging. It runs on any Linux distribution with Python
**3.10+** and a few command-line audio tools on `$PATH`.
| tool | why |
| -------- | ------------------------------------------------------- |
| python3 | runtime (CPython 3.10 or newer; no exact version pin) |
| uv | installs **all** Python dependencies (see `pyproject.toml`) |
| mpv | playback + JSON IPC control |
| ffmpeg | muted stream decode (fallback analyser) |
| pulseaudio | `parec`/`pactl` for the synced monitor capture (works with PipeWire) |
| dbus | session bus for MPRIS (`playerctl` included for testing) |
| tool | why |
| ---- | --- |
| `python3` | runtime (3.10 or newer; no exact version pin) |
| [`uv`](https://docs.astral.sh/uv/) | creates the venv and installs every Python dependency from `uv.lock` |
| `mpv` | playback and JSON IPC control |
| `ffmpeg` | muted stream decode for the fallback analyser |
| `parec` / `pactl` | synced monitor capture for the spectrum (`pulseaudio-utils`; works with PipeWire) |
| D-Bus session bus | MPRIS desktop media integration (`playerctl` is handy for testing) |
Install these with your package manager. Names are usually:
```bash
# Debian / Ubuntu
sudo apt install python3 mpv ffmpeg pulseaudio-utils dbus playerctl
# Fedora (enable RPM Fusion for ffmpeg if needed)
sudo dnf install python3 mpv ffmpeg pulseaudio-utils dbus-tools playerctl
# Arch / Manjaro
sudo pacman -S python mpv ffmpeg libpulse dbus playerctl
# openSUSE
sudo zypper install python3 mpv ffmpeg pulseaudio-utils dbus-1-tools playerctl
```
For other distributions, install the equivalents. On a headless machine you
can skip the audio/D-Bus tools and use `--no-audio` for a UI-only demo, though
the synced spectrum needs `parec`/`pactl`.
Install `uv` once with the official installer:
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
`pipx install uv`, `brew install uv`, or a distro package also work. If your
distro's Python is older than 3.10, let uv manage one: `uv python install 3.12`.
Terminal image rendering uses [Pillow](https://python-pillow.org/) and is
implemented directly (Kitty TGP + iTerm2 OSC 1337) — no terminal probing.
## Run
```bash
nix-shell # enters the FHS dev shell
uv sync
uv run somafm-tui
```
If you used an older `shell.nix` before, recreate the venv once so it picks up
the Nix-provided Python:
From the repository root, sync the environment and start the app:
```bash
rm -rf .venv && uv sync
uv sync # create .venv and install exactly what uv.lock pins
uv run somafm-tui # run inside that environment
```
> FHS shell.nix files do not support `nix-shell --run "..."`. Enter the shell
> interactively and run commands there.
You do **not** need to activate the venv. `uv run` uses `.venv` automatically,
and re-syncs it first if `pyproject.toml` or `uv.lock` changed. If you prefer a
traditional shell, run `source .venv/bin/activate` and then `somafm-tui`.
### Keeping the uv environment in sync
`uv sync` is the command to remember. It is incremental, safe to re-run, and
should be run after pulling changes, switching branches, or editing
`pyproject.toml`:
```bash
uv sync # make .venv match uv.lock
uv sync --frozen # strict: fail if uv.lock is out of date, never rewrite it
uv lock --upgrade # refresh uv.lock to the newest allowed versions
uv sync --upgrade # upgrade dependencies and sync .venv in one step
rm -rf .venv && uv sync # last resort if the venv was built by an older Python
```
Useful flags:
@@ -195,14 +204,6 @@ containers, …) MPRIS is skipped and the status bar shows `mpris off`.
## Notes / troubleshooting
- **NixOS: `libstdc++.so.6: cannot open shared object file`** — this is NumPy's
manylinux wheel looking for the C++ runtime. `shell.nix` now uses
`pkgs.buildFHSEnv` and installs `stdenv.cc.cc.lib`, so `nix-shell` puts you in
an FHS root where the wheel loads. If the error persists, your `.venv` was
built against a different Python: `rm -rf .venv && uv sync`.
- **`bwrap: No permissions to create a new namespace`** — FHS shells need
unprivileged user namespaces. They are enabled by default on NixOS; inside a
locked-down container you may need to run the app on the host instead.
- **Artwork shows the mosaic?** Real images are auto-enabled for Kitty,
iTerm2 and WezTerm. Force a protocol with `SOMAFM_IMAGES=tgp` (Kitty/TGP) or
`SOMAFM_IMAGES=iterm2` (iTerm2/WezTerm); `SOMAFM_IMAGES=0` forces the ANSI
@@ -210,9 +211,10 @@ containers, …) MPRIS is skipped and the status bar shows `mpris off`.
`set -g allow-passthrough on`); iTerm2/WezTerm inside tmux default to the
mosaic. Images are cached under `~/.cache/somafm-tui/artwork`.
- **Clock shows UTC?** The clock and song history use the system zone from
`/etc/localtime`; a non-UTC `TZ` overrides it. `nix-shell` can inherit a
build-time `TZ=UTC`, which the app deliberately ignores. In a container, bind
the host's `/etc/localtime` or set e.g. `TZ=Europe/Berlin`.
`/etc/localtime`; a non-UTC `TZ` overrides it. A container or dev shell can
inherit a build-time `TZ=UTC`, which the app deliberately ignores; bind the
host's `/etc/localtime` or set e.g. `TZ=Europe/Berlin` in the shell that
launches the app.
- **MPRIS says off/error?** No session bus. Run from your desktop session
(the shell profile picks up `$XDG_RUNTIME_DIR/bus`). `dbus-run-session -- uv
run somafm-tui` starts a private bus for testing, but desktop widgets won't
@@ -238,6 +240,28 @@ containers, …) MPRIS is skipped and the status bar shows `mpris off`.
demo).
- SomaFM is listener-supported: if you enjoy it, [donate](https://somafm.com/support/).
## NixOS (optional aside)
None of the above needs Nix. If you *are* on NixOS, `shell.nix` wraps the same
`uv sync` / `uv run` workflow in an FHS environment, because uv installs
manylinux wheels such as NumPy that expect `libstdc++.so.6` in the usual
`/usr/lib` paths:
```bash
nix-shell # enter the FHS dev shell
uv sync
uv run somafm-tui
```
- If you see `libstdc++.so.6: cannot open shared object file`, make sure you
are inside `nix-shell`, then recreate the venv once with
`rm -rf .venv && uv sync`.
- `nix-shell --run "..."` does not work with FHS `shell.nix` files; enter the
shell interactively and run commands there.
- FHS shells need unprivileged user namespaces. `bwrap: No permissions to
create a new namespace` means they are disabled (for example in a locked-down
container); run the app on the host instead.
## Licence
WTFPL — Do What The Fuck You Want To Public License, Version 2. See