Dokumentation · Version 1.0.0
VeloFrame einbauen
Alles, was du brauchst, um Screenshots und Clips in deine App zu holen.
Ü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}}
- Prozess starten. VeloFrame meldet sich mit einem
ready-Event und wärmt die Aufnahme auf allen Bildschirmen vor. - Anfragen mit einer eindeutigen
idschicken, eine pro Zeile. - Antworten über die
idzuordnen.oksagt, 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
| Befehl | Argumente | Ergebnis |
|---|---|---|
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) |
screenshot | format (png/jpeg), quality, cursor, area (screen/window), screen, folder, clipboard | Pfad, Größe, Bytes, Quelle, Zeiten pro Schritt |
copy | path | Letzten Screenshot erneut in die Zwischenablage, sonst Fehler not-cached |
buffer-start | mode (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-clip | folder, optional seconds | Pfad, 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"}
| Code | Bedeutung |
|---|---|
invalid-request | Anfrage unvollständig oder falsch aufgebaut |
no-screen | Kein passender Bildschirm gefunden |
capture-lost | Aufnahme verloren (Auflösungswechsel, UAC, Vollbildwechsel). VeloFrame öffnet einmal neu und versucht es noch mal |
capture-failed | Aufnahme fehlgeschlagen |
save-failed | Datei konnte nicht gespeichert werden |
clipboard-failed | Zwischenablage nicht verfügbar |
not-cached | Für copy liegt kein Screenshot im Speicher |
unsupported | Auf 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
| Performance | Long | |
|---|---|---|
| Länge | 5–60 s | 5–300 s |
| Codec | HEVC (wenn die GPU es kann), sonst H.264 | H.264 (läuft überall) |
| Bitrate 1080p60 „high“ | Schnitt 6,2 / max. 10,4 Mbit/s, folgt dem Inhalt | Schnitt 13,6 / max. 16 Mbit/s |
| Keyframe | alle 2 s | jede Sekunde |
| Encoder-Aufwand | 85, wird bei Bedarf gesenkt | 70, wird bei Bedarf gesenkt |
| GPU-Priorität | hinter dem Spiel | normal |
| Puffer | temporäre Datei | temporä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:
ScreenSourceliefert ein Bild eines Desktop-Bereichs (Desktop Duplication, später Windows Graphics Capture, ScreenCaptureKit, PipeWire).Desktopliefert Vordergrundfenster, Mauszeiger, Zwischenablage und Zeitstempel.
| Ordner | Crate | Inhalt |
|---|---|---|
core | veloframe-core | Bildtypen, Schnittstellen, Screenshot-Pipeline, eigene Encoder, Clip-Modi, Replay-Puffer, MP4-Writer, Protokoll, Fehler |
engine | veloframe | Engine-API (Engine) und das Programm veloframe.exe |
Win | veloframe-win | Desktop Duplication, Mauszeiger, Zwischenablage, System-Check, Clip-Puffer (GPU-Aufnahme, NV12, Hardware-Encoder) |
Mac | veloframe-mac | ScreenCaptureKit, VideoToolbox (in Arbeit) |
Linux | veloframe-linux | PipeWire, xdg-desktop-portal, X11, VAAPI (in Arbeit) |
bench | veloframe-bench | Benchmark-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
| Zustand | Task-Manager | Working Set gesamt | Reserviert |
|---|---|---|---|
| Nach Start + Warm-up | 23,5 MB | 45,5 MB | 57,5 MB |
| Nach Screenshots | 29,9 MB | 52,1 MB | 64,1 MB |
| Nach Screenshot mit Zwischenablage | 37,9 MB | 60,1 MB | 72,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
| Plattform | Status | Technik |
|---|---|---|
| Windows 10 / 11 | Verfügbar | Desktop Duplication, Media Foundation, D3D11 |
| macOS | In Arbeit | ScreenCaptureKit, VideoToolbox |
| Linux | In Arbeit | PipeWire, 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
| Phase | Inhalt | Status |
|---|---|---|
| 0 · Fundament | Typen, IPC-Protokoll kompatibel zu ClipHub | Fertig |
| 1 · Desktop Duplication | Alles, was der ClipHub-Helper kann: Monitore, Drehung, DPI, aktives Fenster, PNG/JPEG, Zwischenablage | Fertig |
| Zwischenschritt · Tempo | Vorwärmen, eigene Encoder auf allen Kernen, Benchmark-Tool | Fertig |
| 2 · Windows Graphics Capture | Einzelne Fenster aufnehmen, auch wenn etwas darüber liegt | Geplant |
| 3 · GPU-Verarbeitung | Zuschneiden und HDR → SDR per Shader | Geplant |
| 4 · Ausgabe | WebP und Metadaten (Zeit, Spielname, Monitor) | Teilweise |
| 5 · Automatische Auswahl | Bester Aufnahmeweg mit Fallback, kein Screenshot schlägt ohne Grund fehl | Geplant |
| 6 · Benchmark & Feinschliff | FPS-Verlust im Spiel messen, Vergleich mit dem alten Helper | Geplant |
Ziele
| Messgröße | Ziel |
|---|---|
| Taste bis fertige Datei, 1440p, JPEG | unter 50 ms |
| Taste bis fertige Datei, 1440p, PNG | unter 150 ms |
| FPS-Verlust im Spiel | nicht messbar (unter 1 %) |
| RAM im Leerlauf | unter 30 MB |
| CPU im Leerlauf | nahe 0 % |
Open Source und Lizenz
VeloFrame ist Open Source. Der komplette Quellcode liegt auf GitHub: github.com/LiGLP-Studios/VeloFrame.
| Nutzung | Was du brauchst |
|---|---|
| Open-Source-Projekte | Frei nutzbar, keine Lizenz von LiGLP Studios nötig |
| Business-Nutzung | Lizenz von LiGLP Studios |
| Apps, die nicht Open Source sind | Lizenz von LiGLP Studios |
Lizenz anfragen: Für Business-Nutzung oder Closed-Source-Apps schreib an business@liglp.de oder melde dich über liglp.de.