Skip to content

Itz-Agasta/pinray

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pinray

Cross-platform screen and audio capture for Rust — raw frames, real metadata, native backends.

Crates.io Documentation CI License: MIT MSRV

Getting StartedPlatform SupportTroubleshootingAPI DocsType reference (any platform)

banner


pinray is a capture infrastructure crate: it talks to each OS's native capture API and hands you raw video and audio frames with their metadata intact - stride, pixel format, timestamps, sequence numbers, drop signals. Encoding is deliberately out of scope; pipe frames into ffmpeg, WebRTC, wgpu, image crates, or your own pipeline.

Why pinray

  • Native backends, no wrapper crates - XDG Desktop Portal + PipeWire and X11 on Linux, ScreenCaptureKit (via objc2) on macOS, DXGI Desktop Duplication + Windows Graphics Capture + WASAPI (via the windows crate) on Windows.
  • Audio is first-class - system-mix capture on all four backends, timestamped on the same clock as video, no cpal detour and no shelling out to pactl.
  • A frame model that doesn't lie - every frame carries width/height/stride, pixel format, color-space hint, a monotonic timestamp, and a per-stream sequence number. Dropped frames surface as explicit Gap events.
  • Inspectable backend selection - Auto picks the right backend per platform (with fallbacks like DXGI→WGC), and session.backend_info() tells you exactly what you got and its caveats.
  • Honest about platform differences - X11 is documented as polling, DXGI as change-driven, Wayland as portal-mediated. No pretending all platforms behave the same.

Platform support

Video System audio Notes
Linux Wayland ✅ portal + PipeWire streaming ✅ PipeWire restore tokens skip the dialog
Linux X11 ✅ paced polling (GetImage) ✅ PipeWire XFixes cursor blend
macOS 12.3+ ✅ ScreenCaptureKit ✅ ScreenCaptureKit display + window capture
Windows 10+ ✅ DXGI + WGC ✅ WASAPI loopback DXGI→WGC auto-fallback

Full matrix with per-backend limitations: docs/platforms.md.

Quick start

cargo add pinray
use std::time::Duration;
use pinray::{AudioCapture, CaptureEvent, CaptureSession, SourceId, VideoCaptureTarget};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Capture the primary display plus everything the system plays.
    let mut session = CaptureSession::builder()
        .video_target(VideoCaptureTarget::Display(SourceId::new("auto")))
        .audio(AudioCapture::SystemMix)
        .build()?;

    println!("backend: {:?}", session.backend_info().kind);
    session.start()?;

    loop {
        match session.next_event(Some(Duration::from_secs(5)))? {
            CaptureEvent::Video(f) => println!("video {}x{} t={}ns", f.width, f.height, f.stream_time_ns),
            CaptureEvent::Audio(f) => println!("audio {} Hz {}ch", f.sample_rate, f.channels),
            CaptureEvent::Gap(g) => println!("gap: {:?}", g.reason),
            CaptureEvent::End => break,
        }
    }

    session.stop()?;
    Ok(())
}

Pick specific displays/windows with pinray::enumerate_sources(), capture audio-only without any permission dialogs, force a backend with BackendPreference - see Getting started.

Requirements

Platform Build Runtime
Linux libpipewire-0.3-dev + clang PipeWire; XDG portal for Wayland video
macOS - macOS 12.3+, Screen Recording permission
Windows - Windows 10+ (WGC needs 1903+)

Examples

cargo run --example wayland_smoke    # Linux Wayland: video + audio
cargo run --example x11_smoke        # Linux X11: polling video + audio
cargo run --example audio_smoke      # Linux/Windows: audio only
cargo run --example macos_smoke      # macOS
cargo run --example windows_smoke    # Windows (PINRAY_BACKEND=wgc|dxgi to force)

Architecture

Cargo workspace: pinray-core defines the frame model and backend traits, one crate per platform owns its native/unsafe code (platform-linux, platform-macos, platform-windows), and pinray is the public facade. A future encoder crate can slot in without touching capture.

Stability

pinray is 0.2 and moving fast: minor versions may break the API while the frame model and builder settle against real-world use. Pin a minor version if you need stability.

Minimum supported Rust version

Rust 1.88 (let-chains). MSRV bumps are minor-version changes during 0.2.

Contributing

Issues and PRs welcome. Please include session.backend_info() output and RUST_LOG=debug logs in bug reports - backend selection differs per machine. CI runs clippy (warnings deny), tests on Linux/macOS/Windows, cross-target checks, and a real Xvfb capture smoke test.

License

MIT - see LICENSE. Contact: rupamgolui@proton.me

About

Cross-platform screen & system-audio capture for Rust. Raw frames + real metadata from native backends: PipeWire/X11, ScreenCaptureKit, DXGI/WGC/WASAPI. No ffmpeg, no wrappers.

Topics

Resources

License

Stars

15 stars

Watchers

0 watching

Forks

Contributors

Languages