Platform-Specific Audio Capture in Meetily: WASAPI, ScreenCaptureKit, and ALSA Implementations

Meetily implements audio capture through a modular Rust architecture that abstracts native OS APIs—using WASAPI on Windows, ScreenCaptureKit on macOS, and ALSA/PulseAudio on Linux—exposing a uniform AudioDevice interface regardless of platform.

Meetily is an open-source meeting transcription application developed by Zackriya-Solutions that processes audio locally for privacy. According to the source code in frontend/src-tauri/src/audio/devices/, the application leverages conditional compilation to provide高性能, low-latency recording across all three major desktop platforms while maintaining a consistent API for the transcription pipeline.

Windows Audio Capture with WASAPI

On Windows, Meetily utilizes the Windows Audio Session API (WASAPI) to enumerate input devices and capture system audio. The platform-specific logic resides in [frontend/src-tauri/src/audio/devices/platform/windows.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/windows.rs).

The configure_windows_audio() function enumerates all available input and output devices through the WASAPI host. For system audio capture, the implementation leverages WASAPI loopback capabilities, allowing the application to record audio output from other applications without requiring stereo mix drivers. When a user selects a specific device, get_windows_device() resolves the selection into a (cpal::Device, cpal::SupportedStreamConfig) tuple that the audio pipeline consumes.

use crate::audio::devices::platform::get_windows_device;
use crate::audio::devices::configuration::AudioDevice;

fn open_windows_device(selected: &AudioDevice) -> anyhow::Result<(cpal::Device, cpal::SupportedStreamConfig)> {
    // Resolve the CPAL device and a compatible config
    get_windows_device(selected)
}

macOS Audio Capture with ScreenCaptureKit and CoreAudio

The macOS implementation in [frontend/src-tauri/src/audio/devices/platform/macos.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/macos.rs) combines ScreenCaptureKit for system audio and CoreAudio for microphone input.

The configure_macos_audio() function uses CPAL's default host to enumerate microphone inputs while filtering built-in speakers from the output device list. ScreenCaptureKit handles the privileged system audio capture required for recording meeting audio from other applications, ensuring compliance with macOS privacy requirements while maintaining low-latency audio quality for transcription.

Linux Audio Capture with ALSA and PulseAudio

Linux support in [frontend/src-tauri/src/audio/devices/platform/linux.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/linux.rs) targets ALSA (Advanced Linux Sound Architecture) and PulseAudio monitor sources.

The configure_linux_audio() function gathers microphone inputs through the default host and specifically identifies PulseAudio monitor sources (devices containing the "monitor" keyword) to enable system audio recording. This approach captures the PulseAudio sink monitor without requiring kernel-level ALSA configuration changes, providing reliable access to system-wide audio on most Linux distributions.

The Unified Device Discovery Interface

All platform modules are conditionally compiled and re-exported through [frontend/src-tauri/src/audio/devices/platform/mod.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/mod.rs), enabling the rest of the application to work with a uniform device structure regardless of the underlying OS.

The entry point list_audio_devices() in [frontend/src-tauri/src/audio/devices/discovery.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/discovery.rs) asynchronously creates a cpal::Host and delegates to the appropriate platform helper—configure_windows_audio(), configure_macos_audio(), or configure_linux_audio()—based on the target_os compilation flag.

// In a Tauri command or any async context
use crate::audio::devices::discovery::list_audio_devices;

#[tauri::command]
async fn get_available_devices() -> Result<Vec<AudioDevice>, String> {
    list_audio_devices()
        .await
        .map_err(|e| format!("Failed to list audio devices: {}", e))
}

For permission handling, trigger_audio_permission() constructs a short-lived input stream to provoke the OS permission dialog on macOS and Windows, ensuring user consent before recording begins.

use crate::audio::devices::discovery::trigger_audio_permission;

#[tauri::command]
fn request_audio_permission() -> Result<bool, String> {
    trigger_audio_permission()
        .map_err(|e| format!("Permission request failed: {}", e))
}

Integrating Platform Audio into the Transcription Pipeline

Once a device is selected, platform-specific resolvers (currently only get_windows_device() for Windows) return a (cpal::Device, cpal::SupportedStreamConfig) tuple. [frontend/src-tauri/src/audio/pipeline.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs) consumes these streams, applies Voice Activity Detection (VAD), mixes microphone and system audio, and forwards the speech-only stream to the Whisper backend.

let device = /* obtained from platform helper */;
let config = /* chosen SupportedStreamConfig */;

let stream = device.build_input_stream(
    &config.clone().into(),
    move |data: &[f32], _: &cpal::InputCallbackInfo| {
        // Forward raw PCM to the pipeline for mixing/VAD
        audio_pipeline.process_mic_chunk(data);
    },
    |err| eprintln!("Audio stream error: {}", err),
    None,
)?;
stream.play()?; // Begins capturing

Because the code relies on the cross-platform cpal crate, the platform modules only need to handle OS-specific quirks—such as WASAPI loopback, PulseAudio monitors, or ScreenCaptureKit privileges—while the higher-level audio logic remains portable.

Summary

  • Windows uses WASAPI via configure_windows_audio() and get_windows_device() in platform/windows.rs to enumerate devices and support loopback recording.
  • macOS combines ScreenCaptureKit for system audio with CoreAudio for microphones via configure_macos_audio() in platform/macos.rs.
  • Linux leverages ALSA and PulseAudio monitor sources via configure_linux_audio() in platform/linux.rs to capture both microphone and system audio.
  • Abstraction occurs through platform/mod.rs conditional compilation and the discovery.rs module, which exposes list_audio_devices() and trigger_audio_permission().
  • Pipeline integration happens in pipeline.rs, which receives raw audio from the platform layer, applies VAD filtering, and forwards speech data to the Whisper transcription engine.

Frequently Asked Questions

How does Meetily capture system audio on Windows without requiring stereo mix drivers?

Meetily uses the WASAPI loopback capability available in platform/windows.rs. The configure_windows_audio() function accesses the WASAPI host to enumerate loopback-capable output devices, allowing direct recording of system audio output without relying on legacy stereo mix drivers or virtual audio cables.

What is the role of ScreenCaptureKit in Meetily's macOS implementation?

ScreenCaptureKit handles privileged system audio capture on macOS, enabling Meetily to record audio from other applications while complying with macOS privacy requirements. The configure_macos_audio() function in platform/macos.rs uses ScreenCaptureKit for system audio alongside CoreAudio for microphone input, filtering built-in speakers from the output list to avoid feedback loops.

Why does Meetily specifically identify PulseAudio "monitor" sources on Linux?

PulseAudio monitor sources represent sink monitors that allow applications to capture the audio being played through a specific output device. In platform/linux.rs, the configure_linux_audio() function identifies these sources by the "monitor" keyword to enable system audio recording without requiring kernel-level ALSA configuration or additional user privileges.

How does Meetily abstract different native audio APIs into a single cross-platform interface?

Meetily uses conditional compilation in platform/mod.rs to re-export only the current platform's module, while discovery.rs provides a unified list_audio_devices() async function. This architecture allows the transcription pipeline in pipeline.rs to work with a standard AudioDevice struct and cpal::Device objects regardless of whether the underlying implementation uses WASAPI, ScreenCaptureKit, or ALSA.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →