Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
flexaudio
Flexible, cross-platform audio capture for Rust. Capture from microphones, system output (loopback), individual processes, and microphone + system mix on Linux, Windows, and macOS through one unified API.
use ;
let mut stream = open?;
stream.start?;
while let Some = stream.poll_chunk
stream.stop;
# Ok::
Capability matrix
| Source | Linux | Windows | macOS |
|---|---|---|---|
| Microphone | ✅ cpal/ALSA | ✅ cpal/WASAPI | ✅ cpal/CoreAudio |
| System output | ✅ PipeWire | ✅ WASAPI loopback | ✅ CoreAudio taps |
| Per-process | ✅ PipeWire | ✅ WASAPI process | ✅ CoreAudio taps |
Highlights
open(StreamConfig)selects the right backend by source + OS.Stream::poll_chunk/poll_event— simple pull loop; no callbacks required.Stream::switch_source— hot-swap source without stopping the stream.devices()enumerates devices;watch_devices()reports Linux PipeWire system output additions, removals and default changes using the same output IDs asdevices(). Microphone and default-microphone changes are not reported: CPAL microphone IDs cannot be resolved from PipeWire nodes. Windows/macOS return a no-op watcher. Discovery returns a complete inventory or an error, including when PipeWire is unavailable. Linux microphone entries use only CPAL device-name IDs; PipeWire source-node IDs are omitted because the microphone backend cannot open them.processes()lists audio output session/stream owners on Linux/Windows and Core Audio processes on macOS, including input-only processes. Idle/stopped processes are included and the caller is excluded; usepidastarget_pidfor capture andis_output_activeto check current playback.SourceKind::Mixcombines mic + system audio. Select each side withmix_mic_device_id/mix_system_device_id(Noneuses defaults), and setmix_mic_gain/mix_system_gainbefore mixing;gainapplies afterward.device_idis ignored for Mix.exclude_pidscombines withexclude_selffor system capture and the system side of Mix. Windows excludes one process-tree root (self whenexclude_selfis true, otherwise the first PID); every entry must equal that root, and distinct PIDs are rejected. macOS resolves audio objects once at start and honors device selection. Linux matches exact PIDs (application.process.idfor pulse-proxied streams,pipewire.sec.pidfor native clients), without descendants. Linux and Windows ignore system-device selection during exclusion.- Output is normalized interleaved
f32at a sample rate / channel count you choose (two-stage resampling internally).
Capability discovery
capabilities() returns a read-only snapshot of source backends and availability,
OS version when known, PID/exclusion scopes and limits, output-device selection
semantics, watcher support, and optional rendering side effects. It opens no
capture or render streams, enumerates no microphones, requests no recording
permission, and plays no audio.
let support = capabilities;
println!;
println!;
Availability::Supported describes backend prerequisites, not permission or a
usable device. Availability::Unknown { error } retains a typed prerequisite
query failure; do not assume support or confirmed unavailability. On Linux,
missing PipeWire sockets are unavailable; failed socket inspection, connection
or server sync is unknown. The bounded query can wait for the audio service;
run it on a worker thread in GUI applications.
Capture open options
Use open_with_options to select optional backend behavior without changing
StreamConfig. Existing open calls keep the default behavior.
use ;
let config = StreamConfig ;
let mut stream = open_with_options?;
stream.start?;
stream.switch_source_with_options?;
stream.stop;
# Ok::
Windows classic loopback keepalive is enabled by default and renders silence to
keep idle system capture delivering packets. It also applies to the system lane
of Mix without PID exclusions. Other platforms and process/exclusion paths ignore
it. Disabling it means idle classic loopback delivers no packets: the 2 s watchdog
reports Event::StreamStalled and reopens repeatedly until audio plays.
Stream::open_options() reads the current settings. switch_source_with_options
replaces them together with the source; ordinary switch_source retains them.
Construction/startup failures retain the previous settings.
Install
Permissions
Audio capture requires user consent: macOS TCC (kTCCServiceAudioCapture, add
NSAudioCaptureUsageDescription to Info.plist), the Windows Microphone privacy
setting, and a running PipeWire session on Linux for system/process capture. See
the workspace README.
On macOS, system/process loopback (Core Audio process taps) requires macOS 14.4 or later.
MSRV
Rust 1.85.
License
MIT © 2026 tubome / Studio Sadola. Third-party notices:
THIRD_PARTY_NOTICES.md.