Skip to content
CLI & REST API · v3.4

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.

  • v3.4 current release
  • MIT CLI source license
  • 93 MB single-binary installer
  • 3 OS macOS · Windows · Linux
03 · Flag reference

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.

  1. 01

    Region & window

    Pick the capture surface by id, name, or pixel rectangle. --follow-cursor keeps 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"
  2. 02

    Frame rate & codec

    Lossless 4K60 through the GPU at <3% CPU. Codec defaults to h264; switch to vp9, av1, prores, or gif per job.

    --fps 60
    --resolution 3840x2160
    --codec av1
    --bitrate 20M
    --keyframe 2
  3. 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
  4. 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 $?
04 · REST surface

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" }
05 · Runtime cost

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.

Cold start → first frame
3.0s

Fastest in the G2 Screen Recorder category, Spring 2024 report.

CPU at 4K60, h264
2.7%

VAAPI-attached encoder; measured as top -bn1 average across 30 s capture on a 2020 MacBook Air.

Resident memory (4K60)
184MB

Bounded by a ring buffer; no growth across a 30-minute regression run.

Installer size
93MB

Lightest in Wirecutter's 2024 comparison; ships as a single signed binary.

06 · CI recipes

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 Actions

.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

.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
07 · FAQ

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.