# How Screen Capture and Recording Functionality Is Implemented in Vorssaint-utils

> Discover how Vorssaint-utils implements screen capture and recording using two Swift services. Learn about ScreenCaptureService and ScreenRecorderService for seamless functionality.

- Repository: [vorssaint/vorssaint-utils](https://github.com/vorssaint/vorssaint-utils)
- Tags: internals
- Published: 2026-09-12

---

**Vorssaint-utils implements screen capture and recording through two tightly-coupled Swift services: `ScreenCaptureService` routes all screenshot-style tools while `ScreenRecorderService` manages asynchronous video sessions with system audio capture and disk-space monitoring.**

Vorssaint-utils is an open-source macOS utility library that unifies screenshot, OCR, color picking, and screen recording capabilities under a permission-first architecture. The implementation separates UI coordination from media engine management, allowing consistent region selection across static captures and video recordings.

## Architecture of the Core Services

The codebase organizes functionality into distinct service layers defined in `Sources/Vorssaint/Services/`.

**`ScreenCaptureService`** acts as the unified entry point for all capture-related tools. Located in [`Sources/Vorssaint/Services/QuickTools/ScreenCaptureService.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/QuickTools/ScreenCaptureService.swift) (lines 31-78), this singleton handles hot-key registration via `QuickToolHotkey`, permission checks, countdown timers, and the `ScreenshotSelectionController` UI. It routes user selections to downstream processors like `ScreenshotService`, `ScreenTextService`, or `ScreenRecorderService`.

**`ScreenRecorderService`** manages the complete lifecycle of a screen-recording session. Found in [`Sources/Vorssaint/Services/Recorder/ScreenRecorderService.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Recorder/ScreenRecorderService.swift) (lines 43-78), this service validates prerequisites, creates recording sessions, drives the video engine, and handles audio routing. It monitors disk space, implements pause/resume logic, and persists the final `MOV` file.

**`RecorderSession`** is an inner class of `ScreenRecorderService` defined in the same file (lines 24-42). It encapsulates a single recording by instantiating the `RecorderWriter`, starting the `RecorderCaptureEngine`, collecting audio samples, and capturing pointer and typing data. The session handles unexpected stops and microphone unavailability before finalizing the output file.

## Capture Workflow for Screenshots and OCR

The static capture implementation follows a five-stage pipeline orchestrated by `ScreenCaptureService`.

### Hot-Key Registration and Permission Validation

When a user triggers a capture tool, `ScreenCaptureService` receives the event through hot-keys registered during its `init`. The service immediately verifies **screen-recording permissions** via `Permissions.shared.requestScreenRecording()`. For the color picker tool, it falls back to a native color-sampler path that requires fewer permissions.

### Countdown and Selection UI

If the user configures a delay, `ScreenCaptureService` starts a countdown via `tickCountdown` that updates the floating `QuickToolHUD.showCountdown`. Once the countdown completes, the service instantiates a `ScreenshotSelectionController` with specific policies: freeze screen state, include or exclude the pointer, and hide Vorssaint's own windows from the selection.

### Routing Logic

Upon region confirmation, `ScreenCaptureService.route(_:selected:recorderAudio:)` dispatches the result to the appropriate handler:

- **`.captured`** → Forwards to `ScreenshotService` for standard screenshots or `ScreenTextService` for OCR processing.
- **`.region`** → Initiates video recording by calling `ScreenRecorderService.record(region:audioOptions:)`.
- **`.color`** → Invokes `ColorSamplerService` to sample the pixel value.

## Recording Workflow Implementation

Video capture follows an eleven-step asynchronous process managed by `ScreenRecorderService`.

### Session Preparation and Validation

The entry point `toggle()` triggers `prepareForSelection()`, which performs three checks before recording:

1. **Feature availability** via `AppFeature.screenRecorder.isAvailable`.
2. **Permission state** for screen recording, accessibility, and microphone access.
3. **Disk space sufficiency** via `RecorderSupport.canStart`.

If a countdown is configured in `DefaultsKey.recorderCountdown`, `prepareCountdown` displays the HUD each second until recording begins.

### Engine and Audio Initialization

`beginRecording(region:generation:)` creates a new `RecorderTakeStore.Take`, reads user preferences (frame rate, audio options), and instantiates a `RecorderSession`. Inside `RecorderSession.start()`, the service launches the `RecorderCaptureEngine` and initializes audio sources:

- **System audio** via `RecorderSystemAudioTap` (preferred) or stream output fallback.
- **Microphone capture** via `RecorderMicrophoneCapture` if `DefaultsKey.recorderMicrophone` is enabled.

The session monitors `writesTapAudio` and `streamHeard` to verify audio integrity and switch sources if the tap fails.

### Input Sampling and UI Indicators

During recording, `RecorderPointerSampler` tracks mouse movement and `RecorderTypingSampler` captures typed characters. These data streams are saved alongside the video track.

A floating `RecorderIndicator` displays elapsed time and pause/stop controls. The indicator excludes its own window from capture via `indicator.excludedWindowNumbers` to prevent UI artifacts in the final recording.

### Pause, Resume, and Disk Monitoring

The service delegates pause/resume logic to `RecorderPauseClock` to freeze elapsed time accurately. A background task `checkDiskSpace` periodically queries available storage; if space runs low, the recording stops automatically with a HUD warning.

### Finalization

Calling `stop()` cancels the capture engine, flushes the `RecorderWriter`, writes pointer and typing tracks, and invokes `deliver(_:,reason:)` to either open the editor or save directly to the user-configured `saveDestination`.

## Key Architectural Concepts

- **Singleton pattern**: Both `ScreenCaptureService.shared` and `ScreenRecorderService.shared` provide global access points observed by the UI layer, including `ScreenRecorderSettings` views and radial menus.
- **Separation of concerns**: The `ScreenshotSelectionController` UI component is reused across screenshots, OCR, color picking, and recording, while `RecorderSession` isolates video-specific logic.
- **Asynchronous design**: Recording start and stop are `async` operations executing on background queues (`writerQueue`, global utility queue) to maintain UI responsiveness.
- **Permission-first approach**: All entry points verify screen-recording, accessibility, and microphone permissions before accessing system resources, requesting authorization only when needed.
- **Pluggable audio architecture**: System audio capture prefers the `AudioTap` implementation but falls back to stream output; microphone capture remains optional and user-configurable.

## Practical Implementation Examples

```swift
import Vorssaint

// Toggle recording start/stop from a global shortcut
ScreenRecorderService.shared.toggle()

// Capture a screenshot with a 2-second delay
ScreenCaptureService.shared.capture(initial: .screenshot)

// Programmatically record a specific region with system audio only
let region = RecorderSupport.Region(
    displayID: 12345,
    origin: .zero,
    pixelSize: CGSize(width: 1280, height: 720)
)
let audioOpts = RecorderSelectionAudioOptions()
audioOpts.systemAudio = true
audioOpts.microphone = false
ScreenRecorderService.shared.record(region, audioOptions: audioOpts)

// Pause or resume from UI callbacks
ScreenRecorderService.shared.togglePause()

```

## Summary

- **Dual-service architecture**: `ScreenCaptureService` coordinates static captures while `ScreenRecorderService` handles video lifecycle management.
- **Unified selection UI**: The `ScreenshotSelectionController` supports screenshots, OCR, color picking, and recording through policy-based configuration.
- **Permission-first validation**: All workflows check `Permissions.shared` before accessing screen-recording or microphone resources.
- **Asynchronous recording**: `RecorderSession` manages the `RecorderCaptureEngine`, audio taps, and input samplers on background queues.
- **Resilient audio handling**: The system verifies tap functionality via `writesTapAudio` and `streamHeard`, falling back to stream capture when necessary.
- **Runtime monitoring**: Disk-space checks and pause/resume functionality ensure reliable long-form recordings.

## Frequently Asked Questions

### How does Vorssaint-utils handle missing screen recording permissions?

The framework checks permissions at every entry point using `Permissions.shared.requestScreenRecording()`. If authorization is missing, the service prompts the user before instantiating the capture UI or starting the `RecorderCaptureEngine`.

### Can the screen recorder capture both system audio and microphone input simultaneously?

Yes. `ScreenRecorderService` initializes both a `RecorderSystemAudioTap` for system audio and a `RecorderMicrophoneCapture` for microphone input when `DefaultsKey.recorderMicrophone` is enabled. The `RecorderSession` writes both streams to the `MOV` file while monitoring audio integrity.

### How is the region selection UI reused between screenshots and video recording?

The `ScreenshotSelectionController` accepts policy parameters that define behavior for freezing the screen, showing the pointer, and hiding Vorssaint windows. `ScreenCaptureService` instantiates this controller for all tools, routing the resulting region to either `ScreenshotService` or `ScreenRecorderService.record(region:audioOptions:)` based on the selected tool type.

### What triggers automatic stopping of a recording?

A background task `checkDiskSpace` monitors available storage during the session. If disk space falls below the threshold defined in `RecorderSupport.canStart`, the service calls `stop()` automatically and displays a warning HUD to prevent data loss from insufficient storage.