diff --git a/src/platform/linux.rs b/src/platform/linux.rs index beed657d3..b739e1b82 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -1550,6 +1550,9 @@ where } pub fn get_pa_monitor() -> String { + if let Some(monitor) = get_default_pa_monitor() { + return monitor; + } get_pa_sources() .drain(..) .map(|x| x.0) @@ -1558,6 +1561,49 @@ pub fn get_pa_monitor() -> String { .unwrap_or("".to_owned()) } +// The first monitor in the source list can belong to an output the desktop does not play to. +fn get_default_pa_monitor() -> Option { + use pulsectl::controllers::*; + // The audio service retries about every second while PulseAudio is unavailable. + const LOG_INTERVAL: std::time::Duration = std::time::Duration::from_secs(60); + let mut handler = SinkController::create() + .map_err(|err| { + hbb_common::throttled_log!( + LOG_INTERVAL, + warn, + "Failed to create SinkController: {:?}", + err + ) + }) + .ok()?; + let sink = handler + .get_server_info() + .map_err(|err| { + hbb_common::throttled_log!( + LOG_INTERVAL, + warn, + "Failed to get the PulseAudio server info: {:?}", + err + ) + }) + .ok()? + .default_sink_name?; + handler + .get_device_by_name(&sink) + .map_err(|err| { + hbb_common::throttled_log!( + LOG_INTERVAL, + warn, + "Failed to get the default sink {}: {:?}", + sink, + err + ) + }) + .ok()? + .monitor_name + .filter(|name| !name.is_empty()) +} + pub fn get_pa_source_name(desc: &str) -> String { get_pa_sources() .drain(..)