Fix HDMI audio after suspend/resume on PipeWire + WirePlumber
Project description
aproman
Fix HDMI audio after suspend/resume on Linux systems running PipeWire + WirePlumber.
The Problem
When a Linux system resumes from suspend, HDMI audio devices often lose their
connection. WirePlumber tries to link to stale node proxies, resulting in
silence. The only manual fix is to open your audio settings and switch the card
profile away (for example to off) and back, forcing a full teardown and
rebuild of the audio nodes.
How It Works
aproman runs as a user systemd service and:
- Auto-detects your HDMI audio card, or accepts one via
--card - Monitors D-Bus for
PrepareForSleepsignals from systemd-logind - On wake, waits briefly for HDMI to renegotiate, then cycles the card profile off and back on
This forces PipeWire and WirePlumber to rebuild fresh nodes, restoring audio without manual intervention.
Requirements
- PipeWire with WirePlumber, or PulseAudio compatibility via PipeWire
pactldbus-monitorsystemctl- A systemd-based Linux distribution
Installation
Recommended: uv
uv tool install aproman
This installs aproman to ~/.local/bin/.
Then install and start the systemd service:
git clone https://github.com/mwolson/aproman.git
cd aproman
mkdir -p ~/.config/systemd/user
cp systemd/aproman.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now aproman.service
Alternative: install.sh
git clone https://github.com/mwolson/aproman.git
cd aproman
./install.sh
systemctl --user start aproman.service
This copies aproman to ~/.local/bin/ and installs and enables the user
service.
Usage
The service runs automatically. To check status:
systemctl --user status aproman.service
journalctl --user -u aproman.service -f
Command-Line Options
You can customize behavior by editing the ExecStart line in the service file:
--card CARD_NAME PipeWire/PulseAudio card name (default: auto-detect HDMI card)
--profile PROFILE Desired audio profile (default: active profile on startup)
--wake-delay SECONDS Seconds to wait after wake before cycling (default: 3.0)
To find your card name:
pactl list cards short
Example: Custom Card and Profile
Edit ~/.config/systemd/user/aproman.service:
ExecStart=%h/.local/bin/aproman --card alsa_card.pci-0000_01_00.1 --profile output:hdmi-stereo
Then reload and restart:
systemctl --user daemon-reload
systemctl --user restart aproman.service
Uninstall
systemctl --user disable --now aproman.service
uv tool uninstall aproman # or: rm ~/.local/bin/aproman
rm ~/.config/systemd/user/aproman.service
systemctl --user daemon-reload
Testing
python3 -m unittest discover -s tests -v
Hooks
lefthook install
lefthook run pre-commit --all-files
The pre-commit hook runs uvx ruff check, uvx ty check, and the unit test
suite.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aproman-0.1.1.tar.gz.
File metadata
- Download URL: aproman-0.1.1.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc581fcb91c304ea67d8c6b6f49fa6f05d62d73cbd5364ba0cc2e8016502bc33
|
|
| MD5 |
89a1f54e09c7367e9eacab3f540ba8e7
|
|
| BLAKE2b-256 |
75aab8f79c7b73d5ffc72d998662ee3d9d77b6dd75aec5138e46dcf4824c31ad
|
Provenance
The following attestation bundles were made for aproman-0.1.1.tar.gz:
Publisher:
publish.yml on mwolson/aproman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aproman-0.1.1.tar.gz -
Subject digest:
dc581fcb91c304ea67d8c6b6f49fa6f05d62d73cbd5364ba0cc2e8016502bc33 - Sigstore transparency entry: 1208777968
- Sigstore integration time:
-
Permalink:
mwolson/aproman@9b896beccf72cb2c7b7246988207b70b783a274d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/mwolson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9b896beccf72cb2c7b7246988207b70b783a274d -
Trigger Event:
push
-
Statement type:
File details
Details for the file aproman-0.1.1-py3-none-any.whl.
File metadata
- Download URL: aproman-0.1.1-py3-none-any.whl
- Upload date:
- Size: 5.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a068e24a5857bfc92115af540a26d68ff7d9fc4a9f86aca2478f9512da69e344
|
|
| MD5 |
e48d8a8bada79beb404d5391a789e549
|
|
| BLAKE2b-256 |
56931a0e2daf883bb3d63b0fe4ad8a77afcdfea6da86823ce712ae3e25b8db2b
|
Provenance
The following attestation bundles were made for aproman-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on mwolson/aproman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aproman-0.1.1-py3-none-any.whl -
Subject digest:
a068e24a5857bfc92115af540a26d68ff7d9fc4a9f86aca2478f9512da69e344 - Sigstore transparency entry: 1208777987
- Sigstore integration time:
-
Permalink:
mwolson/aproman@9b896beccf72cb2c7b7246988207b70b783a274d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/mwolson
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9b896beccf72cb2c7b7246988207b70b783a274d -
Trigger Event:
push
-
Statement type: