🎉 live server seems to be working now
This commit is contained in:
114
README.md
Normal file
114
README.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# rpi-sendspin
|
||||
|
||||
A [sendspin](https://github.com/Sendspin/sendspin-go) client and server with native PipeWire node selection.
|
||||
Audio is routed through `pw-cat`, so any PipeWire source or sink can be targeted by name — no ALSA/PulseAudio compatibility layer needed.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.22+
|
||||
- PipeWire with `pw-cat` and `pw-dump` in `$PATH`
|
||||
- `libopus` and `libopusfile` (for the sendspin dependency)
|
||||
|
||||
**Build host** (dev packages, only needed to compile):
|
||||
```bash
|
||||
# Arch
|
||||
sudo pacman -S pipewire opus opusfile
|
||||
|
||||
# Debian/Ubuntu
|
||||
sudo apt install libopus-dev libopusfile-dev libasound2-dev
|
||||
```
|
||||
|
||||
**Raspberry Pi** (runtime only, no dev packages needed):
|
||||
```bash
|
||||
sudo apt install libopus0 libopusfile0 libasound2 pipewire
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
make # builds bin/sendspin-client and bin/sendspin-server (native)
|
||||
make rpi # cross-compiles for RPi via Docker → bin/*-armhf and bin/*-arm64
|
||||
make clean
|
||||
```
|
||||
|
||||
`make rpi` requires Docker. It builds a Debian image with ARM cross-compilers and the ARM versions of libopus/libasound, then copies the four binaries into `bin/`. No toolchain installation needed on the host.
|
||||
|
||||
## Usage
|
||||
|
||||
### Server
|
||||
|
||||
Captures audio from a PipeWire source node and streams it to connected clients.
|
||||
|
||||
```bash
|
||||
# List available capture sources
|
||||
./bin/sendspin-server --list-sources
|
||||
|
||||
# Stream from a specific source
|
||||
./bin/sendspin-server --source alsa_input.usb-JBL_Quantum810-00.pro-input-0
|
||||
|
||||
# Options
|
||||
./bin/sendspin-server --help
|
||||
-source string PipeWire source node name
|
||||
-port int listen port (default 8927)
|
||||
-name string server name (default "Sendspin Server")
|
||||
-rate int capture sample rate (default 48000)
|
||||
-channels int capture channels (default 2)
|
||||
```
|
||||
|
||||
### Client
|
||||
|
||||
Connects to a sendspin server and plays audio on a PipeWire sink.
|
||||
|
||||
```bash
|
||||
# List available playback sinks
|
||||
./bin/sendspin-client --list-devices
|
||||
|
||||
# Play on a specific sink (omit --device to use the system default)
|
||||
./bin/sendspin-client --server rpi.local:8927 --device alsa_output.usb-JBL_Quantum810-00.pro-output-0
|
||||
|
||||
# Options
|
||||
./bin/sendspin-client --help
|
||||
-server string server address (default "localhost:8927")
|
||||
-device string PipeWire sink node name (default: system default)
|
||||
-name string player name (default: hostname)
|
||||
-volume int initial volume 0-100 (default 80)
|
||||
```
|
||||
|
||||
## Running as a systemd user service
|
||||
|
||||
Example unit files are in [dist/systemd/](dist/systemd/). Both run as a **user** service so they have access to the PipeWire session without any special privileges.
|
||||
|
||||
```bash
|
||||
# 1. Copy the binary
|
||||
install -Dm755 bin/sendspin-client-arm64 ~/.local/bin/sendspin-client
|
||||
|
||||
# 2. Edit the unit file — set --server, --device, --name to your values
|
||||
cp dist/systemd/sendspin-client.service ~/.config/systemd/user/
|
||||
|
||||
# 3. Enable and start
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now sendspin-client
|
||||
|
||||
# Logs
|
||||
journalctl --user -u sendspin-client -f
|
||||
```
|
||||
|
||||
The unit files use `%H` (hostname) for `--name` and `%h` (home dir) for the binary path. Replace the placeholder `--device` / `--source` values — use `--list-devices` / `--list-sources` to find the right node name first.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
PipeWire source node
|
||||
│
|
||||
pw-cat --capture
|
||||
│ int32 PCM
|
||||
sendspin server ──── network ──── sendspin client
|
||||
│ int32 PCM
|
||||
pw-cat --playback
|
||||
│
|
||||
PipeWire sink node
|
||||
```
|
||||
|
||||
`internal/pipewire/source.go` wraps `pw-cat --capture` as an `AudioSource`.
|
||||
`internal/pipewire/output.go` wraps `pw-cat --playback` as an `Output`.
|
||||
`internal/pipewire/nodes.go` parses `pw-dump` JSON to enumerate nodes.
|
||||
Reference in New Issue
Block a user