# How to Set Up System Audio Capture with Virtual Audio Devices in Meetily

> Learn to set up system audio capture in Meetily using virtual audio devices. This guide covers BlackHole on macOS and WASAPI loopback on Windows for seamless audio integration.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-17

---

**Meetily captures system audio using platform-specific virtual audio devices—BlackHole on macOS via ScreenCaptureKit and WASAPI loopback on Windows—through Tauri commands implemented in `frontend/src-tauri/src/audio/`.**

Setting up system audio capture with virtual audio devices like BlackHole or WASAPI loopback enables Meetily to record both microphone input and system output simultaneously. The open-source repository Zackriya-Solutions/meetily implements this functionality through a Rust-based Tauri backend that abstracts macOS ScreenCaptureKit and Windows WASAPI APIs into unified recording commands.

## Architecture Overview

The audio capture system resides in `frontend/src-tauri/src/audio/` and consists of three primary components that handle cross-platform system audio detection and streaming.

- **[`system_detector.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_detector.rs)**: Detects the current operating system and selects the appropriate capture implementation for macOS or Windows.
- **[`system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_stream.rs)**: Opens platform-specific audio streams using ScreenCaptureKit on macOS or WASAPI loopback mode on Windows.
- **[`system_audio_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_commands.rs)**: Exposes Tauri commands that the frontend invokes to start and stop system audio capture.

## macOS: Configure BlackHole for System Audio

macOS requires a virtual audio device to capture system output because the platform does not expose internal audio mixing to applications directly.

### Install BlackHole

Install the BlackHole virtual audio driver using Homebrew to create a software audio device that routes system output back into Meetily.

```bash
brew install blackhole-2ch

```

This creates the **BlackHole 2ch** device that appears in audio settings as a valid input source.

### Configure Aggregate Devices

Create an aggregate device in Audio MIDI Setup to combine your microphone and the BlackHole virtual device, ensuring synchronized capture of both sources.

1. Open **Audio MIDI Setup** and click the **+** button.
2. Select **Create Aggregate Device**.
3. Check both **Built-in Microphone** and **BlackHole 2ch**.
4. Set this aggregate device as the default input to capture both microphone and system audio simultaneously.

### Grant macOS Permissions

ScreenCaptureKit requires explicit user permissions. The application requests **Microphone** and **Screen Recording** permissions on first launch, or you can prompt them programmatically:

```rust
// src-tauri/src/utils.rs
open_system_settings("Privacy_Microphone".to_string());
open_system_settings("Privacy_ScreenCapture".to_string());

```

Navigate to **System Settings → Privacy & Security → Screen Recording** to manually enable Meetily if permissions were previously denied.

### Select Devices in Meetily

Open **Settings → Audio** in the Meetily interface and configure:

- **System Audio**: Select **BlackHole 2ch**
- **Microphone**: Select your physical microphone or the aggregate device

## Windows: Configure WASAPI Loopback

Windows provides direct access to the audio mix through WASAPI loopback mode without requiring third-party virtual drivers.

### Enable Stereo Mix

Ensure the WASAPI loopback device is visible in your recording devices.

1. Right-click the speaker icon in the system tray and select **Sounds**.
2. Navigate to the **Recording** tab.
3. Right-click in the device list and select **Show Disabled Devices**.
4. Enable **Stereo Mix** or the equivalent loopback device.

### Select Loopback Device in Meetily

In **Settings → Audio**, choose the loopback entry (labeled as `Loopback (Stereo Mix)` or `WASAPI Loopback`) as the **System Audio** source, and select your physical microphone as the **Mic** device.

## Technical Implementation

The Rust backend handles platform detection and stream initialization through conditional compilation and platform-specific APIs.

### Device Detection Logic

The [`system_detector.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_detector.rs) file determines the operating system at runtime and routes to the appropriate capture implementation.

### Stream Initialization

The [`system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_stream.rs) file contains the platform-specific logic to open audio streams. On macOS, it interfaces with ScreenCaptureKit to capture the BlackHole device; on Windows, it utilizes WASAPI loopback mode.

### Command Interface

The [`system_audio_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_commands.rs) file defines the Tauri command interface that the frontend invokes. The `start_system_capture` function receives the device name and initializes the stream:

