diff --git a/crates/recording/src/feeds/microphone.rs b/crates/recording/src/feeds/microphone.rs index 6144e50df09..15a1004f81f 100644 --- a/crates/recording/src/feeds/microphone.rs +++ b/crates/recording/src/feeds/microphone.rs @@ -987,12 +987,31 @@ fn stream_config_with_latency( let buffer_size_frames = desired_buffer_size_frames(config, device_name); if let Some(frames) = buffer_size_frames { - stream_config.buffer_size = BufferSize::Fixed(frames); + if uses_pulse_backend(device_name) { + stream_config.buffer_size = BufferSize::Default; + } else { + stream_config.buffer_size = BufferSize::Fixed(frames); + } } (stream_config, buffer_size_frames) } +#[cfg(target_os = "linux")] +fn uses_pulse_backend(device_name: Option<&str>) -> bool { + device_name + .map(|n| { + let lower = n.to_ascii_lowercase(); + lower == "default" || lower == "pulse" || lower == "pipewire" + }) + .unwrap_or(false) +} + +#[cfg(not(target_os = "linux"))] +fn uses_pulse_backend(_device_name: Option<&str>) -> bool { + false +} + fn desired_buffer_size_frames( config: &SupportedStreamConfig, device_name: Option<&str>, diff --git a/crates/recording/src/sources/screen_capture/linux.rs b/crates/recording/src/sources/screen_capture/linux.rs index c141b08bf37..9cf8a0a4f36 100644 --- a/crates/recording/src/sources/screen_capture/linux.rs +++ b/crates/recording/src/sources/screen_capture/linux.rs @@ -941,6 +941,14 @@ fn select_system_audio_monitor() -> anyhow::Result { return Ok(selected); } + if !pactl_available() { + return Err(anyhow!( + "Linux system audio capture needs `pactl` to discover monitor sources, but it was not found on PATH. \ + Install it (e.g. `apt install pulseaudio-utils`, `dnf install pulseaudio-utils`, `pacman -S libpulse`) and try again. \ + Available cpal input devices: {available:?}." + )); + } + Err(anyhow!( "No PulseAudio/PipeWire monitor input was found for Linux system audio. \ Available input devices: {available:?}. Select a monitor source with --mic, or enable a monitor source in your audio server." @@ -1029,6 +1037,14 @@ fn pactl_monitor_rank(name: &str) -> Option { } } +fn pactl_available() -> bool { + Command::new("pactl") + .arg("--version") + .output() + .map(|o| o.status.success()) + .unwrap_or(false) +} + fn pactl_default_source() -> Option { let output = Command::new("pactl") .arg("get-default-source")