<div align="center">
<h1>ScreenCaptureKit-rs</h1>
</div>
<div align="center"><p>
<a href="https://crates.io/crates/screencapturekit"><img alt="Crates.io" src="https://img.shields.io/crates/v/screencapturekit?style=for-the-badge&logo=rust&color=C9CBFF&logoColor=D9E0EE&labelColor=302D41" /></a>
<a href="https://crates.io/crates/screencapturekit"><img alt="Crates.io Downloads" src="https://img.shields.io/crates/d/screencapturekit?style=for-the-badge&logo=rust&color=A6E3A1&logoColor=D9E0EE&labelColor=302D41" /></a>
<a href="https://docs.rs/screencapturekit"><img alt="docs.rs" src="https://img.shields.io/docsrs/screencapturekit?style=for-the-badge&logo=docs.rs&color=8bd5ca&logoColor=D9E0EE&labelColor=302D41" /></a>
<a href="https://github.com/doom-fish/screencapturekit-rs#license"><img alt="License" src="https://img.shields.io/crates/l/screencapturekit?style=for-the-badge&logo=apache&color=ee999f&logoColor=D9E0EE&labelColor=302D41" /></a>
<a href="https://github.com/doom-fish/screencapturekit-rs/actions"><img alt="Build Status" src="https://img.shields.io/github/actions/workflow/status/doom-fish/screencapturekit-rs/ci.yml?branch=main&style=for-the-badge&logo=github&color=c69ff5&logoColor=D9E0EE&labelColor=302D41" /></a>
<a href="https://github.com/doom-fish/screencapturekit-rs/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/doom-fish/screencapturekit-rs?style=for-the-badge&logo=starship&color=F5E0DC&logoColor=D9E0EE&labelColor=302D41" /></a>
</p></div>
> **๐ผ Looking for a hosted desktop recording API?**
> Check out [Recall.ai](https://www.recall.ai/product/desktop-recording-sdk?utm_source=github&utm_medium=sponsorship&utm_campaign=screencapturekit-rs) - an API for recording Zoom, Google Meet, Microsoft Teams, in-person meetings, and more.
Safe, idiomatic Rust bindings for Apple's [ScreenCaptureKit](https://developer.apple.com/documentation/screencapturekit) framework.
Capture screen content, windows, and applications with high performance and low overhead on macOS 12.3+.
## ๐ Table of Contents
- [Features](#-features)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Key Concepts](#-key-concepts)
- [Feature Flags](#-feature-flags)
- [API Overview](#-api-overview)
- [Examples](#-examples)
- [Testing](#-testing)
- [Architecture](#-architecture)
- [Troubleshooting](#-troubleshooting)
- [Platform Requirements](#-platform-requirements)
- [Performance](#-performance)
- [Contributing](#-contributing)
- [License](#-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`:
```toml
[dependencies]
screencapturekit = "1"
```
For async support:
```toml
[dependencies]
screencapturekit = { version = "1", features = ["async"] }
```
For latest macOS features:
```toml
[dependencies]
screencapturekit = { version = "1", features = ["macos_26_0"] }
```
## ๐ Quick Start
### Basic Screen Capture
```rust
use screencapturekit::prelude::*;
struct Handler;
impl SCStreamOutputTrait for Handler {
fn did_output_sample_buffer(&self, sample: CMSampleBuffer, _type: SCStreamOutputType) {
println!("๐น Received frame at {:?}", sample.presentation_timestamp());
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Get available displays
let content = SCShareableContent::get()?;
let display = &content.displays()[0];
// Configure capture
let filter = SCContentFilter::create()
.with_display(display)
.with_excluding_windows(&[])
.build();
let config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080)
.with_pixel_format(PixelFormat::BGRA);
// Start streaming
let mut stream = SCStream::new(&filter, &config);
stream.add_output_handler(Handler, SCStreamOutputType::Screen);
stream.start_capture()?;
// Capture runs in background...
std::thread::sleep(std::time::Duration::from_secs(5));
stream.stop_capture()?;
Ok(())
}
```
### Async Capture
```rust,ignore
use screencapturekit::async_api::{AsyncSCShareableContent, AsyncSCStream};
use screencapturekit::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Get content asynchronously
let content = AsyncSCShareableContent::get().await?;
let display = &content.displays()[0];
// Create filter and config
let filter = SCContentFilter::create()
.with_display(display)
.with_excluding_windows(&[])
.build();
let config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080);
// Create async stream with frame buffer
let stream = AsyncSCStream::new(&filter, &config, 30, SCStreamOutputType::Screen);
stream.start_capture()?;
// Capture frames asynchronously
for _ in 0..10 {
if let Some(frame) = stream.next().await {
println!("๐น Got frame!");
}
}
stream.stop_capture()?;
Ok(())
}
```
### Window Capture with Audio
```rust,no_run
use screencapturekit::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let content = SCShareableContent::get()?;
// Find a specific window
let windows = content.windows();
let window = windows
.iter()
.find(|w| w.title().as_deref() == Some("Safari"))
.ok_or("Safari window not found")?;
// Capture window with audio
let filter = SCContentFilter::create()
.with_window(window)
.build();
let config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080)
.with_captures_audio(true)
.with_sample_rate(48000)
.with_channel_count(2);
let mut stream = SCStream::new(&filter, &config);
// Add handlers...
stream.start_capture()?;
Ok(())
}
```
### Content Picker (macOS 14.0+)
Use the system picker UI to let users choose what to capture:
```rust,ignore
use screencapturekit::content_sharing_picker::*;
use screencapturekit::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = SCContentSharingPickerConfiguration::new();
// Show picker - callback receives result when user selects or cancels
SCContentSharingPicker::show(&config, |outcome| {
match outcome {
SCPickerOutcome::Picked(result) => {
// Get dimensions from the picked content
let (width, height) = result.pixel_size();
println!("Selected: {}x{} (scale: {})", width, height, result.scale());
let stream_config = SCStreamConfiguration::new()
.with_width(width)
.with_height(height);
// Get filter for streaming
let filter = result.filter();
let mut stream = SCStream::new(&filter, &stream_config);
// ...
}
SCPickerOutcome::Cancelled => println!("User cancelled"),
SCPickerOutcome::Error(e) => eprintln!("Error: {}", e),
}
});
Ok(())
}
```
### Async Content Picker (macOS 14.0+)
Use the async version in async contexts to avoid blocking:
```rust,ignore
use screencapturekit::async_api::AsyncSCContentSharingPicker;
use screencapturekit::content_sharing_picker::*;
use screencapturekit::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = SCContentSharingPickerConfiguration::new();
// Async picker - doesn't block the executor
match AsyncSCContentSharingPicker::show(&config).await {
SCPickerOutcome::Picked(result) => {
let (width, height) = result.pixel_size();
println!("Selected: {}x{}", width, height);
let filter = result.filter();
// Use filter with stream...
}
SCPickerOutcome::Cancelled => println!("User cancelled"),
SCPickerOutcome::Error(e) => eprintln!("Error: {}", e),
}
Ok(())
}
```
## ๐ฏ Key Concepts
### Builder Pattern
All types use a consistent `::new()` with `.with_*()` chainable methods pattern:
```rust,ignore
// Stream configuration
let config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080)
.with_pixel_format(PixelFormat::BGRA)
.with_captures_audio(true);
// Content retrieval options
let content = SCShareableContent::create()
.with_on_screen_windows_only(true)
.with_exclude_desktop_windows(true)
.get()?;
// Content filters
let filter = SCContentFilter::create()
.with_display(&display)
.with_excluding_windows(&windows)
.build();
```
### Custom Dispatch Queues
Control callback threading with custom dispatch queues:
```rust,ignore
use screencapturekit::prelude::*;
use screencapturekit::dispatch_queue::{DispatchQueue, DispatchQoS};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let content = SCShareableContent::get()?;
let display = content.displays().into_iter().next().unwrap();
let filter = SCContentFilter::create()
.with_display(&display)
.with_excluding_windows(&[])
.build();
let config = SCStreamConfiguration::new();
let mut stream = SCStream::new(&filter, &config);
let queue = DispatchQueue::new("com.myapp.capture", DispatchQoS::UserInteractive);
stream.add_output_handler_with_queue(
|_sample: CMSampleBuffer, _of_type: SCStreamOutputType| { /* process frame */ },
SCStreamOutputType::Screen,
Some(&queue)
);
Ok(())
}
```
**Quality of Service Levels:**
- `Background` - Maintenance tasks
- `Utility` - Long-running tasks
- `Default` - Standard priority
- `UserInitiated` - User-initiated tasks
- `UserInteractive` - UI updates (highest priority)
### IOSurface Access
Zero-copy GPU texture access:
```rust,no_run
use screencapturekit::prelude::*;
struct Handler;
impl SCStreamOutputTrait for Handler {
fn did_output_sample_buffer(&self, sample: CMSampleBuffer, _of_type: SCStreamOutputType) {
if let Some(pixel_buffer) = sample.image_buffer() {
if let Some(surface) = pixel_buffer.io_surface() {
let width = surface.width();
let height = surface.height();
// Use with Metal/OpenGL...
println!("IOSurface: {}x{}", width, height);
}
}
}
}
```
### Metal Integration
Built-in Metal types for hardware-accelerated rendering without external crates:
```rust,no_run
use screencapturekit::prelude::*;
use screencapturekit::metal::{
MetalDevice, MetalRenderPassDescriptor, MetalRenderPipelineDescriptor,
MTLLoadAction, MTLStoreAction, MTLPrimitiveType, MTLPixelFormat,
Uniforms, SHADER_SOURCE,
};
// Get the system default Metal device
let device = MetalDevice::system_default().expect("No Metal device");
let command_queue = device.create_command_queue().unwrap();
// Compile built-in shaders (supports BGRA, YCbCr, UI overlays)
let library = device.create_library_with_source(SHADER_SOURCE).unwrap();
// Create render pipeline for textured rendering
let vert_fn = library.get_function("vertex_fullscreen").unwrap();
let frag_fn = library.get_function("fragment_textured").unwrap();
let pipeline_desc = MetalRenderPipelineDescriptor::new();
pipeline_desc.set_vertex_function(&vert_fn);
pipeline_desc.set_fragment_function(&frag_fn);
pipeline_desc.set_color_attachment_pixel_format(0, MTLPixelFormat::BGRA8Unorm);
let _pipeline = device.create_render_pipeline_state(&pipeline_desc).unwrap();
```
**Built-in Shader Functions:**
- `vertex_fullscreen` - Aspect-ratio-preserving fullscreen quad
- `fragment_textured` - BGRA/L10R single-texture rendering
- `fragment_ycbcr` - YCbCr biplanar (420v/420f) to RGB conversion
- `vertex_colored` / `fragment_colored` - UI overlay rendering
**Metal Types:**
- `MetalDevice`, `MetalCommandQueue`, `MetalCommandBuffer`
- `MetalTexture`, `MetalBuffer`, `MetalLayer`, `MetalDrawable`
- `MetalRenderPipelineState`, `MetalRenderPassDescriptor`
- `CapturedTextures<T>` - Multi-plane texture container (Y + `CbCr` for `YCbCr` formats)
## ๐๏ธ Feature Flags
### Core Features
| `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).
| `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
```rust,ignore
let mut config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080);
#[cfg(feature = "macos_13_0")]
config.set_should_be_opaque(true);
#[cfg(feature = "macos_14_2")]
{
config.set_ignores_shadows_single_window(true);
config.set_includes_child_windows(false);
}
```
## ๐ API Overview
### Core Types
| [`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 |
[`SCShareableContent`]: https://doom-fish.github.io/screencapturekit-rs/screencapturekit/shareable_content/struct.SCShareableContent.html
[`SCContentFilter`]: https://doom-fish.github.io/screencapturekit-rs/screencapturekit/stream/content_filter/struct.SCContentFilter.html
[`SCStreamConfiguration`]: https://doom-fish.github.io/screencapturekit-rs/screencapturekit/stream/configuration/struct.SCStreamConfiguration.html
[`SCStream`]: https://doom-fish.github.io/screencapturekit-rs/screencapturekit/stream/sc_stream/struct.SCStream.html
[`CMSampleBuffer`]: https://doom-fish.github.io/screencapturekit-rs/screencapturekit/cm/struct.CMSampleBuffer.html
### Async API (requires `async` feature)
| `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
| `SCDisplay` | Display information (resolution, ID, frame) |
| `SCWindow` | Window information (title, bounds, owner, layer) |
| `SCRunningApplication` | Application information (name, bundle ID, PID) |
### Media Types
| `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)
| `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
| `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/`](examples/) directory contains focused API demonstrations:
### Quick Start (Numbered by Complexity)
1. **`01_basic_capture.rs`** - Simplest screen capture
2. **`02_window_capture.rs`** - Capture specific windows
3. **`03_audio_capture.rs`** - Audio + video capture
4. **`04_pixel_access.rs`** - Read pixel data with `std::io::Cursor`
5. **`05_screenshot.rs`** - Single screenshot, HDR capture (macOS 14.0+, 26.0+)
6. **`06_iosurface.rs`** - Zero-copy GPU buffers
7. **`07_list_content.rs`** - List available content
8. **`08_async.rs`** - Async/await API with multiple examples
9. **`09_closure_handlers.rs`** - Closure-based handlers and delegates
10. **`10_recording_output.rs`** - Direct video file recording (macOS 15.0+)
11. **`11_content_picker.rs`** - System UI for content selection (macOS 14.0+)
12. **`12_stream_updates.rs`** - Dynamic config/filter updates
13. **`13_advanced_config.rs`** - HDR, presets, microphone (macOS 15.0+)
14. **`14_app_capture.rs`** - Application-based filtering
15. **`15_memory_leak_check.rs`** - Memory leak detection with `leaks`
16. **`16_full_metal_app/`** - Full Metal GUI application (macOS 14.0+)
17. **`17_metal_textures.rs`** - Metal texture creation from `IOSurface`
18. **`18_wgpu_integration.rs`** - Zero-copy wgpu integration
19. **`19_ffmpeg_encoding.rs`** - Real-time H.264 encoding via `FFmpeg`
20. **`20_egui_viewer.rs`** - egui screen viewer integration
21. **`21_bevy_streaming.rs`** - Bevy texture streaming
22. **`22_tauri_app/`** - Tauri 2.0 desktop app with WebGL (macOS 14.0+)
23. **`23_client_server/`** - Client/server screen sharing
See [`examples/README.md`](examples/README.md) for detailed descriptions.
Run an example:
```bash
# Basic examples
cargo run --example 01_basic_capture
cargo run --example 09_closure_handlers
cargo run --example 12_stream_updates
cargo run --example 14_app_capture
cargo run --example 17_metal_textures
cargo run --example 18_wgpu_integration
cargo run --example 19_ffmpeg_encoding # Requires: brew install ffmpeg
cargo run --example 20_egui_viewer
cargo run --example 21_bevy_streaming
# Feature-gated examples
cargo run --example 05_screenshot --features macos_14_0
cargo run --example 08_async --features async
cargo run --example 10_recording_output --features macos_15_0
cargo run --example 11_content_picker --features macos_14_0
cargo run --example 13_advanced_config --features macos_15_0
cargo run --example 16_full_metal_app --features macos_14_0
# Tauri app (separate project)
cd examples/22_tauri_app && npm install && npm run tauri dev
# Client/server screen sharing
cargo run --example 23_client_server_server # Terminal 1
cargo run --example 23_client_server_client # Terminal 2
```
## ๐งช Testing
### Run Tests
```bash
# All tests
cargo test
# With features
cargo test --features async
cargo test --all-features
# Specific test
cargo test test_stream_configuration
```
### Linting
```bash
cargo clippy --all-features -- -D warnings
cargo fmt --check
```
## ๐๏ธ Architecture
### Module Organization
```text
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:
1. Open **System Preferences** โ **Privacy & Security** โ **Screen Recording**
2. Add your app or Terminal to the list
3. 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`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.screen-capture</key>
<true/>
</dict>
</plist>
```
### Black Frames / No Video Data
**Problem**: Frames are received but contain no visible content.
**Solutions**:
1. Ensure the captured window/display is visible (not minimized)
2. Check that `pixel_format` matches your processing expectations
3. Verify the content filter includes the correct display/window
4. On Apple Silicon, ensure proper GPU access
### Audio Capture Not Working
**Problem**: Audio samples not received or empty.
**Solutions**:
1. Enable audio capture: `.with_captures_audio(true)`
2. Add an audio output handler: `stream.add_output_handler(handler, SCStreamOutputType::Audio)`
3. Verify `sample_rate` and `channel_count` are set correctly
### Build Errors
**Problem**: Compilation fails with Swift bridge errors.
**Solutions**:
1. Ensure Xcode Command Line Tools are installed: `xcode-select --install`
2. Clean and rebuild: `cargo clean && cargo build`
3. Check that you're on macOS (this crate is macOS-only)
## ๐ง Platform Requirements
- **macOS 12.3+** (Monterey) - Base `ScreenCaptureKit` support
- **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 `NSScreenCaptureUsageDescription` to your `Info.plist`
- Sign with appropriate entitlements for notarization
## โก Performance
Run benchmarks to measure performance on your hardware:
```bash
cargo bench
```
See [`docs/BENCHMARKS.md`](docs/BENCHMARKS.md) for detailed benchmark documentation including:
- API overhead measurements
- Frame throughput at various resolutions
- First-frame latency
- Pixel buffer and `IOSurface` access 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`](docs/MIGRATION.md) for:
- API changes between versions
- Code examples for common migrations
- Deprecated API replacements
## ๐ค Contributing
Contributions welcome! Please:
1. Follow existing code patterns (builder pattern with `::new()` and `.with_*()` methods)
2. Add tests for new functionality
3. Run `cargo test` and `cargo clippy`
4. Update documentation
## ๐ Used By
This crate is used by some amazing projects:
- **[AFFiNE](https://github.com/toeverything/AFFiNE)** - Next-gen knowledge base, alternative to Notion and Miro (50k+ โญ)
- **[Vibe](https://github.com/thewh1teagle/vibe)** - Transcribe on your own! Local transcription tool (5k+ โญ)
- **[Lycoris](https://github.com/solaoi/lycoris)** - Real-time speech recognition & AI-powered note-taking for macOS
*Using screencapturekit-rs? [Let us know](https://github.com/doom-fish/screencapturekit-rs/issues) and we'll add you to the list!*
## ๐ฅ Contributors
Thanks to everyone who has contributed to this project!
- [Per Johansson](https://github.com/doom-fish) - Maintainer
- [Iason Paraskevopoulos](https://github.com/iasparaskev)
- [Kris Krolak](https://github.com/kriskrolak)
- [Tokuhiro Matsuno](https://github.com/tokuhirom)
- [Pranav Joglekar](https://github.com/pranavj1001)
- [Alex Jiao](https://github.com/uohzxela)
- [Charles](https://github.com/aizukanne)
- [bigduu](https://github.com/bigduu)
- [Andrew N](https://github.com/adnissen)
## ๐ License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT License ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
at your option.