```rust
// frontend/src-tauri/src/audio/system_audio_commands.rs
#[tauri::command]
pub async fn start_system_capture(
    app: AppHandle,
    device_name: Option<String>,
) -> Result<(), String> {
    let name = device_name.ok_or("System device not supplied")?;
    let stream = system_audio_stream::open(&name).await?;
    // Store the stream handle in the recording manager
    Ok(())
}

```

### Frontend Integration

The TypeScript frontend calls the `start_recording` command with device parameters:

```typescript
// src/app/page.tsx
import { invoke } from '@tauri-apps/api/tauri';

export async function beginRecording() {
  await invoke('start_recording', {
    mic_device_name: 'Built-in Microphone',
    system_device_name: 'BlackHole 2ch',  // macOS
    // system_device_name: 'Loopback (Stereo Mix)',  // Windows
    meeting_name: 'Team Standup',
  });
}

```

The React UI implements device selection using standard form controls:

```tsx
// src/components/AudioSettings.tsx
<select
  value={systemDevice}
  onChange={e => setSystemDevice(e.target.value)}
>
  {systemDevices.map(dev => (
    <option key={dev.id} value={dev.name}>{dev.name}</option>
  ))}
</select>

```

## Troubleshooting Common Issues

**No system audio options appear in settings**
- **macOS**: BlackHole is not installed. Run `brew install blackhole-2ch` and restart the application.
- **Windows**: Stereo Mix is disabled. Open Sound settings and enable the loopback device in the Recording tab.

**Permissions error on macOS**
- Missing Screen Recording permission. Open **System Settings → Privacy & Security → Screen Recording** and enable Meetily, then restart the application.

**Audio latency or echo**
- On macOS, using separate mic and system devices without an aggregate device causes sync issues. Create an Aggregate Device in Audio MIDI Setup combining both sources.

**Whisper receives silence**
- The system audio stream failed to open. Verify that the selected system device matches the active output (BlackHole on macOS or Stereo Mix on Windows) and that the device is not muted.

## Summary

- **Meetily** captures system audio on macOS using **BlackHole** virtual devices with ScreenCaptureKit, and on Windows using **WASAPI loopback** mode.
- The Rust backend in `frontend/src-tauri/src/audio/` provides cross-platform abstraction through [`system_detector.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_detector.rs), [`system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_stream.rs), and [`system_audio_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_commands.rs).
- macOS requires installing BlackHole via Homebrew and optionally creating aggregate devices, while Windows only requires enabling the Stereo Mix device.
- Frontend TypeScript code invokes `start_recording` with specific device names to initiate capture through the Tauri command layer.

## Frequently Asked Questions

### Do I need a virtual audio cable on Windows?

No. Windows exposes the system audio mix through WASAPI loopback mode, which Meetily accesses directly without requiring third-party virtual cables. Simply enable the **Stereo Mix** device in your sound settings and select it as the system audio source in Meetily.

### Why does Meetily require Screen Recording permission on macOS?

macOS **ScreenCaptureKit** requires Screen Recording permission to capture audio from the system, even when only capturing audio without video. This is a platform security requirement. The permission is requested when you first attempt to record system audio, and can be managed in **System Settings → Privacy & Security → Screen Recording**.

### Can I use a different virtual audio device instead of BlackHole on macOS?

Yes. While the documentation references BlackHole 2ch as the default, any macOS virtual audio device that presents itself as a standard input source will work with Meetily. Ensure the device appears in **Audio MIDI Setup** and is selected in the application's audio settings. The [`system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_stream.rs) implementation uses standard CoreAudio APIs that support any compatible virtual device.

### How do I troubleshoot when the system audio stream fails to initialize?

First, verify that your selected device name exactly matches the device name shown in system settings. Check the application logs for errors from [`system_audio_commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_commands.rs) indicating "System device not supplied" or stream open failures. On macOS, confirm BlackHole is installed with `brew list blackhole-2ch`. On Windows, ensure the Stereo Mix device is enabled and not set to "Listen to this device" in its properties, as this can create conflicts with WASAPI loopback capture.