Motivation
Camtasia keeps breaking underneath us — the latest being the .trec thumbnail deadlock (#17) that bricks any project with 3+ cuts from one recording. The parts of Camtasia this workflow actually needs (record, cut by transcript, PiP, captions, render) are all scriptable. Everything else is liability.
Goal: a Camtasia-free pipeline — record → transcribe → cut → render — as a new tool living in this monorepo (repo is already bun-workspaces; no restructuring needed), with its own name, CLI, and later an MCP server over the same core.
Shape
New package(s) under packages/, separate from the camkit CLI:
- Own project format: small JSON timeline — sources, clips (src, in/out, timeline position), PiP transforms, caption track. Human-diffable, git-friendly. No tscproj semantics (no editRate 705600000, no ScreenVMFile-style types); Camtasia's format shaped by its internals is exactly the debt being escaped.
- Recording: don't build a recorder. ffmpeg avfoundation capture (screen + camera + mic) straight to mp4. Deletes the whole trec/proxy problem class.
- Render: ffmpeg filter_complex — trim/atrim + setpts + concat, overlay for PiP, subtitles/ASS for burned word-level captions. The parse.cmproj recovery (2026-07-14) was this render engine hand-rolled; lessons: tscc2/VFR input-seek is unreliable (single-pass filter graph per source), AAC concat priming (~23ms/segment) needs the single-pass path.
- Reuse from camkit core (already format-agnostic): transcript/takes/words, silence detection, time math.
- camkit's role: becomes the migration bridge —
<newtool> import foo.cmproj via camkit's tscproj parsing. Dependency arrow is one-way: the new package never imports tscproj-shaped types, so extracting it to its own repo later stays cheap.
- CLI first; MCP as a thin wrapper over the same core functions once they exist.
v1 slice
record (ffmpeg) → transcribe (existing engines) → takes/cut-list → render mp4 with PiP + burned captions. That is the entire YouTube pipeline with Camtasia fully out.
Non-goals (write into the README as a never-list)
Transitions, effect packs, general NLE features, GUI timeline. The moment it grows those it becomes a worse Kdenlive. Preview = fast low-res proxy render of a time range, nothing more.
Open questions
- Name.
- Caption styling depth (ASS word-highlight parity with Dynamic Captions is the fiddliest part — budget real time).
- Golden-file render tests for A/V sync / VFR correctness.
Motivation
Camtasia keeps breaking underneath us — the latest being the .trec thumbnail deadlock (#17) that bricks any project with 3+ cuts from one recording. The parts of Camtasia this workflow actually needs (record, cut by transcript, PiP, captions, render) are all scriptable. Everything else is liability.
Goal: a Camtasia-free pipeline — record → transcribe → cut → render — as a new tool living in this monorepo (repo is already bun-workspaces; no restructuring needed), with its own name, CLI, and later an MCP server over the same core.
Shape
New package(s) under
packages/, separate from the camkit CLI:<newtool> import foo.cmprojvia camkit's tscproj parsing. Dependency arrow is one-way: the new package never imports tscproj-shaped types, so extracting it to its own repo later stays cheap.v1 slice
record (ffmpeg) → transcribe (existing engines) → takes/cut-list → render mp4 with PiP + burned captions. That is the entire YouTube pipeline with Camtasia fully out.
Non-goals (write into the README as a never-list)
Transitions, effect packs, general NLE features, GUI timeline. The moment it grows those it becomes a worse Kdenlive. Preview = fast low-res proxy render of a time range, nothing more.
Open questions