fix: drop audio stream when idle to allow system suspend (#54)

* fix: drop audio stream when idle to allow system suspend

The daemon kept its ALSA playback stream open permanently, which
PipeWire reported as a running Stream/Output/Audio node even with
no tracks playing. This prevented desktop environments from detecting
idle state and entering suspend.

- Make the audio sink on-demand: created when playback starts,
  dropped when all tracks finish
- Reduce player loop polling from 100ms to 2s when idle
- Throttle PipeWire device enumeration to every ~5s while playing
- Log only first and last link retry attempt instead of all 60
This commit is contained in:
RiDDiX
2026-04-11 23:42:10 +02:00
committed by GitHub
parent 5a2418325d
commit cb56cb3a04
2 changed files with 65 additions and 29 deletions
+20 -10
View File
@@ -40,7 +40,11 @@ async fn main() -> Result<(), Box<dyn Error>> {
println!("Successfully linked player to virtual mic.");
break;
}
Err(e) => println!("{e}\t{i}/{max_retries}"),
Err(e) => {
if i == 0 || i == max_retries {
eprintln!("{e} (attempt {i}/{max_retries})");
}
}
}
sleep(Duration::from_millis(1000)).await;
@@ -174,19 +178,25 @@ async fn commands_loop(listener: UnixListener) -> Result<(), Box<dyn Error>> {
}
async fn player_loop() {
let mut device_check_counter: u32 = 0;
loop {
match get_audio_player().await {
let is_idle = match get_audio_player().await {
Ok(player_mutex) => {
let mut audio_player = player_mutex.lock().await;
audio_player.update().await;
let check_devices = device_check_counter == 0;
audio_player.update(check_devices).await;
audio_player.tracks.is_empty()
}
Err(_err) => {
// To avoid spamming logs every 100ms when audio player fails to init
// we can just sleep, or you might prefer to print the error.
// Assuming it failed to initialize, no player update is possible.
}
}
Err(_err) => true,
};
sleep(Duration::from_millis(100)).await;
if is_idle {
device_check_counter = 0;
sleep(Duration::from_secs(2)).await;
} else {
// Check devices every ~5 seconds (50 * 100ms) while playing
device_check_counter = (device_check_counter + 1) % 50;
sleep(Duration::from_millis(100)).await;
}
}
}