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

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 (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 (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

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.

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 →