Fix virtual mic audio linking (#62)

* Fix virtual mic audio linking by managing it in AudioPlayer lifecycle

- Moved `link_player_to_virtual_mic` to `src/utils/pipewire.rs` and updated it to return a termination sender.
- Added `player_link_sender` to `AudioPlayer` to manage the PipeWire link between the daemon and the virtual mic.
- Integrated linking logic into `AudioPlayer::play` and `AudioPlayer::update` to ensure the link is established when audio starts playing.
- Ensured the link is terminated in `AudioPlayer::drop_stream` when the audio sink is closed.
- Removed redundant and potentially failing startup linking loop from the daemon.
- Fixed log spam by ensuring `link_player` is only attempted when necessary and errors are handled gracefully.
- Maintained compatibility with stable Rust by avoiding unstable features.

Co-authored-by: arabianq <55220741+arabianq@users.noreply.github.com>

* small refactor

* refactor

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
Tarasov Aleksandr
2026-04-17 14:24:58 +03:00
committed by GitHub
parent 5c4b8f4b45
commit 2a8fcca06b
5 changed files with 97 additions and 76 deletions
+38
View File
@@ -258,6 +258,44 @@ pub fn create_virtual_mic() -> Result<pipewire::channel::Sender<Terminate>, Box<
Ok(pw_sender)
}
pub async fn link_player_to_virtual_mic()
-> Result<pipewire::channel::Sender<Terminate>, Box<dyn Error>> {
let pwsp_daemon_output = match get_device("pwsp-daemon").await {
Ok(device) => device,
Err(_) => {
return Err(
"Could not find alsa_playback.pwsp-daemon device, skipping device linking".into(),
);
}
};
let pwsp_daemon_input = match get_device("pwsp-virtual-mic").await {
Ok(device) => device,
Err(_) => {
return Err("Could not find pwsp-virtual-mic device, skipping device linking".into());
}
};
let output_fl = match pwsp_daemon_output.output_fl {
Some(port) => port,
None => return Err("Failed to get pwsp-daemon output_fl".into()),
};
let output_fr = match pwsp_daemon_output.output_fr {
Some(port) => port,
None => return Err("Failed to get pwsp-daemon output_fr".into()),
};
let input_fl = match pwsp_daemon_input.input_fl {
Some(port) => port,
None => return Err("Failed to get pwsp-virtual-mic input_fl".into()),
};
let input_fr = match pwsp_daemon_input.input_fr {
Some(port) => port,
None => return Err("Failed to get pwsp-virtual-mic input_fr".into()),
};
create_link(output_fl, output_fr, input_fl, input_fr)
}
pub fn create_link(
output_fl: Port,
output_fr: Port,