Dokumentation · Version 1.0.0

VeloFrame einbauen

Alles, was du brauchst, um Screenshots und Clips in deine App zu holen.

Windows macOS in Arbeit Linux in Arbeit

Überblick

VeloFrame wurde extra für ClipHub geschrieben, die Clipping-App von LiGLP Studios, und ist Open Source: github.com/LiGLP-Studios/VeloFrame. Für Business-Nutzung oder Apps, die nicht Open Source sind, brauchst du eine Lizenz von LiGLP Studios.

VeloFrame hat keine Benutzeroberfläche. Die Host-App (zum Beispiel ClipHub) entscheidet, wann aufgenommen wird, per Hotkey, Button oder Automatik, und was mit dem Ergebnis passiert. VeloFrame macht die Aufnahme.

  • Nur Engine. Hotkeys, Einstellungen und Anzeige gehören der Host-App. VeloFrame bekommt fertige Anfragen und liefert Ergebnisse mit Messwerten.
  • Zwei Wege zum Einbetten. Als Rust-Bibliothek (veloframe::Engine) oder als eigener Prozess (veloframe.exe, JSON-Zeilen über stdin/stdout). Der Prozess schützt die Host-App vor Abstürzen und funktioniert mit jeder Sprache.
  • Warm bleiben. warm_up() öffnet die Aufnahme vorab, Puffer werden wiederverwendet. Auch der erste Screenshot ist schnell.
  • Alles wird gemessen. Jede Antwort enthält die Zeiten pro Schritt und welche Quelle das Bild geliefert hat.

Noch nicht dabei: Ton in Clips, Mauszeiger im Video, Windows Graphics Capture (Phase 2) sowie macOS und Linux. An der Mac- und Linux-Version wird gearbeitet.

Bauen, testen, messen

VeloFrame ist ein Rust-Workspace. Der Release-Build landet unter target/release/veloframe.exe.

cargo build --release
cargo test --workspace

# Benchmarks
cargo run --release -p veloframe-bench -- encode "Screenshot.png"   # Encoder vergleichen
cargo run --release -p veloframe-bench -- capture 20                 # echte Screenshots messen
cargo run --release -p veloframe-bench -- memory                     # Speicher nach jedem Schritt
cargo run --release -p veloframe-bench -- clip performance 30        # Clip-Puffer messen und prüfen
cargo run --release -p veloframe-bench -- clip long 60

Als Rust-Bibliothek

Der direkte Weg für Rust-Apps. warm_up() öffnet die Aufnahme vorab, damit schon der erste Screenshot schnell ist.

use veloframe::{Engine, ScreenshotRequest, ImageFormat, Area, Rect};

let mut engine = Engine::new()?;
engine.warm_up()?;                         // Aufnahme vorab öffnen
let shot = engine.screenshot(&ScreenshotRequest {
    format: ImageFormat::Jpeg,
    quality: 90,
    cursor: false,
    area: Area::Window,                    // Vordergrundfenster, sonst der Bildschirm
    screen: Rect::new(0, 0, 2560, 1440),   // physische Pixel
    folder: "C:\\Users\\Name\\Pictures\\Screenshots".into(),
    clipboard: true,                       // parallel zum Kodieren in die Zwischenablage
})?;
println!("{} in {:.1} ms", shot.path, shot.total_ms);

Als eigener Prozess

Für Electron, Node, Python, C# und alles andere: veloframe.exe starten und pro Zeile eine JSON-Nachricht auf stdin schicken. Antworten kommen Zeile für Zeile auf stdout. Stürzt die Engine ab, läuft die Host-App weiter.

→ {"id":1,"cmd":"screenshot","args":{"format":"png","area":"screen",
     "screen":{"x":0,"y":0,"width":1920,"height":1080},"folder":"C:\\Pictures"}}

← {"id":1,"ok":true,"result":{"path":"C:\\Pictures\\Screenshot 2026-11-05 163141.png",
     "width":1920,"height":1080,"captureMs":4.0,"encodeMs":25.0,"totalMs":29.0,"warm":true}}
  1. Prozess starten. VeloFrame meldet sich mit einem ready-Event und wärmt die Aufnahme auf allen Bildschirmen vor.
  2. Anfragen mit einer eindeutigen id schicken, eine pro Zeile.
  3. Antworten über die id zuordnen. ok sagt, ob es geklappt hat.

