Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
๐ผ Looking for a hosted desktop recording API?
Check out Recall.ai - an API for recording Zoom, Google Meet, Microsoft Teams, in-person meetings, and more.
Safe, idiomatic Rust bindings for Apple's ScreenCaptureKit framework.
Capture screen content, windows, and applications with high performance and low overhead on macOS 12.3+.
๐ Table of Contents
- Features
- Installation
- Quick Start
- Key Concepts
- Feature Flags
- API Overview
- Examples
- Testing
- Architecture
- Troubleshooting
- Platform Requirements
- Performance
- Contributing
- License
โจ Features
- ๐ฅ Screen & Window Capture - Capture displays, windows, or specific applications
- ๐ Audio Capture - Capture system audio and microphone input
- โก Real-time Processing - High-performance frame callbacks with custom dispatch queues
- ๐๏ธ Builder Pattern API - Clean, type-safe configuration with
::builder() - ๐ Async Support - Runtime-agnostic async API (works with Tokio, async-std, smol, etc.)
- ๐จ IOSurface Access - Zero-copy GPU texture access for Metal/OpenGL
- ๐ก๏ธ Memory Safe - Proper reference counting and leak-free by design
- ๐ฆ Zero Dependencies - No runtime dependencies (only dev dependencies for examples)
https://github.com/user-attachments/assets/8a272c48-7ec3-4132-9111-4602b4fa991d
๐ฆ Installation
Add to your Cargo.toml:
[]
= "1"
For async support:
[]
= { = "1", = ["async"] }
For latest macOS features:
[]
= { = "1", = ["macos_26_0"] }
๐ Quick Start
Basic Screen Capture
use *;
;
Async Capture
use ;
use *;
async
Window Capture with Audio
use *;
Content Picker (macOS 14.0+)
Use the system picker UI to let users choose what to capture:
use *;
use *;
Async Content Picker (macOS 14.0+)
Use the async version in async contexts to avoid blocking:
use AsyncSCContentSharingPicker;
use *;
use *;
async
๐ฏ Key Concepts
Builder Pattern
All types use a consistent ::new() with .with_*() chainable methods pattern:
// Stream configuration
let config = new
.with_width
.with_height
.with_pixel_format
.with_captures_audio;
// Content retrieval options
let content = create
.with_on_screen_windows_only
.with_exclude_desktop_windows
.get?;
// Content filters
let filter = create
.with_display
.with_excluding_windows
.build;
Custom Dispatch Queues
Control callback threading with custom dispatch queues:
use *;
use ;
Quality of Service Levels:
Background- Maintenance tasksUtility- Long-running tasksDefault- Standard priorityUserInitiated- User-initiated tasksUserInteractive- UI updates (highest priority)
IOSurface Access
Zero-copy GPU texture access:
use *;
;
Metal Integration
Built-in Metal types for hardware-accelerated rendering without external crates:
use *;
use ;
// Get the system default Metal device
let device = system_default.expect;
let command_queue = device.create_command_queue.unwrap;
// Compile built-in shaders (supports BGRA, YCbCr, UI overlays)
let library = device.create_library_with_source.unwrap;
// Create render pipeline for textured rendering
let vert_fn = library.get_function.unwrap;
let frag_fn = library.get_function.unwrap;
let pipeline_desc = new;
pipeline_desc.set_vertex_function;
pipeline_desc.set_fragment_function;
pipeline_desc.set_color_attachment_pixel_format;
let _pipeline = device.create_render_pipeline_state.unwrap;
Built-in Shader Functions:
vertex_fullscreen- Aspect-ratio-preserving fullscreen quadfragment_textured- BGRA/L10R single-texture renderingfragment_ycbcr- YCbCr biplanar (420v/420f) to RGB conversionvertex_colored/fragment_colored- UI overlay rendering
Metal Types:
MetalDevice,MetalCommandQueue,MetalCommandBufferMetalTexture,MetalBuffer,MetalLayer,MetalDrawableMetalRenderPipelineState,MetalRenderPassDescriptorCapturedTextures<T>- Multi-plane texture container (Y +CbCrforYCbCrformats)
๐๏ธ Feature Flags
Core Features
| Feature | Description |
|---|---|
async |
Runtime-agnostic async API (works with any executor) |
macOS Version Features
Feature flags enable APIs for specific macOS versions. They are cumulative (enabling macos_15_0 enables all earlier versions).
| Feature | macOS | APIs Enabled |
|---|---|---|
macos_13_0 |
13.0 Ventura | Audio capture, synchronization clock |
macos_14_0 |
14.0 Sonoma | Content picker, screenshots, content info |
macos_14_2 |
14.2 | Menu bar capture, child windows, presenter overlay |
macos_14_4 |
14.4 | Current process shareable content |
macos_15_0 |
15.0 Sequoia | Recording output, HDR capture, microphone |
macos_15_2 |
15.2 | Screenshot in rect, stream active/inactive delegates |
macos_26_0 |
26.0 | Advanced screenshot config, HDR screenshot output |
Version-Specific Example
let mut config = new
.with_width
.with_height;
config.set_should_be_opaque;
๐ API Overview
Core Types
| Type | Description |
|---|---|
SCShareableContent |
Query available displays, windows, and applications |
SCContentFilter |
Define what to capture (display/window/app) |
SCStreamConfiguration |
Configure resolution, format, audio, etc. |
SCStream |
Main capture stream with output handlers |
CMSampleBuffer |
Frame data with timing and metadata |
Async API (requires async feature)
| Type | Description |
|---|---|
AsyncSCShareableContent |
Async content queries |
AsyncSCStream |
Async stream with frame iteration |
AsyncSCScreenshotManager |
Async screenshot capture (macOS 14.0+) |
AsyncSCContentSharingPicker |
Async content picker UI (macOS 14.0+) |
Display & Window Types
| Type | Description |
|---|---|
SCDisplay |
Display information (resolution, ID, frame) |
SCWindow |
Window information (title, bounds, owner, layer) |
SCRunningApplication |
Application information (name, bundle ID, PID) |
Media Types
| Type | Description |
|---|---|
CMSampleBuffer |
Sample buffer with timing and attachments |
CMTime |
High-precision timestamps with timescale |
IOSurface |
GPU-backed pixel buffers for zero-copy access |
CGImage |
Core Graphics images for screenshots |
CVPixelBuffer |
Core Video pixel buffer with lock guards |
Metal Types (metal module)
| Type | Description |
|---|---|
MetalDevice |
Metal GPU device wrapper |
MetalTexture |
Metal texture with automatic retain/release |
MetalBuffer |
Vertex/uniform buffer |
MetalCommandQueue / MetalCommandBuffer |
Command submission |
MetalLayer |
CAMetalLayer for window rendering |
MetalRenderPipelineState |
Compiled render pipeline |
CapturedTextures<T> |
Multi-plane texture container (Y + CbCr for YCbCr) |
Uniforms |
Shader uniform structure matching SHADER_SOURCE |
Configuration Types
| Type | Description |
|---|---|
PixelFormat |
BGRA, YCbCr420v, YCbCr420f, l10r (10-bit) |
SCPresenterOverlayAlertSetting |
Privacy alert behavior |
SCCaptureDynamicRange |
HDR/SDR modes (macOS 15.0+) |
SCScreenshotConfiguration |
Advanced screenshot config (macOS 26.0+) |
SCScreenshotDynamicRange |
SDR/HDR screenshot output (macOS 26.0+) |
๐ Examples
The examples/ directory contains focused API demonstrations:
Quick Start (Numbered by Complexity)
01_basic_capture.rs- Simplest screen capture02_window_capture.rs- Capture specific windows03_audio_capture.rs- Audio + video capture04_pixel_access.rs- Read pixel data withstd::io::Cursor05_screenshot.rs- Single screenshot, HDR capture (macOS 14.0+, 26.0+)06_iosurface.rs- Zero-copy GPU buffers07_list_content.rs- List available content08_async.rs- Async/await API with multiple examples09_closure_handlers.rs- Closure-based handlers and delegates10_recording_output.rs- Direct video file recording (macOS 15.0+)11_content_picker.rs- System UI for content selection (macOS 14.0+)12_stream_updates.rs- Dynamic config/filter updates13_advanced_config.rs- HDR, presets, microphone (macOS 15.0+)14_app_capture.rs- Application-based filtering15_memory_leak_check.rs- Memory leak detection withleaks16_full_metal_app/- Full Metal GUI application (macOS 14.0+)17_metal_textures.rs- Metal texture creation fromIOSurface18_wgpu_integration.rs- Zero-copy wgpu integration19_ffmpeg_encoding.rs- Real-time H.264 encoding viaFFmpeg20_egui_viewer.rs- egui screen viewer integration21_bevy_streaming.rs- Bevy texture streaming22_tauri_app/- Tauri 2.0 desktop app with WebGL (macOS 14.0+)23_client_server/- Client/server screen sharing
See examples/README.md for detailed descriptions.
Run an example:
# Basic examples
# Feature-gated examples
# Tauri app (separate project)
&& &&
# Client/server screen sharing
๐งช Testing
Run Tests
# All tests
# With features
# Specific test
Linting
๐๏ธ Architecture
Module Organization
screencapturekit/
โโโ cm/ # Core Media (CMSampleBuffer, CMTime, IOSurface)
โโโ cv/ # Core Video (CVPixelBuffer, CVPixelBufferPool)
โโโ cg/ # Core Graphics (CGRect, CGPoint, CGSize)
โโโ metal/ # Metal GPU integration (textures, shaders)
โโโ stream/ # Stream management
โ โโโ configuration/ # SCStreamConfiguration
โ โโโ content_filter/ # SCContentFilter
โ โโโ sc_stream/ # SCStream
โโโ shareable_content/ # SCShareableContent, SCDisplay, SCWindow
โโโ dispatch_queue/ # Custom dispatch queues
โโโ error/ # Error types
โโโ screenshot_manager/ # SCScreenshotManager (macOS 14.0+)
โโโ content_sharing_picker/ # SCContentSharingPicker (macOS 14.0+)
โโโ recording_output/ # SCRecordingOutput (macOS 15.0+)
โโโ async_api/ # Async wrappers (feature = "async")
โโโ utils/ # FFI strings, FourCharCode utilities
โโโ prelude/ # Convenience re-exports
Memory Management
- Reference Counting - Proper CFRetain/CFRelease for all CoreFoundation types
- RAII - Automatic cleanup in Drop implementations
- Thread Safety - Safe to share across threads (where supported)
- Leak Free - Comprehensive leak tests ensure no memory leaks
โ Troubleshooting
Permission Denied / No Displays Found
Problem: SCShareableContent::get() returns an error or empty lists.
Solution: Grant screen recording permission:
- Open System Preferences โ Privacy & Security โ Screen Recording
- Add your app or Terminal to the list
- Restart your application
For development, you may need to add Terminal.app to the allowed list.
Entitlements for App Store / Notarization
Problem: App crashes or permissions fail after notarization.
Solution: Add required entitlements to your entitlements.plist:
com.apple.security.app-sandbox
com.apple.security.screen-capture
Black Frames / No Video Data
Problem: Frames are received but contain no visible content.
Solutions:
- Ensure the captured window/display is visible (not minimized)
- Check that
pixel_formatmatches your processing expectations - Verify the content filter includes the correct display/window
- On Apple Silicon, ensure proper GPU access
Audio Capture Not Working
Problem: Audio samples not received or empty.
Solutions:
- Enable audio capture:
.with_captures_audio(true) - Add an audio output handler:
stream.add_output_handler(handler, SCStreamOutputType::Audio) - Verify
sample_rateandchannel_countare set correctly
Build Errors
Problem: Compilation fails with Swift bridge errors.
Solutions:
- Ensure Xcode Command Line Tools are installed:
xcode-select --install - Clean and rebuild:
cargo clean && cargo build - Check that you're on macOS (this crate is macOS-only)
๐ง Platform Requirements
- macOS 12.3+ (Monterey) - Base
ScreenCaptureKitsupport - macOS 13.0+ (Ventura) - Audio capture, synchronization clock
- macOS 14.0+ (Sonoma) - Content picker, screenshots, content info
- macOS 15.0+ (Sequoia) - Recording output, HDR capture, microphone
- macOS 26.0+ (Tahoe) - Advanced screenshot config, HDR screenshot output
Screen Recording Permission
Screen recording requires explicit user permission. For development:
- Terminal/IDE must be in System Preferences โ Privacy & Security โ Screen Recording
For distribution:
- Add
NSScreenCaptureUsageDescriptionto yourInfo.plist - Sign with appropriate entitlements for notarization
โก Performance
Run benchmarks to measure performance on your hardware:
See docs/BENCHMARKS.md for detailed benchmark documentation including:
- API overhead measurements
- Frame throughput at various resolutions
- First-frame latency
- Pixel buffer and
IOSurfaceaccess patterns - Optimization tips for latency, throughput, and memory
Typical Performance (Apple Silicon)
| Resolution | Expected FPS | First Frame Latency |
|---|---|---|
| 1080p | 30-60 FPS | 30-100ms |
| 4K | 15-30 FPS | 50-150ms |
๐ Migration
Upgrading from an older version? See docs/MIGRATION.md for:
- API changes between versions
- Code examples for common migrations
- Deprecated API replacements
๐ค Contributing
Contributions welcome! Please:
- Follow existing code patterns (builder pattern with
::new()and.with_*()methods) - Add tests for new functionality
- Run
cargo testandcargo clippy - Update documentation
๐ Used By
This crate is used by some amazing projects:
- AFFiNE - Next-gen knowledge base, alternative to Notion and Miro (50k+ โญ)
- Vibe - Transcribe on your own! Local transcription tool (5k+ โญ)
- Lycoris - Real-time speech recognition & AI-powered note-taking for macOS
Using screencapturekit-rs? Let us know and we'll add you to the list!
๐ฅ Contributors
Thanks to everyone who has contributed to this project!
- Per Johansson - Maintainer
- Iason Paraskevopoulos
- Kris Krolak
- Tokuhiro Matsuno
- Pranav Joglekar
- Alex Jiao
- Charles
- bigduu
- Andrew N
๐ License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.