🎙️ Switch your default PulseAudio input device with a single click from the GNOME / KDE / Cinnamon system tray. Now powered by a small Rust backend and a Rust tray frontend — same UX as the original Python applet, but ~10× lighter on memory and CPU.
input-audio-monitord → HTTP+SSE daemon, wraps `pactl` (port 9127)
input-audio-monitor-tray → Linux system tray (ksni / SNI) (consumes the daemon)
The split is the same one used in gpu_monitor: a long-running backend that samples PulseAudio once a second, and a thin tray that subscribes to its SSE stream. A future remote frontend (web / mobile) can talk to the same HTTP API — see docs/api.md.
If you also want CPU / RAM / disk / GPU monitors in the same tray, the sibling repos follow the same pattern with different ports.
sudo apt install pulseaudio-utils # provides `pactl`
# Rust stable (rustup will install the toolchain pinned by rust-toolchain.toml)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shOn GNOME the AppIndicator and KStatusNotifierItem Support extension is required to render SNI tray icons.
git clone https://github.com/maximofn/input_audio_device.git
cd input_audio_device
cargo build --release --workspace./packaging/install.shInstalls:
~/.local/bin/input-audio-monitordand~/.local/bin/input-audio-monitor-tray~/.local/share/input-audio-monitor/microphone.png~/.config/systemd/user/input-audio-monitord.service(enabled + started)~/.config/autostart/input-audio-monitor-tray.desktop
The tray will auto-start on next login. To start it now without logging out:
nohup ~/.local/bin/input-audio-monitor-tray >/dev/null 2>&1 & disownThe Python script (legacy/input_audio_device.py) and its install helpers are kept under legacy/ for reference until the Rust version has been running clean for a release cycle. If the old autostart entry is still around from a previous install, remove it:
rm -f ~/.config/autostart/input_audio_device.sh.desktop# Backend on its own — useful for hacking on the API
cargo run -p input-audio-monitord -- --port 9127
# Tray pointing at the running backend
cargo run -p input-audio-monitor-tray -- --backend-url http://127.0.0.1:9127
# Backend without real PulseAudio (CI, containers)
cargo run -p input-audio-monitord -- --mockinput-audio-monitord:
| flag | env var | default |
|---|---|---|
--bind |
INPUT_AUDIO_MONITORD_BIND |
127.0.0.1 |
--port |
INPUT_AUDIO_MONITORD_PORT |
9127 |
--sample-interval-ms |
INPUT_AUDIO_MONITORD_SAMPLE_INTERVAL_MS |
1000 |
--mock |
INPUT_AUDIO_MONITORD_MOCK |
false |
--log-level |
RUST_LOG |
info |
input-audio-monitor-tray:
| flag | env var | default |
|---|---|---|
--backend-url |
INPUT_AUDIO_MONITOR_TRAY_URL |
http://127.0.0.1:9127 |
--hide-monitors |
INPUT_AUDIO_MONITOR_TRAY_HIDE_MONITORS |
false |
--log-level |
RUST_LOG |
info |
--hide-monitors filters out PulseAudio *.monitor sources (which capture the output of a sink) from the menu.
The daemon is a systemd user unit; reload it with:
cargo build --release --workspace
install -m 0755 target/release/input-audio-monitord ~/.local/bin/
systemctl --user restart input-audio-monitordThe tray is not a systemd unit (it needs the graphical session). Replace the binary and respawn it manually:
install -m 0755 target/release/input-audio-monitor-tray ~/.local/bin/
pkill -f "$HOME/.local/bin/input-audio-monitor-tray$"
nohup ~/.local/bin/input-audio-monitor-tray >/dev/null 2>&1 & disown(Do not use pkill -x input-audio-monitor-tray — the kernel truncates comm to 15 chars and the binary name is 24, so the exact match misses.)
Same architecture, different resource:
gpu_monitor— NVIDIA GPU temperature / memory / processes (port 9123)cpu_monitor,ram_monitor,disk_monitor— planned (ports 9124 / 9125 / 9126)
If this is useful to you, a ☆ Star is appreciated.
