S-Clip - competition-grade rolling replay capture for Windows
CI status Python 3.10 through 3.13 Windows 10 and 11 MIT licence
S-Clip is a native Windows capture client for competitive players. It keeps a real rolling replay buffer on disk, listens for global hotkeys, and turns the previous few seconds of play into a smooth MP4 without pulling you out of the match.
Arming an empty buffer, filling to the configured window, saving, and the finished clip landing.
- The clip is what just happened. FFmpeg rotates short MPEG-TS segments through a bounded buffer, then joins the current window when you press the clip hotkey.
- The readout never overstates the buffer. A rolling buffer starts empty and takes your whole window to fill. S-Clip reports what a save would actually produce at that instant - 18 of 30 seconds buffered - because the figure is read from the same segment snapshot the save path uses. The number on screen cannot drift from the clip you get.
- Capture stays on the GPU. S-Clip prefers Desktop Duplication through
ddagraband automatically selects NVENC, AMD AMF, or Intel Quick Sync when the machine supports it. - Game audio and microphone are handled together. Windows WASAPI loopback captures desktop sound without a virtual cable, while DirectShow supplies the microphone input.
- First launch is hardware-aware. Display geometry, frame rate, encoder, preset, and quality defaults are selected from the detected machine rather than a one-size-fits-all profile.
- It can measure your PC rather than guess at it. Benchmark this PC times every available encoder on a short synthetic clip at your display's own resolution and recommends the best one that keeps up. In Advanced mode, Test this setup does the same for the settings you picked yourself and says plainly when they will not hold. Nothing is captured from your screen and no file is written.
- It tells you when it is out of date, and nothing else. S-Clip asks GitHub once a day whether a newer release exists and shows a link if one does. That is its only use of the network, it can be switched off in Settings, and it never downloads or installs anything - see below.
- The interface stays out of the match. Global hotkeys, tray operation, direct state feedback, and a local clip library keep the common path short.
S-Clip library: recorded clips as a reflowing grid of thumbnails with duration, size and date
Capture, Settings and About
S-Clip capture screen: a full 30-second replay window with live buffer telemetry
S-Clip settings in Automatic mode, showing the hardware-detected capture profile
S-Clip about page with third-party acknowledgements and diagnostics
About these images. They are generated by
render_readme_screenshot.pyandrender_demo_gif.py, which render the real window offscreen against in-memory collaborators, so they are reproducible and never touch a developer's own clips folder. The sample recordings are genuinely encoded by FFmpeg and thumbnailed through the same code path the library uses; their content is a generated gradient rather than real gameplay footage. In the animation the interface is real and the capture engine is scripted - driving a live capture would mean committing whatever happened to be on the author's screen.
S-Clip is deliberately small at the surface and serious underneath:
| Area | Design |
|---|---|
| Capture | GPU-first Desktop Duplication with a guarded GDI fallback |
| Replay | Bounded segment ring, asynchronous save worker, and constant-rate final timeline |
| Telemetry | Buffer fill, footprint and bitrate read from the snapshot the save path uses, so the readout cannot drift from the clip |
| Concurrency | Explicit FFmpeg process ownership and Qt-thread event bridges |
| Architecture | Typed Protocol boundaries between UI, capture core, devices, and persistence |
| Settings | Atomic writes, schema migration, hostile-input validation, and hardware-tuned defaults |
| Quality | Strict mypy, Ruff, a whole-package coverage gate covering the interface as well as the core, and Windows CI across Python 3.10–3.13 |
The settings benchmark is worth a paragraph too, because the obvious threshold
is wrong. It measures how much faster than real time an encoder runs, and the
tempting rule is that anything above 1.0 will do. On the development machine
libx264 at the medium preset measures 1.9x at 1440p60 and comfortably
clears that bar - and in a real capture it dropped one frame in five while
using 227% of a CPU core. The encode is only part of what a software encoder
costs: it also pays to copy every frame out of GPU memory, and it competes with
the game that is worth recording in the first place. So the bar is 3.0x for CPU
encoders and 1.25x for GPU ones, which are numbers taken from that measurement
rather than picked. Timing is done by encoding two different lengths and
subtracting, because a single timed run charges FFmpeg's start-up to the
encoder, and setting up an NVENC session costs enough to understate hardware
encoding by about a quarter - biasing the benchmark against the very encoder it
should be recommending.
S-Clip notices new releases but will not install them, and that is a decision rather than an unfinished feature. The installer is not code-signed, so an automatic update would have to download an unsigned executable and run it. That trains the user to click past the SmartScreen warning which is, today, the only thing standing between them and a tampered build - and it turns this project's release pipeline into a code-execution channel on every machine that has ever run it. Doing it properly needs a signed update manifest and a key to sign it with, at which point the download can be verified independently of any certificate authority. Until then, a link to the release page is the honest option, and the user installs it exactly as they installed the first one.
Saving is a remux, not a re-encode, and that is worth a paragraph because the obvious reasoning points the other way. Feeding the segments through FFmpeg's concat demuxer and copying does leave a timing seam, because the demuxer re-times every input it opens. The conclusion usually drawn from that - encode the whole thing again - is the expensive one and costs a generation of quality.
MPEG-TS is designed to be concatenated at the byte level, so S-Clip joins the segments as bytes and remuxes the result. Measured on a real 20-second buffer, that takes 0.12 seconds against 7.09 for the re-encode, and the frames come out spaced to within 11 microseconds of the ideal 16.667 ms - no seam, no judder, and the pixels are exactly the ones the encoder produced live. A re-encode is still there as a fallback for segments a remux will not accept, such as a codec change part-way through a buffer.
Download the latest installer from Releases and run it. It installs for the current user, so there is no administrator prompt, and it leaves your clips and settings alone if you later uninstall.
You also need FFmpeg, which S-Clip drives to capture and encode:
winget install Gyan.FFmpeg
The installer checks for FFmpeg and says so if it is missing. Without it the interface still opens and the About page explains the problem, but nothing can be recorded.
The installer is not signed. Code signing needs a certificate issued against a verified identity, and this project does not have one. Windows SmartScreen will therefore show "Windows protected your PC" the first time you run it: choose More info, then Run anyway. If you would rather check the download yourself, each release ships a
SHA256SUMS.txtbeside the installer. Saying this plainly seems better than letting the warning come as a surprise.
Requires Windows 10 or 11, Python 3.10–3.13, and FFmpeg on PATH.
git clone https://github.com/shilohhm/S-Clip.git cd S-Clip py -3.13 -m venv .venv .\.venv\Scripts\Activate.ps1 python -m pip install . sclip-gui
For development, install the quality tooling with python -m pip install -e ".[dev]".
S-Clip also picks up FFmpeg placed beside it, which is how the portable layout
works: put the binary at ffmpeg\bin\ffmpeg.exe next to S-Clip.exe (or, in a
checkout, at the repository root) and it will be preferred over whatever is on
PATH. Those directories are ignored by Git and never shipped in the source
repository.
| Default input | Action |
|---|---|
F5 |
Save the current replay window |
Ctrl+F6 |
Start or stop a manual recording |
| Record control | Run the action shown by the current capture state |
| System tray | Save a clip, toggle recording, show S-Clip, or quit |
Hotkeys are global and remappable. Recordings land in the platform data directory by default, with an optional custom output directory in Settings.
flowchart LR
APP["Composition root<br/>sclip.app"]
UI["PySide6 UI<br/>sclip.ui"]
CONTRACTS["Typed contracts<br/>sclip.contracts"]
CORE["Capture core<br/>sclip.core"]
FFMPEG["FFmpeg processes"]
STORAGE["Settings + clips"]
APP --> UI
APP --> CORE
UI --> CONTRACTS
CORE --> CONTRACTS
CORE --> FFMPEG
CORE --> STORAGE
The core contains no Qt imports. UI code consumes small typed contracts, while
sclip.app wires the concrete engine, settings store, device registry, hotkey
listener, and window together. The result is a capture pipeline that can be
tested without booting the desktop interface.
See docs/ARCHITECTURE.md for the module map,
threading model, replay save sequence, and rationale behind the main technical
decisions.
python -m ruff check . python -m ruff format --check . python -m mypy src python -m pytest -m "not slow"
The full suite includes FFmpeg-backed replay integration tests:
python -m pytestCoverage is gated over the whole package rather than the core alone, so the interface counts too:
python -m pytest -m "not slow" --cov=sclip --cov-report=term-missing
CI runs linting, formatting, strict type checking, that coverage gate, compatibility tests, wheel builds, and packaged-asset verification on Windows.
S-Clip 2.2 is in beta. The capture engine, rolling replay buffer, desktop audio
path, hardware benchmark, update notifier, settings migration, and desktop
interface are implemented, and ship as a per-user Windows installer built and
published by release.yml on a version tag.
The installer is unsigned, which is the honest remaining gap rather than a
planned feature: signing needs a code-signing certificate tied to a verified
identity, so it waits on one being obtained rather than on any work in this
repository. packaging/sclip.iss already carries the
SignTool hook, commented, for the day there is a certificate to point it at.
FFmpeg is a prerequisite rather than a bundled dependency; redistributing a GPL
build alongside an MIT application raises licensing questions that a one-line
winget install avoids entirely.
Read CONTRIBUTING.md before opening a pull request.
S-Clip is MIT licensed; third-party asset notices live in
THIRD_PARTY_NOTICES.md.
Built by Shiloh Malka.