Codync
무료 오픈소스 1:1 대안, Grok Bot과 Muse 대신
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Programmatic video capture and screenshots for .NET games and apps: trailer footage, store screenshots, devlog clips and bug-repro video, triggered from code when something happens or recorded for a whole run, with adapters for desktop, WPF, WebView2 and Unity.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Programmatic video capture and screenshots for MindAttic games and apps: trailer footage, store screenshots, devlog clips and bug-repro video, triggered from code or recorded by hand from the tray.
capture-tray.exe) for hand recording: screens, any open app, or a dragged area.-capture command-line flag, understood by every wired MindAttic GUI app.capture recover. your app / game MindAttic.Capture R:\MindAttic\Capture\
─────────────── ───────────────── ─────────────────────
Capture.Raise("critical-hit") ──> trigger rules ──> replay / clip / screenshot ──> {RepoName}\{RepoName}_{timestamp}.{ext}
-capture video / screen N ──> session tape (1 s segments, lossless FFV1) ──> {RepoName}_{start}.mkv + .mp4
ScreenshotAsync / ClipAsync ──> host adapter (desktop, WPF, WebView2, Unity) *.png *.mp4 *.json sidecars
session.json manifest
| Package | Target | What it does |
|---|---|---|
MindAttic.Capture | netstandard2.1; net10.0 | Core: API, -capture parsing, trigger rules, rolling tape, exports, sidecars, session manifest. No third-party dependencies (Unity consumes the netstandard2.1 build). |
MindAttic.Capture.Windows | net10.0-windows10.0.19041 | Desktop capture: Windows Graphics Capture for windows, Desktop Duplication / GDI for monitors and regions, WASAPI audio, global hotkeys, DI. |
MindAttic.Capture.Wpf | net10.0-windows10.0.19041 | CaptureWpf.Init(this, e.Args): records the main window at native size, export on exit. |
MindAttic.Capture.WebView2 | net10.0-windows10.0.19041 | window.mindattic.capture JavaScript bridge for any WebView2. |
capture.exe (agent) | net10.0-windows10.0.19041 | CLI and localhost API: record any app with no code changes, serve browser pages and scripts, finalize and recover sessions. |
com.mindattic.capture (Unity) | Unity 6, Windows | Game-view capture via GPU readback, game audio, Play Mode menu; reads -capture from the player command line. |
The agent and the tray recorder are installed together (see Install and deploy below). With the agent installed, apps hand their session export to it and exit immediately.
Run run.ps1 from the repo root. It installs the agent (capture.exe) and tray recorder (capture-tray.exe) only when the source is newer than the installed copy, so it is cheap to run every time.
.\run.ps1 # install if stale
.\run.ps1 -Force # install even if the installed copy looks current
.\run.ps1 -Launch # also start the tray recorder
%LOCALAPPDATA%\MindAttic\Capture\bin, where DesktopCapture finds the agent for other apps.C:\Apps\MindAttic.Capture\run.bat (under %LOCALAPPDATA%\Programs when C:\Apps is missing). The desktop shortcut MindAttic Capture opens that file, which asks first: 1) Deploy & Run reinstalls (-Force -Launch) and starts the tray recorder; 2) Run just starts the installed tray recorder. .\run.ps1 -LauncherOnly rewrites the launcher and shortcut without installing anything.tools\install.ps1 is the underlying installer; add -AddToPath to get capture on PATH everywhere. A file in use is renamed to *.old and replaced, so installing is safe while an export runs.capture-tray.exe sits in the system tray and records without any code changes. The icon turns red with the elapsed time while recording, and a left-click stops it.
Ctrl+Alt+Shift+R starts and stops recording whatever is armed, Ctrl+Alt+Shift+S takes a screenshot. Both are rebindable in Settings.%LOCALAPPDATA%\MindAttic\Capture\tray.json.Video is encoded by ffmpeg (choco install ffmpeg, or put ffmpeg.exe next to the app). Hardware encoders (NVENC → QuickSync → AMF) are probed automatically, with a software fallback.
Everything video comes from one tape: a recorder writing 1-second segments to
{root}\.staging\. A recording, clip, replay or session is just a time range cut from the
tape. Starting a recording is instant, and SaveReplay(before, after) can include footage from
before the event. The tape is lossless FFV1 (TapeQuality.Lossless) or hardware HEVC
(HighQuality). Exports produce a .mkv master plus, depending on the preset, an H.264 .mp4
that imports into any editor, WebM, GIF or animated WebP, and a thumbnail.
-capture flagEvery MindAttic GUI app wired to MindAttic.Capture understands the same flag:
Game.exe -capture video # film from start to exit at the app's native resolution
Game.exe -capture screen 5 # a PNG every 5 seconds until exit (also 500ms, 10s, 1m)
Game.exe -capture video screen 5 # both
Game.exe -demo -capture video hq # hardware HEVC tape (~0.2 GB/min) instead of lossless
Game.exe -capture video 8h # stop after 8 hours (the shut-off valve can stop it sooner)
Game.exe -capture # same as -capture video
Game.exe -capture video -capture-config capture.json # explicitly opt into settings/rules from a file
Capture is off unless the -capture flag is literally on the command line: there is no environment
variable and no project config auto-loaded on launch, so a plain launch is always a plain launch.
-capture-config path.json is the one way to bring in settings or trigger rules, and it is opt-in —
you have to pass it yourself.
-capture followed by anything that isn't a capture word (for example an app's own -capture <folder>)
is left alone. -demo and other flags belong to the app: capture only records what runs.
When the app closes, the session goes to R:\MindAttic\Capture\{RepoName}\{RepoName}_{session start}.mkv
and .mp4, alongside every screenshot, clip and replay its events triggered. If capture.exe is
installed, the export runs in a detached process so the app exits immediately. If the app
crashes, a job object stops ffmpeg, the finished segments stay on disk, and the next launch (or
capture recover) exports them as session-recovered.
If R: is missing, output falls back to %USERPROFILE%\Videos\MindAttic with a warning.
A long run can't fill the disk or exhaust memory. While capture runs, the engine polls the machine every 5 s. The first limit crossed stops capture and exports everything recorded so far, exactly as if the app had closed. The app keeps running, and nothing is deleted.
Limit (limits in capture.json) | Default | Why |
|---|---|---|
minFreeDiskGB | 50 | output (and staging) drive nearly full |
minFreeMemoryMB | 2048 | the machine is running out of RAM |
maxEncoderMemoryMB | 4096 | frames are backing up inside ffmpeg (the drive or CPU can't keep up) |
maxEncoderLagSeconds | 60 | the encoder is that far behind real time |
maxDuration | off | -capture video 8h, or "maxDuration": "8h" |
Set a limit to 0 to turn it off, or "enabled": false to turn off all the resource limits; a duration cap (-capture video 8h or "maxDuration") still applies. Flags on the command line win over the config file.
pollEvery changes the interval. Every poll is appended to {RepoName}_{start}.stats.csv. That
file records free disk, available RAM, CPU, app and encoder memory, encoder lag, tape time,
frames written and dropped, and the drive's write rate. The engine log goes to
{RepoName}_{start}.log, with a status line each minute. The session manifest records the
lowest and highest values seen, plus stoppedBy when the valve closed.
WPF app (one line in App.OnStartup, before showing the main window):
CaptureWpf.Init(this, e.Args); // -capture video / -capture screen N; capture.json beside the exe for rules
The app's project needs net10.0-windows10.0.19041.0 (or later) and MINDATTIC_CAPTURE in
DefineConstants for Capture.Raise hooks. Automata is the worked example.
Unity game: add to Packages/manifest.json
"com.mindattic.capture": "file:../../MindAttic.Capture/unity/com.mindattic.capture". Players
then honor -capture video / -capture screen 5 and nothing else — there is no project config
auto-loaded from StreamingAssets, so a plain launch never has capture silently on or off by
surprise; in the editor use MindAttic ▸ Capture to record Play Mode. Game code raises events
with CaptureUnity.Raise("battle-complete"); to bring in rules, pass -capture-config path.json
explicitly.
Websites: C:\Apps\MindAttic.Browser\MindAttic.Browser.exe <url | site folder> -capture video. Capture
always uses this deployed copy of MindAttic.Browser (capture run --url
included); deploy or refresh it with that repo's run.ps1. A folder is served at
https://<folder>.local/, and its captures are named after the folder (mindattic.com\mindattic.com_<timestamp>.mkv)
or, for generic folders like dist or wwwroot, after the repository. A URL's captures are named after its host. Pages (in the browser, any WebView2 with the bridge, or plain browsers
with capture serve) call:
mindattic.capture.raise('critical-hit', { damage: 912 });
await mindattic.capture.screenshot('victory');
await mindattic.capture.replay(15, 5, 'boss-death');
Windows app (in-process, any UI framework):
await using var capture = await DesktopCapture.StartAsync(CaptureTarget.CurrentApp, args,
o => { o.AppName = "GridGame"; o.ReplayArmed = true; });
// anywhere in game/app code (compiled out when MINDATTIC_CAPTURE is not defined):
Capture.Raise("critical-hit", new CaptureData { ["damage"] = 912 });
Capture.Marker("boss-phase-2");
Capture.Screenshot("victory");
// or the instance API:
var shot = await capture.Engine.ScreenshotAsync("store-shot");
var clip = await capture.Engine.ClipAsync(TimeSpan.FromSeconds(10), "devlog", new() { Preset = CapturePreset.Devlog });
var replay = await capture.Engine.SaveReplayAsync(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(5), "boss-death");
capture.Engine.Triggers.On("boss-death").Replay(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(5)).Cooldown(TimeSpan.FromSeconds(30));
Any app, no code changes (agent):
capture run -- Game.exe -demo # record the app's window from launch to exit
capture run --window "Notepad" -- notepad.exe # launcher stubs: name the real window
capture run --url http://localhost:5173 # record a web app in the deployed MindAttic Browser
capture shot --region 0,0,1920,1080 --format png
capture record --monitor 0 --duration 30s --preset devlog
capture replay --window "GridGame" --length 30s # Enter or `capture save` saves the last 30 s
capture serve --window "Tutor" # localhost API for browser pages and scripts
capture raise critical-hit damage=900 # send an event to `capture serve`
capture recover R:\MindAttic\Capture # export sessions left by crashed apps
Targets: --monitor N, --region x,y,w,h, --window "title", --hwnd 0x1234, --process name.
Placed beside the exe (picked up automatically), or passed with -capture-config / --config:
{
"enabled": true,
"outputRoot": "R:\\Recording",
"fileTemplate": "{app}_{timestamp}",
"tapeQuality": "Lossless",
"audio": "App",
"replay": { "armed": true, "seconds": 30 },
"rules": [
{ "on": "critical-hit", "action": "replay", "before": "5s", "after": "2s",
"where": { "damage": ">=500" }, "debounce": "1s", "maxPerSession": 25 },
{ "on": "battle-complete", "action": "screenshot", "tag": "victory", "cooldown": "10s" },
{ "on": "boss-death", "action": "replay", "before": "15s", "after": "5s", "preset": "Trailer" },
{ "on": "battle-*", "action": "marker" }
],
"hotkeys": { "F9": "screenshot", "F10": "toggle-recording", "F11": "save-replay" },
"diskWarnGB": 500,
"limits": { "minFreeDiskGB": 50, "minFreeMemoryMB": 2048, "maxEncoderMemoryMB": 4096, "maxEncoderLagSeconds": 60, "maxDuration": "8h" },
"postCapture": [ { "on": "replay", "run": "pwsh -File notify.ps1 \"{path}\"" } ]
}
enabled: (default true) false makes every capture call a no-op. Only takes effect via an
explicitly-loaded file (-capture-config path.json) — there is no auto-loaded project config and
no environment variable, so this never turns capture off behind your back; an explicit -capture ...
on the same command line always wins over it anyway.screenshot, replay, clip, marker, start-recording, stop-recording, toggle-recording.where, cooldown, debounce, maxPerSession, enabled, preset, format.Trailer: lossless master + high-quality MP4LosslessDevlog: MP4, 1080p maxBugReport: 720p30 MP4SessiondiskWarnGB only warns.capture serve)http://127.0.0.1:47800/.localhost/127.0.0.1 origins.--allow-origin.X-Capture-Token header from
%LOCALAPPDATA%\MindAttic\Capture\agent.json.POST /raise {event, data}, /marker, /screenshot, /clip {seconds},
/replay {before, after}, /record/start|stop|pause|resume, GET /status./ws accepts the same operations as {op, ...} messages.postCapture only comes from config files.Everything goes to R:\MindAttic\Capture\{RepoName}\. Each file name starts with the project name, so a file
copied elsewhere still says what it shows, followed by ISO 8601 local time with : replaced by .
(Windows file names cannot contain :):
R:\MindAttic\Capture\UnitySolarSystem\
UnitySolarSystem_2026-10-11T14.38.02.625.session.json session manifest: app, version, events, markers, captures, diagnostics
UnitySolarSystem_2026-10-11T14.38.02.625.mkv / .mp4 / .thumb.jpg / .mkv.json the -capture video session (named by its start)
UnitySolarSystem_2026-10-11T14.38.03.577.png / .png.json a screenshot and its sidecar
UnitySolarSystem_2026-10-11T14.39.12.004.mkv / .mp4 a replay, clip or recording
tools\prefix-existing-captures.ps1 renames captures made before the prefix (and fixes the names inside their
manifests). It only renames, skips files still in use, and is safe to re-run.
{RepoName} is the git repository the app runs from (an app in bin\Debug, a Unity project, a local site
folder), so projects that share a product name (GridGame, GridGame2025, GridGame2026) still get separate
folders. Unity players carry it from the build. Outside a repo it falls back to the app name. If R: is
missing, output goes to %USERPROFILE%\Videos\MindAttic\Capture with a warning. fileTemplate can
change the names (tokens {timestamp} {date} {time} {session} {tag} {index} {kind} {app}).
Each sidecar records:
Markers are also written into exported video as chapters.
Capture is a development tool and stays out of shipped builds:
<ItemGroup Condition="'$(Configuration)' != 'Release'">
<PackageReference Include="MindAttic.Capture.Wpf" Version="1.0.0" />
</ItemGroup>
The packages define MINDATTIC_CAPTURE, so wrap the init call and hooks in #if MINDATTIC_CAPTURE.
Release builds then contain no capture code at all. The packages come from the workspace feed
C:\LocalNuGet (refresh with dotnet pack src\<project> -c Release -o C:\LocalNuGet).MINDATTIC_CAPTURE
define, output Builds/Capture/).-capture (one log line) and never start ffmpeg.file:../../MindAttic.Capture/unity/com.mindattic.capture), which needs this repo checked out next
to them, the same as any sibling-repo dependency here. Once the repo is pushed it can be switched to
https://github.com/mindattic/MindAttic.Capture.git?path=/unity/com.mindattic.capture#<tag> if you
prefer pinned versions.tools\update-unity-plugin.ps1.-capture=hq for long sessions.dotnet build MindAttic.Capture.slnx
dotnet test MindAttic.Capture.slnx # engine and desktop tests need ffmpeg and an interactive desktop
Source layout: src\ holds the core, Windows, Wpf, WebView2, Agent and Tray projects; tests\ holds
MindAttic.Capture.Tests and MindAttic.Capture.Windows.Tests; unity\ is the Unity package and js\
the JavaScript client. capture recover with no root also scans the fallback output folder.
This README is also the home page of the published docs at https://mindattic.github.io/MindAttic.Capture/
(built by .github\workflows\docs.yml through the shared DocFX pipeline).
No license file: all rights reserved.
Part of MindAttic — see more projects at github.com/mindattic.