# How Meetily Captures System Audio on macOS Using ScreenCaptureKit

> Learn how Meetily captures pristine macOS system audio: discover its use of ScreenCaptureKit and CPAL for seamless real-time audio integration, bypassing Bluetooth processing.

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

---

**Meetily leverages Apple's ScreenCaptureKit through the CPAL audio abstraction layer to capture pristine digital system audio on macOS, bypassing Bluetooth processing and integrating seamlessly into the real-time audio pipeline.**

Meetily, an open-source meeting assistant from Zackriya-Solutions, implements macOS system audio capture using Apple's ScreenCaptureKit (SCK) framework. This approach allows the application to tap into a digital audio stream directly from the operating system, avoiding the recompression artifacts common with Bluetooth audio paths. By routing ScreenCaptureKit through the Cross-Platform Audio Library (CPAL), Meetily achieves low-latency system audio capture that feeds directly into its voice activity detection and recording pipeline.

## Backend Configuration and Default Selection

Meetily defines its audio capture architecture through the `AudioCaptureBackend` enum, which specifies available capture methods for different platforms. On macOS, the default backend is explicitly set to `ScreenCaptureKit` in the configuration layer.

In [`frontend/src-tauri/src/audio/capture/backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/capture/backend_config.rs), the implementation selects the appropriate backend based on the target operating system. This ensures that macOS builds automatically utilize the ScreenCaptureKit host for system audio operations rather than legacy Core Audio paths.

### Selecting the ScreenCaptureKit Backend

The backend selection determines which CPAL host initializes the audio stream. When `AudioCaptureBackend::ScreenCaptureKit` is selected, the application configures the CPAL host to use `HostId::ScreenCaptureKit`, which provides direct access to system audio output devices.

```rust
// Selecting the backend (macOS default)
let backend = AudioCaptureBackend::ScreenCaptureKit;
println!("Using backend: {}", backend.name());
// → "ScreenCaptureKit" (see capture/backend_config.rs)

```

## Device Enumeration and Host Initialization

Before creating the capture stream, Meetily enumerates available output devices using the ScreenCaptureKit host. This occurs in [`frontend/src-tauri/src/audio/core-old.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/core-old.rs), where the application specifically opens the `ScreenCaptureKit` host to list digital system-audio devices.

Using the SCK host for enumeration avoids the noisy Bluetooth-processed audio path that macOS typically presents to applications. Instead, Meetily receives a pristine, unprocessed digital copy of the system audio stream, essential for high-quality meeting recordings.

## Stream Creation via CPAL Abstraction

The generic `AudioStream::create` function in [`frontend/src-tauri/src/audio/stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/stream.rs) serves as the primary wrapper for CPAL stream initialization. When system audio capture is requested, this function receives the `"ScreenCaptureKit"` backend designation and configures the CPAL stream to use the corresponding host.

The stream setup establishes a connection between the operating system's audio output and Meetily's internal processing pipeline. The SCK-backed stream delivers PCM audio samples directly to the application without requiring kernel extensions or third-party audio drivers.

```rust
// Creating a system‑audio stream with SCK
let sys_device = Arc::new(AudioDevice::new(
    "Built‑in Output".to_string(),
    DeviceType::Output,
));
let sys_stream = AudioStream::create(
    &sys_device,
    state.clone(),
    DeviceType::Output,
    recording_sender.clone(),
).await?;   // stream uses CPAL host = ScreenCaptureKit

```

## Fallback Mechanism in Enhanced Audio Management

Meetily's newer `EnhancedAudioStreamManager` implements a sophisticated fallback strategy for system audio capture. Located in [`frontend/src-tauri/src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/system_audio_stream.rs), this manager first attempts to use the Core Audio capture path. However, if the system only provides a digital output unsuitable for Core Audio capture, the implementation automatically falls back to the ScreenCaptureKit implementation.

This fallback logic ensures compatibility across different Mac hardware configurations while prioritizing the highest quality capture method available.