Das Protokoll ist kompatibel zum bisherigen ClipHub-Capture-Helper. ClipHub kann veloframe.exe statt cliphub-capture.exe starten, ohne den Electron-Code zu ändern.

Befehle

BefehlArgumenteErgebnis
ping–"pong"
version–Engine, Version, aktive Bildquelle
system-check–Grafikkarten, Monitore, HDR, Encoder, verfügbare Aufnahmewege
warm-up–Aufnahme auf allen Bildschirmen vorab öffnen (macht veloframe.exe beim Start selbst)
screenshotformat (png/jpeg), quality, cursor, area (screen/window), screen, folder, clipboardPfad, Größe, Bytes, Quelle, Zeiten pro Schritt
copypathLetzten Screenshot erneut in die Zwischenablage, sonst Fehler not-cached
buffer-startmode (performance/long), seconds, fps, quality (low…ultra), resolution (native, 1440p, 1080p, 720p), screen, optional codec (h264/hevc), storage (file/ram)Plan, Encoder, übernommene Einstellungen
buffer-status–Sekunden und Bytes im Puffer, kodierte und verlorene Bilder (nach Grund), Encoder-Aufwand
save-clipfolder, optional secondsPfad, Größe, Dauer, Bilder, Codec, Speicherzeit
buffer-stop–Puffer stoppen, Speicher und Encoder freigeben

Zeiten in jeder Antwort

Screenshot-Antworten enthalten captureMs, encodeMs, writeMs, totalMs und clipboardMs. So siehst du immer, wo Zeit verloren geht.

Fehler

Fehler haben einen festen Code für die App und eine Meldung, die du deinen Nutzern direkt zeigen kannst. Reagiere im Code auf code, nicht auf den Text.

{"id":1,"ok":false,"error":"Meldung für den Nutzer","code":"no-screen"}
CodeBedeutung
invalid-requestAnfrage unvollständig oder falsch aufgebaut
no-screenKein passender Bildschirm gefunden
capture-lostAufnahme verloren (Auflösungswechsel, UAC, Vollbildwechsel). VeloFrame öffnet einmal neu und versucht es noch mal
capture-failedAufnahme fehlgeschlagen
save-failedDatei konnte nicht gespeichert werden
clipboard-failedZwischenablage nicht verfügbar
not-cachedFür copy liegt kein Screenshot im Speicher
unsupportedAuf diesem System nicht möglich

Screenshots

Ablauf einer Screenshot-Anfrage, vom Aufruf bis zur Datei:

Anfrage (Rust-API oder JSON-Zeile)
  └─ ScreenshotPipeline::take                      core/pipeline.rs
       ├─ Ziel: Bildschirm oder Vordergrundfenster
       ├─ ScreenSource::capture -> RgbImage        Win/duplication.rs
       │    └─ Bildschirm mit dem größten Anteil am Ziel, D3D-Gerät auf seiner GPU,
       │       BGRA -> RGB (4 Pixel pro Schritt), Drehung berücksichtigt
       ├─ Mauszeiger zeichnen (optional)           Win/desktop.rs
       ├─ parallel: Zwischenablage (eigener Thread) Win/clipboard.rs
       │            PNG/JPEG im Speicher kodieren   core/codec (alle Kerne)
       │            dann in einem Rutsch schreiben  core/screenshot.rs
       └─ Ergebnis mit Messwerten; Bild bleibt für `copy` im Speicher

Eigene Encoder

Beide teilen das Bild in waagerechte Streifen, einen pro CPU-Kern, und setzen die Teile zu einer ganz normalen Datei zusammen.

  • PNG: Pro Zeile werden alle fünf PNG-Filter berechnet (mit AVX2, wenn die CPU es kann), der beste gewinnt. Danach ein eigener DEFLATE-Encoder mit eigenem Huffman-Code pro Streifen. Verlustfrei geprüft.
  • JPEG: Jeder Streifen wird einzeln kodiert (SIMD) und über Restart-Marker verbunden. Die Datei dekodiert Pixel für Pixel genau wie ein einzelner Durchlauf.
  • Das Spiel geht vor: Die Helfer-Threads laufen unter normaler Priorität und nutzen nur CPU-Zeit, die gerade frei ist.

