1
0
Fork 0
mirror of https://github.com/badaix/snapcast synced 2025-09-08 11:02:33 +02:00
snapcast/doc/pipewire-stream.md
2025-08-28 20:51:03 +02:00

153 lines
4.6 KiB
Markdown

# PipeWire Stream Usage Guide for Snapcast
## Overview
This implementation adds native PipeWire support to Snapcast server, allowing direct audio capture from PipeWire without going through ALSA or JACK compatibility layers.
It is the solution to [issue 1371](https://github.com/badaix/snapcast/issues/1371).
## Building with PipeWire Support
1. Ensure PipeWire development packages are installed:
```bash
# Fedora/RHEL
sudo dnf install pipewire-devel
# Ubuntu/Debian
sudo apt install libpipewire-0.3-dev
```
2. Build Snapcast with PipeWire support:
```bash
cmake .. -DBUILD_WITH_PIPEWIRE=ON
make
```
## Usage
### Basic Usage
In your `snapserver.conf`, add a PipeWire stream:
```ini
[stream]
source = pipewire://?name=Snapcast&device=&auto_connect=true
```
### URI Parameters
- `name`: The name of the PipeWire stream (default: "Snapcast")
- `target`: Target device/node to connect to (default: empty, auto-selects)
- `capture_sink`: Capture from sink outputs instead of sources (default: false)
- `send_silence`: Send silent chunks when idle (default: false)
- `idle_threshold`: Duration of silence before switching to idle state in ms (default: 100)
### Examples
1. **Capture from default source:**
```ini
source = pipewire://?name=<your_stream_name>
```
2. **Capture from specific application/device:**
```ini
source = pipewire://?name=<your_stream_name>&target=Firefox
```
3. **Capture sink output (like pw-record with stream.capture.sink=true):**
```ini
source = pipewire://?name=<your_stream_name>&capture_sink=true&target=alsa_output.platform-snd_aloop.0.analog-stereo
```
4. **Named stream with custom idle settings:**
```ini
source = pipewire://?name=SnapcastCapture&idle_threshold=500&send_silence=true
```
## PipeWire Graph Management
You can use PipeWire tools to manage connections:
```bash
# List all nodes
pw-cli list-objects Node
# View the PipeWire graph
pw-dot
qpwgraph # GUI tool
# Connect manually if auto_connect=false
pw-link "Snapcast:input_FL" "Firefox:output_FL"
pw-link "Snapcast:input_FR" "Firefox:output_FR"
```
Pulseaudio clients like the `pavucontrol` UI can also be used.
## Key Differences from ALSA Implementation
1. **Callback-based**: PipeWire uses callbacks instead of polling
2. **Graph-based**: Audio routing is handled through the PipeWire graph
3. **Lower latency**: Direct PipeWire integration can provide lower latency
4. **Better integration**: Works seamlessly with PipeWire's session management
## Troubleshooting
1. **No audio captured**: Check PipeWire connections with `pw-link -l`
2. **Permission issues**: Ensure your user is in the `audio` group
3. **High CPU usage**: Adjust buffer sizes in PipeWire configuration
## Replacing pw-record
If you're currently using pw-record to capture audio into a FIFO, like:
```bash
pw-record -P stream.capture.sink=true --target alsa_output.platform-snd_aloop.0.analog-stereo - >/tmp/snapfifo
```
You can replace it with a native PipeWire stream in snapserver:
```ini
source = pipewire://?capture_sink=true&target=alsa_output.platform-snd_aloop.0.analog-stereo
```
This eliminates the need for FIFOs and external processes, providing better performance and lower latency.
## Using with sound loopback devices
It is possible (but not needed) to use pipewire-stream with sound loopback.
Load the loopback module temporarily with:
```bash
sudo modprobe snd-aloop
```
Or permanently by creating a file `/etc/modules-load.d/snd_aloop.conf` like this:
```bash
$ cat /etc/modules-load.d/snd_aloop.conf
snd_aloop
```
## Alternative: Use the `libpipewire-module-snapcast-discover` from PipeWire
An alternative to using the `pipewire-stream` source in Snapcast is to use the `libpipewire-module-snapcast-discover` module from PipeWire. This module allows PipeWire clients to automatically discover and connect to snapserver.
For details, see the [PipeWire documentation](https://docs.pipewire.org/page_module_snapcast_discover.html)
and [issue 1371](https://github.com/badaix/snapcast/issues/1371).
Using `libpipewire-module-snapcast-discover` allows for discover snapserver on the (sub) network.
Using pipewire-stream is more direct, avoids loopback networking, but is restricted to snapserver on the local machine. It is - of course - better integrated with PipeWire and may feel more naturally because of that.
## Acknowledgements
Research for this implementation was done with perplexity AI. Most of the inital code was written by Claude Code AI, including this documentation.
However, all tests, prompt directions, and the initial PR were done by [aanno](https://github.com/aanno).