```rust
// Inside EnhancedAudioStreamManager – fallback to SCK
if should_use_enhanced_system_audio(&sys_device) {
    // …use Core Audio
} else {
    // Fallback to ScreenCaptureKit
    let sys_stream = super::stream::AudioStream::create(
        sys_device,
        self.state.clone(),
        DeviceType::Output,
        recording_sender,
    ).await?;
    // (see system_audio_stream.rs lines 150‑160)
}

```

## Real-Time Audio Processing Pipeline

Once the ScreenCaptureKit stream is active, the `SystemAudioStreamManager` spawns an asynchronous Tokio task to process incoming audio samples. This task pulls samples from the SCK stream, batches them into 1024-frame chunks, and forwards them to the `AudioCapture` processing stage.

The processing pipeline treats system audio identically to microphone input, feeding both streams into the same mixing and Voice Activity Detection (VAD) stages. This unified approach allows Meetily to record both sides of a conversation with synchronized timing.

```rust
// Processing loop in SystemAudioStreamManager (SCK path)
tokio::spawn(async move {
    while let Some(sample) = system_stream.next().await {
        buffer.push(sample);
        if buffer.len() >= frames_per_chunk {
            audio_capture.process_audio_data(&buffer);
            buffer.clear();
        }
    }
    // Process any leftovers
    if !buffer.is_empty() {
        audio_capture.process_audio_data(&buffer);
    }
});

```

## User Preferences and Backend Visibility

The frontend exposes the ScreenCaptureKit backend as a user-selectable option in the recording preferences. In [`frontend/src-tauri/src/audio/recording_preferences.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/recording_preferences.rs), the UI presents "ScreenCaptureKit" among the available capture backends on macOS, allowing advanced users to explicitly select this capture method or allow the automatic selection to choose it by default.

## Summary

- Meetily uses **ScreenCaptureKit** as the default audio capture backend on macOS, configured in [`backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/backend_config.rs).
- Device enumeration occurs through the **CPAL ScreenCaptureKit host**, providing access to pristine digital audio streams without Bluetooth recompression.
- The `AudioStream::create` wrapper initializes SCK-backed streams in [`stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/stream.rs), delivering low-latency system audio to the processing pipeline.
- An **intelligent fallback mechanism** in [`system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_stream.rs) ensures ScreenCaptureKit activates when Core Audio is unsuitable for the hardware configuration.
- Audio samples process in **1024-frame chunks** through a dedicated Tokio task, feeding directly into the VAD and mixing stages via `audio_capture.process_audio_data()`.

## Frequently Asked Questions

### Why does Meetily use ScreenCaptureKit instead of Core Audio for system audio?

Meetily selects ScreenCaptureKit because it provides direct access to the digital system audio stream before macOS applies Bluetooth codec processing or other system-level audio modifications. Core Audio often presents processed audio that has undergone additional compression steps, while SCK delivers the raw PCM data required for high-quality transcription and recording.

### Can users manually select the ScreenCaptureKit backend in Meetily's preferences?

Yes. The recording preferences UI in [`recording_preferences.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_preferences.rs) exposes "ScreenCaptureKit" as a selectable capture backend on macOS. While the application automatically selects this backend by default on compatible systems, advanced users can explicitly choose it or switch to alternative methods through the settings interface.

### How does Meetily handle audio format conversion with ScreenCaptureKit?

Meetily relies on CPAL's abstraction layer to handle format negotiation between ScreenCaptureKit and the internal audio pipeline. The `AudioStream::create` function configures the stream parameters to match the system's native output format, then batches samples into 1024-frame chunks for processing by the `AudioCapture` module, ensuring consistent handling regardless of the physical audio hardware.

### What happens if ScreenCaptureKit is unavailable on a Mac system?

If ScreenCaptureKit proves unsuitable for the current hardware configuration, Meetily's `EnhancedAudioStreamManager` implements a fallback mechanism that attempts Core Audio capture first, then reverts to ScreenCaptureKit if the enhanced path fails. This ensures the application maintains audio capture functionality across different Mac models and macOS versions, as implemented in [`system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/system_audio_stream.rs).