# How to Debug Audio Capture Issues on macOS Using ScreenCaptureKit in Meetily

> Fix audio capture problems on macOS with Meetily. Learn to debug ScreenCaptureKit issues by checking permissions, setting environment variables, and reviewing device logs in the codebase.

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

---

**To debug audio capture issues in Meetily on macOS, verify Screen Recording permissions are enabled in System Settings, launch the application with `RUST_LOG=app_lib::audio=debug,cpal=trace` for verbose tracing, and inspect the device selection logs in [`src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/system_audio_stream.rs) to confirm the ScreenCaptureKit backend is binding to the correct output device.**

Meetily leverages Apple's **ScreenCaptureKit** (SCK) framework to capture system audio on macOS through the CPAL audio-host abstraction. When users experience silent recordings or missing system audio, the issue typically stems from permission denials, backend misconfiguration, or device enumeration failures within the Rust audio pipeline. This guide provides a code-level walkthrough of the diagnostic process using the actual implementation in the [Zackriya-Solutions/meetily](https://github.com/Zackriya-Solutions/meetily) repository.

## How Meetily Routes System Audio Through ScreenCaptureKit

Understanding the audio capture architecture is essential before debugging. The flow follows five distinct layers according to the Meetily source code:

1. **Device Discovery** – [`src/audio/devices/platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/devices/platform/macos.rs) enumerates built-in output devices compatible with SCK.
2. **Backend Selection** – [`src/audio/capture/backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/capture/backend_config.rs) defines `AudioCaptureBackend::ScreenCaptureKit` as the default macOS backend and resolves the string "screencapturekit".
3. **Stream Creation** – [`src/audio/stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/stream.rs) instantiates a CPAL stream using `cpal::HostId::ScreenCaptureKit` and tags it with the name "ScreenCaptureKit".
4. **System-Audio Wrapper** – [`src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/system_audio_stream.rs) constructs a `SystemAudioStream` that holds the CPAL stream; if SCK initialization fails, it triggers fallback logic and logs a warning.
5. **Permission Validation** – [`src/audio/permissions.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/permissions.rs) requests the **Screen Recording** permission required by SCK on macOS through `request_screen_capture_permission()`.

Each layer emits specific log messages that allow you to pinpoint where the capture chain breaks.

## Six-Step Debugging Workflow

When system audio capture fails, trace through these checkpoints in order:

### Verify macOS Screen Recording Permissions

SCK requires explicit user consent. Open **System Settings** → **Privacy & Security** → **Screen Recording** and ensure "Meetily" is enabled. If you moved the binary after granting permission, macOS invalidates the consent and you must re-enable it. The application calls `request_screen_capture_permission()` in [`src/audio/permissions.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/permissions.rs), which logs any authorization errors.

### Confirm the ScreenCaptureKit Backend Is Active

Check that the configuration resolves to `AudioCaptureBackend::ScreenCaptureKit`. In [`src/audio/capture/backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/capture/backend_config.rs), the default is enforced through assertions at lines 25-34. If the backend has been overridden via user settings, delete `~/Library/Application Support/Meetily/settings.json` to reset to defaults.

### Inspect Host Creation Logs

Look for `cpal::host_from_id(cpal::HostId::ScreenCaptureKit)` initialization messages in the logs. In [`src/audio/stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/stream.rs) (lines 18-22), successful host creation proceeds to stream construction; failures emit `error!` logs and trigger fallback paths in [`src/audio/core-old.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/core-old.rs) (lines 264, 309).

### Validate Device Selection

The log entry `Falling back to ScreenCaptureKit for: <device_name>` appears in [`src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/system_audio_stream.rs) at line 150. Verify that `<device_name>` matches a real system output such as "Built-in Output". If it references an unavailable Bluetooth device, switch to a wired output or built-in speakers.

### Monitor Fallback Activation

If you see `warn!("Fallback ScreenCaptureKit stream created but not stored in enhanced manager")` in [`src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/system_audio_stream.rs) (lines 159-160), the primary SCK stream failed to initialize. The fallback stream may provide reduced quality or intermittent audio capture.

### Analyze Runtime Stream Health

