4.6 KiB
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.
Building with PipeWire Support
-
Ensure PipeWire development packages are installed:
# Fedora/RHEL sudo dnf install pipewire-devel # Ubuntu/Debian sudo apt install libpipewire-0.3-dev
-
Build Snapcast with PipeWire support:
cmake .. -DBUILD_WITH_PIPEWIRE=ON make
Usage
Basic Usage
In your snapserver.conf
, add a PipeWire stream:
[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
-
Capture from default source:
source = pipewire://?name=<your_stream_name>
-
Capture from specific application/device:
source = pipewire://?name=<your_stream_name>&target=Firefox
-
Capture sink output (like pw-record with stream.capture.sink=true):
source = pipewire://?name=<your_stream_name>&capture_sink=true&target=alsa_output.platform-snd_aloop.0.analog-stereo
-
Named stream with custom idle settings:
source = pipewire://?name=SnapcastCapture&idle_threshold=500&send_silence=true
PipeWire Graph Management
You can use PipeWire tools to manage connections:
# 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
- Callback-based: PipeWire uses callbacks instead of polling
- Graph-based: Audio routing is handled through the PipeWire graph
- Lower latency: Direct PipeWire integration can provide lower latency
- Better integration: Works seamlessly with PipeWire's session management
Troubleshooting
- No audio captured: Check PipeWire connections with
pw-link -l
- Permission issues: Ensure your user is in the
audio
group - 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:
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:
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:
sudo modprobe snd-aloop
Or permanently by creating a file /etc/modules-load.d/snd_aloop.conf
like this:
$ 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 and issue 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.