docs(readme): document distro install path and demote NixOS to optional aside
This commit is contained in:
1 parent
3866f0277c
commit
44cc36a470
1 file changed
+85
-61
@@ -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
|
audio control, spectrum visualiser and MPRIS service are all implemented here from
|
||||||
the public SomaFM endpoints and open protocols.
|
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
|
## Features
|
||||||
|
|
||||||
- **Live spectrum analyser** — 72 log-spaced bands with peak caps, a moving
|
- **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
|
## Requirements
|
||||||
|
|
||||||
Python **3.10+**, plus the tools below. This is a minimum, not a pin: there
|
`somafm-tui` is a normal Python application: there is nothing to compile and
|
||||||
is no `.python-version`, and `uv` can install a compatible interpreter if your
|
no distro-specific packaging. It runs on any Linux distribution with Python
|
||||||
distro ships something older. `shell.nix` provides everything inside an
|
**3.10+** and a few command-line audio tools on `$PATH`.
|
||||||
**FHS environment** (needed because uv installs manylinux wheels such as
|
|
||||||
NumPy, which expect `libstdc++.so.6` in the standard FHS paths):
|
|
||||||
|
|
||||||
| tool | why |
|
| tool | why |
|
||||||
| -------- | ------------------------------------------------------- |
|
| ---- | --- |
|
||||||
| python3 | runtime (CPython 3.10 or newer; no exact version pin) |
|
| `python3` | runtime (3.10 or newer; no exact version pin) |
|
||||||
| uv | installs **all** Python dependencies (see `pyproject.toml`) |
|
| [`uv`](https://docs.astral.sh/uv/) | creates the venv and installs every Python dependency from `uv.lock` |
|
||||||
| mpv | playback + JSON IPC control |
|
| `mpv` | playback and JSON IPC control |
|
||||||
| ffmpeg | muted stream decode (fallback analyser) |
|
| `ffmpeg` | muted stream decode for the fallback analyser |
|
||||||
| pulseaudio | `parec`/`pactl` for the synced monitor capture (works with PipeWire) |
|
| `parec` / `pactl` | synced monitor capture for the spectrum (`pulseaudio-utils`; works with PipeWire) |
|
||||||
| dbus | session bus for MPRIS (`playerctl` included for testing) |
|
| 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
|
Terminal image rendering uses [Pillow](https://python-pillow.org/) and is
|
||||||
implemented directly (Kitty TGP + iTerm2 OSC 1337) — no terminal probing.
|
implemented directly (Kitty TGP + iTerm2 OSC 1337) — no terminal probing.
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
```bash
|
From the repository root, sync the environment and start the app:
|
||||||
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:
|
|
||||||
|
|
||||||
```bash
|
```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
|
You do **not** need to activate the venv. `uv run` uses `.venv` automatically,
|
||||||
> interactively and run commands there.
|
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:
|
Useful flags:
|
||||||
|
|
||||||
@@ -195,14 +204,6 @@ containers, …) MPRIS is skipped and the status bar shows `mpris off`.
|
|||||||
|
|
||||||
## Notes / troubleshooting
|
## 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,
|
- **Artwork shows the mosaic?** Real images are auto-enabled for Kitty,
|
||||||
iTerm2 and WezTerm. Force a protocol with `SOMAFM_IMAGES=tgp` (Kitty/TGP) or
|
iTerm2 and WezTerm. Force a protocol with `SOMAFM_IMAGES=tgp` (Kitty/TGP) or
|
||||||
`SOMAFM_IMAGES=iterm2` (iTerm2/WezTerm); `SOMAFM_IMAGES=0` forces the ANSI
|
`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
|
`set -g allow-passthrough on`); iTerm2/WezTerm inside tmux default to the
|
||||||
mosaic. Images are cached under `~/.cache/somafm-tui/artwork`.
|
mosaic. Images are cached under `~/.cache/somafm-tui/artwork`.
|
||||||
- **Clock shows UTC?** The clock and song history use the system zone from
|
- **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
|
`/etc/localtime`; a non-UTC `TZ` overrides it. A container or dev shell can
|
||||||
build-time `TZ=UTC`, which the app deliberately ignores. In a container, bind
|
inherit a build-time `TZ=UTC`, which the app deliberately ignores; bind the
|
||||||
the host's `/etc/localtime` or set e.g. `TZ=Europe/Berlin`.
|
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
|
- **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
|
(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
|
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).
|
demo).
|
||||||
- SomaFM is listener-supported: if you enjoy it, [donate](https://somafm.com/support/).
|
- 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
|
## Licence
|
||||||
|
|
||||||
WTFPL — Do What The Fuck You Want To Public License, Version 2. See
|
WTFPL — Do What The Fuck You Want To Public License, Version 2. See
|
||||||
|
|||||||
Reference in new issue
Block a user