Enable debug logging and look for `perf_debug!` entries showing consistent 48 kHz sample rates. Variable sample rates indicate the SCK host is not correctly managing the audio buffer, which usually precedes capture dropouts.

## Enabling Verbose Logging and Interpreting Output

To capture detailed diagnostics from the audio subsystem, launch Meetily from the terminal with the following environment variables:

```bash
RUST_LOG=app_lib::audio=debug,cpal=trace ./clean_run.sh

```

Debug builds emit all internal metrics including buffer sizes, sample-rate changes, and VAD (Voice Activity Detection) activity. Release builds strip the `perf_debug!` macro, so always use a debug build for deep diagnostics.

Key log patterns to search for:

- `info!` entries containing "ScreenCaptureKit" confirm the backend loaded.
- `warn!` entries referencing "Fallback" indicate the primary stream failed.
- `error!` entries from `cpal::host_from_id` signal permission or host availability issues.

## Manual Debugging Techniques

You can programmatically verify components using the following patterns from the Meetily codebase.

**Force the capture backend to ScreenCaptureKit for testing:**

```rust
use meetily::audio::capture::backend_config::AudioCaptureBackend;

// Override at runtime from the dev console
AudioCaptureBackend::set(AudioCaptureBackend::ScreenCaptureKit);

```

**Programmatically request Screen Recording permission:**

```rust
#[cfg(target_os = "macos")]
pub async fn request_screen_capture_permission() -> Result<()> {
    // Tauri helper forwarding to macOS APIs
    tauri::api::dialog::ask(
        Some(&app_handle),
        "Screen Capture Permission",
        "Meetily needs screen-recording permission to capture system audio.",
        move |answer| {
            if answer {
                // permission granted
            } else {
                // handle denial
            }
        },
    );
    Ok(())
}

```

**Inspect the selected system audio device:**

```rust
#[cfg(target_os = "macos")]
fn log_selected_device(device: &AudioDevice) {
    info!("ScreenCaptureKit will capture from system device: {}", device.name);
}

```

## Summary

- **Screen Recording permission** is mandatory for ScreenCaptureKit; verify it in System Settings whenever audio capture fails silently.
- **Verbose logging** via `RUST_LOG=app_lib::audio=debug,cpal=trace` exposes the backend selection, host creation, and device binding steps.
- **Device selection logs** in [`src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/system_audio_stream.rs) reveal which output device SCK attempts to capture; mismatches indicate enumeration errors.
- **Fallback warnings** signal that the primary SCK stream failed, often due to incompatible hardware or permission issues.
- **Configuration reset** by deleting `~/Library/Application Support/Meetily/settings.json` resolves backend override issues.

## Frequently Asked Questions

### Why does Meetily show no audio input even after granting permissions?

If permissions were granted but the app was moved or rebuilt, macOS invalidates the entitlements. Re-grant permission in **System Settings** → **Privacy & Security** → **Screen Recording**, or use the "Refresh Devices" UI button which invokes `get_safe_recording_devices_macos()` in [`src/audio/recording_manager.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/recording_manager.rs) to re-enumerate devices.

### How do I know if ScreenCaptureKit is actually being used instead of a fallback?

Check the logs for the string `Falling back to ScreenCaptureKit for:` in [`src/audio/system_audio_stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/system_audio_stream.rs). If you instead see `Fallback ScreenCaptureKit stream created`, the primary backend failed and the application is using a lower-quality fallback path.

### Can I force Meetily to use a specific audio backend for testing?

Yes. You can programmatically set the backend using `AudioCaptureBackend::set(AudioCaptureBackend::ScreenCaptureKit)` as defined in [`src/audio/capture/backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/capture/backend_config.rs). Alternatively, reset the configuration file at `~/Library/Application Support/Meetily/settings.json` to remove any user overrides that might disable SCK.

### What sample rate should I expect from ScreenCaptureKit streams?

ScreenCaptureKit typically provides audio at **48 kHz**. If you observe variable sample rates in the `perf_debug!` logs within [`src/audio/pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src/audio/pipeline.rs), the SCK host is not correctly managing the buffer, indicating a potential driver or permission issue at the system level.