pulsectl
raw JSON → 24.12.0 verified Mon Apr 27 auth: no python
Python high-level interface and ctypes-based bindings for PulseAudio (libpulse). Version 24.12.0 provides an object-oriented wrapper for controlling PulseAudio volume, sinks, sources, and more.
pip install pulsectl Common errors
error pulsectl.PulseError: Failed to create mainloop: No such file or directory ↓
cause PulseAudio server not running or socket not accessible.
fix
Start PulseAudio with 'pulseaudio --start' or set PULSE_SERVER environment variable.
error AttributeError: module 'pulsectl' has no attribute 'Pulse' ↓
cause Installed old version (<3.0) or import of wrong module.
fix
Run 'pip install --upgrade pulsectl' and use 'from pulsectl import Pulse'.
error pulsectl.PulseError: Connection refused ↓
cause PulseAudio native protocol socket is not listening (e.g., in container without shared socket).
fix
Forward PulseAudio socket with '-v /run/user/$(id -u)/pulse:/run/user/$(id -u)/pulse' or set PULSE_SERVER=tcp:host:port.
Warnings
breaking in version 24.12.0, the 'Pulse' context manager no longer uses pulseaudio server string; removed deprecated 'connect_to_server' method. ↓
fix Use Pulse('app-name') with PulseAudio autodetection. Do not pass server string.
deprecated The 'sink_input_set_volume' method is deprecated; use 'volume_set_all_chans' on sink input objects. ↓
fix Replace pulse.sink_input_set_volume(index, volume) with pulse.volume_set_all_chans(sink_input, volume).
gotcha Running without a running PulseAudio server or inside a Docker container will raise a PulseError. ↓
fix Ensure PulseAudio is running (pulseaudio --start) or handle PulseError gracefully.
gotcha Volume values are floats between 0.0 and 1.0 (or greater for pa_volume_t range), not percentages or decibels. ↓
fix Use values in [0.0, 1.0] scale, e.g., 0.5 for 50% volume.
Imports
- Pulse
from pulsectl import Pulse - PulseVolumeInfo
from pulsectl import PulseVolumeInfo
Quickstart
from pulsectl import Pulse
with Pulse('my-app') as pulse:
sink_list = pulse.sink_list()
for sink in sink_list:
print(sink.description, sink.volume)
# Set volume of first sink
if sink_list:
pulse.volume_set_all_chans(sink_list[0], 0.5)