Fastest in the G2 Screen Recorder category, Spring 2024 report.
Screen recording, driven from a terminal.
DarthScreenCapture ships a first-class command-line recorder and a documented, versioned REST API — the same engine your GUI uses, exposed for CI jobs, regression videos, and scripted bug repros. No clicks. No drag handles. Just dsc record and a stable 93 MB binary.
Every knob that matters, in one place.
The flags below cover the 95% of technical recording sessions. They are stable across major versions and emitted in machine-readable form by dsc record --help-json.
-
01
Region & window
Pick the capture surface by id, name, or pixel rectangle.
--follow-cursorkeeps a magnified reticle locked to the mouse for keystroke tutorials.--window "Stripe Dashboard" --region 0,0,1920,1080 --display 1 --follow-cursor --exclude "System Settings" -
02
Frame rate & codec
Lossless 4K60 through the GPU at <3% CPU. Codec defaults to h264; switch to
vp9,av1,prores, orgifper job.--fps 60 --resolution 3840x2160 --codec av1 --bitrate 20M --keyframe 2 -
03
Audio routing
Per-region audio. Mix a desktop system feed plus a microphone on different tracks, mute on idle, or hand off to a VAD for silence cuts.
--audio "MacBook Microphone" --system-audio "PulseAudio:Monitor" --audio-track split --vad silence --gain 1.0 -
04
Lifecycle & output
Drive everything from the terminal: timed stops, signal handlers, webhooks on completion, and deterministic output paths so CI can diff artifacts.
--duration 30s --autostop on-idle 5s --out ./artifacts/regression.mp4 --on-finish "curl -X POST …" --exit-code $?
A versioned REST API on 127.0.0.1:7749.
Every CLI flag maps 1:1 to a JSON body. The daemon speaks OpenAPI 3.1, ships with a Postman collection, and is covered by a Trail of Bits audit (Nov 2023). Drop it behind a unix socket in production.
| Method | Endpoint | Purpose | Auth | Since |
|---|---|---|---|---|
| POST | /v1/sessions |
Begin a recording session — returns a session-id and tracks metadata. | Bearer | v3.0 |
| POST | /v1/sessions/{id}/stop |
Flush the encoder, finalize the file, and close the WebSocket event stream. | Bearer | v3.0 |
| GET | /v1/devices |
List windows, displays, audio inputs/outputs available to the current user. | Bearer | v3.0 |
| GET | /v1/sessions/{id}/status |
Poll runtime stats — CPU, fps, dropped frames, audio peaks — for dashboards. | Bearer | v3.2 |
| POST | /v1/export |
Convert a captured file to mp4, webm, gif, or mov without re-recording. | Bearer | v3.1 |
# Begin a session — every key mirrors a CLI flag.
curl -X POST http://127.0.0.1:7749/v1/sessions \
-H "Authorization: Bearer $DSC_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "window": "Stripe Dashboard",
"fps": 60, "codec": "h264",
"audio": ["system", "macbook-mic"],
"duration": "30s",
"out": "./artifacts/regression.mp4" }'
# → 201 Created { "id": "s_8f4a…", "ws": "ws://…/events" }
Budget it into a CI job.
Numbers below are reproducible on the open bench/ harness against a 2020 MacBook Air (M1, 8 GB). Source the script, run it, get the same curve.
VAAPI-attached encoder; measured as top -bn1 average across 30 s capture on a 2020 MacBook Air.
Bounded by a ring buffer; no growth across a 30-minute regression run.
Lightest in Wirecutter's 2024 comparison; ships as a single signed binary.
Paste, commit, ship a regression clip.
Two 14-line YAML files that turn a failed test into an attachable MP4. Both assume DSC_TOKEN is set as a repository secret and the binary is on PATH.
.github/workflows/regression-video.yml
name: regression-video
on: [push]
jobs:
record:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- run: brew install darthscreencapture
- run: npm test
continue-on-error: true
- if: failure()
run: |
dsc record --window "$WINDOW_TITLE" \
--fps 60 --duration 30s \
--out regression.mp4
- uses: actions/upload-artifact@v4
with:
name: regression-clip
path: regression.mp4
.gitlab-ci.yml
stages: [test, record]
test:
stage: test
script: npm test
allow_failure: true
record-regression:
stage: record
needs: [test]
when: on_failure
image: darthscreencapture/runner:3.4
script:
- dsc record --window "$WINDOW_TITLE"
--fps 60 --duration 30s
--out regression.mp4
artifacts:
paths: [regression.mp4]
when: on_failure
The four questions a backend engineer asks first.
01 How is the REST API authenticated?
Bearer tokens, scoped to record:write and record:read. The daemon binds 127.0.0.1:7749 by default; expose over a unix socket and front it with nginx if you need remote access. No cloud account required.
02 What are the rate limits on the daemon?
60 requests/minute per token for control endpoints, no cap on the /events WebSocket stream. Heavy paths (/v1/export) accept at most 4 concurrent jobs per host — exceeding it returns 429 with a Retry-After header.
03 Does the API deliver webhooks on session events?
Two surfaces: a WebSocket stream at /v1/sessions/{id}/events for live stats, and outbound webhooks on started, stopped, failed, and exported. Signatures use HMAC-SHA256 over the raw body.
04 Where does the binary live on Linux?
Static binary at /usr/local/bin/dsc, daemon unit at /etc/systemd/user/dscd.service. Headless capture uses VAAPI; on a sandbox without a GPU the encoder downshifts to libx264 automatically and the same flags apply.
Read the OpenAPI spec straight from the source.