Clip-Engine

Der Clip-Puffer nimmt einen Bildschirm laufend auf, kodiert in Hardware und hält die letzten Sekunden bereit. Auf Anfrage werden sie als MP4 gespeichert, ohne neu zu kodieren.

Modi

PerformanceLong
Länge5–60 s5–300 s
CodecHEVC (wenn die GPU es kann), sonst H.264H.264 (läuft überall)
Bitrate 1080p60 „high“Schnitt 6,2 / max. 10,4 Mbit/s, folgt dem InhaltSchnitt 13,6 / max. 16 Mbit/s
Keyframealle 2 sjede Sekunde
Encoder-Aufwand85, wird bei Bedarf gesenkt70, wird bei Bedarf gesenkt
GPU-Prioritäthinter dem Spielnormal
Puffertemporäre Dateitemporäre Datei

Codec und Pufferort lassen sich pro Anfrage überschreiben (codec, storage).

Ablauf pro Bild (60 fps = alle 16,7 ms)

Desktop Duplication ─► GPU-Textur (nur wenn sich etwas geändert hat)
        │
GPU-Videoprozessor: BGRA → NV12, BT.709, Skalierung ─► Bild aus dem Encoder-Pool
        │
Warteschlange (bis 4 Bilder) ─► Hardware-Encoder (NVENC / AMF / QuickSync)
        │
Pakete ─► Replay-Puffer (fester Ring, vorne immer ein Keyframe)
        │
save-clip ─► MP4 (Index vorne, Pakete unverändert)

Was VeloFrame selbst erledigt

  • Warteschlange vor dem Encoder: Kurze Verzögerungen kosten kein Bild mehr. Verlorene Bilder unter Last: von 8–11 % auf 0,4–1,6 %.
  • Regler für den Encoder-Aufwand: Gehen mehr als 1 % der Bilder verloren, senkt VeloFrame den Aufwand im Betrieb und hebt ihn wieder an, sobald Luft da ist. Flüssiges Video geht vor dem letzten Prozent Kompression.
  • Puffer in einer temporären Datei: Windows hält sie möglichst im Cache und gibt den Speicher jederzeit ans Spiel zurück. Beim Beenden wird sie gelöscht, auch nach einem Absturz.
  • Speichern ohne Kopie: Der Index wird unter Sperre kopiert, die Daten danach gelesen, während die Aufnahme weiterläuft.
  • Eine Aufnahme für beides: Läuft der Puffer, kommen Screenshots desselben Bildschirms aus dem Live-Bild (17 ms gesamt).
  • Sauberes Beenden: Der Encoder wird vor dem Herunterfahren geleert. 40 von 40 Läufen enden sauber.

Bekannte Einschränkungen

  • Noch kein Ton und kein Mauszeiger im Video.
  • Ein Bildschirm pro Puffer, gedrehte Bildschirme noch nicht unterstützt.
  • Ein Clip beginnt am letzten Keyframe vor dem gewünschten Start (Performance: bis zu 2 s früher). Bildgenauer Start ist noch offen.
  • Windows 10 spielt HEVC nur mit den „HEVC-Videoerweiterungen“ aus dem Microsoft Store ab. Browser (Chrome, Edge, Electron) können HEVC mit Hardware-Unterstützung. Für maximale Kompatibilität codec: "h264" nutzen.
  • Der NVIDIA-HEVC-Encoder nimmt keine B-Frames an.

Architektur

Der Ablauf liegt plattformunabhängig in core. Die Plattform-Crates setzen nur zwei Schnittstellen um:

  • ScreenSource liefert ein Bild eines Desktop-Bereichs (Desktop Duplication, später Windows Graphics Capture, ScreenCaptureKit, PipeWire).
  • Desktop liefert Vordergrundfenster, Mauszeiger, Zwischenablage und Zeitstempel.
OrdnerCrateInhalt
coreveloframe-coreBildtypen, Schnittstellen, Screenshot-Pipeline, eigene Encoder, Clip-Modi, Replay-Puffer, MP4-Writer, Protokoll, Fehler
engineveloframeEngine-API (Engine) und das Programm veloframe.exe
Winveloframe-winDesktop Duplication, Mauszeiger, Zwischenablage, System-Check, Clip-Puffer (GPU-Aufnahme, NV12, Hardware-Encoder)
Macveloframe-macScreenCaptureKit, VideoToolbox (in Arbeit)
Linuxveloframe-linuxPipeWire, xdg-desktop-portal, X11, VAAPI (in Arbeit)
benchveloframe-benchBenchmark-Tool: Encoder vergleichen, Screenshots, Speicher und Clip-Puffer messen

Messwerte

Release-Build, Intel Core i5-6400 (4 Kerne), RTX 3050, Windows 10, zwei Monitore an zwei GPUs. Unter Last gemessen: andere Programme nutzten bereits 60–70 % der CPU.

Speicher der Screenshot-Engine

ZustandTask-ManagerWorking Set gesamtReserviert
Nach Start + Warm-up23,5 MB45,5 MB57,5 MB
Nach Screenshots29,9 MB52,1 MB64,1 MB
Nach Screenshot mit Zwischenablage37,9 MB60,1 MB72,0 MB
  • Task-Manager zeigt den privaten Speicher, den nur VeloFrame nutzt.
  • Working Set gesamt enthält zusätzlich die Grafiktreiber (etwa 22 MB), die sich alle Programme auf derselben GPU teilen, auch das Spiel.
  • CPU im Leerlauf: 0,00 %, kein Polling im Hintergrund. 20 weitere Screenshots ändern den Verbrauch um weniger als 1 MB, also kein Speicherleck.

Plattformen

PlattformStatusTechnik
Windows 10 / 11VerfügbarDesktop Duplication, Media Foundation, D3D11
macOSIn ArbeitScreenCaptureKit, VideoToolbox
LinuxIn ArbeitPipeWire, xdg-desktop-portal, X11, VAAPI

An der Mac- und Linux-Version wird noch gearbeitet. Die Schnittstellen sind dieselben wie unter Windows, deine Einbindung muss dafür später nicht geändert werden.

Roadmap für Windows

PhaseInhaltStatus
0 · FundamentTypen, IPC-Protokoll kompatibel zu ClipHubFertig
1 · Desktop DuplicationAlles, was der ClipHub-Helper kann: Monitore, Drehung, DPI, aktives Fenster, PNG/JPEG, ZwischenablageFertig
Zwischenschritt · TempoVorwärmen, eigene Encoder auf allen Kernen, Benchmark-ToolFertig
2 · Windows Graphics CaptureEinzelne Fenster aufnehmen, auch wenn etwas darüber liegtGeplant
3 · GPU-VerarbeitungZuschneiden und HDR → SDR per ShaderGeplant
4 · AusgabeWebP und Metadaten (Zeit, Spielname, Monitor)Teilweise
5 · Automatische AuswahlBester Aufnahmeweg mit Fallback, kein Screenshot schlägt ohne Grund fehlGeplant
6 · Benchmark & FeinschliffFPS-Verlust im Spiel messen, Vergleich mit dem alten HelperGeplant

Ziele

MessgrößeZiel
Taste bis fertige Datei, 1440p, JPEGunter 50 ms
Taste bis fertige Datei, 1440p, PNGunter 150 ms
FPS-Verlust im Spielnicht messbar (unter 1 %)
RAM im Leerlaufunter 30 MB
CPU im Leerlaufnahe 0 %

Open Source und Lizenz

VeloFrame ist Open Source. Der komplette Quellcode liegt auf GitHub: github.com/LiGLP-Studios/VeloFrame.

NutzungWas du brauchst
Open-Source-ProjekteFrei nutzbar, keine Lizenz von LiGLP Studios nötig
Business-NutzungLizenz von LiGLP Studios
Apps, die nicht Open Source sindLizenz von LiGLP Studios

Lizenz anfragen: Für Business-Nutzung oder Closed-Source-Apps schreib an business@liglp.de oder melde dich über .