Skip to content
Back to skills

Longform Edit

ASecurity

Edits a raw long-form YouTube recording (screen recording export, camera file, or either plus a separate mic) into a publish-ready video automatically, like Descript on autopilot: transcribes with word timestamps, removes retakes and keeps the last take, tightens dead space while keeping silent on-screen action (speeding up long waits), masters the voice to -14 LUFS / -1.5 dBTP with no music bed, re-transcribes the FINAL render for an every-word SRT (optional burned-in captions), drafts chapt...

  • 15 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentspythonrustbashaws

Works with

  • claude code
  • cursor
  • cli

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 15 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add jsath/claude-skills --skill longform-edit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Longform Edit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Longform Edit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jsath-longform-edit/badge)](https://www.skillsdirectory.com/skills/jsath-longform-edit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: longform-edit
description: "Edits a raw long-form YouTube recording (screen recording export, camera file, or either plus a separate mic) into a publish-ready video automatically, like Descript on autopilot: transcribes with word timestamps, removes retakes and keeps the last take, tightens dead space while keeping silent on-screen action (speeding up long waits), masters the voice to -14 LUFS / -1.5 dBTP with no music bed, re-transcribes the FINAL render for an every-word SRT (optional burned-in captions), drafts chapters, titles and a description, and fails loudly on QA gates (words, A/V sync, caption sync per chapter, caption coverage, loudness) plus contact sheets you look at. Use when someone says edit this long-form, clean up my recording, cut the retakes and dead space, process the long-form inbox, or descript this. Needs Claude Code with ffmpeg, whisper.cpp and Python 3."
---

# longform-edit

Drop raws in a folder, run one command, get a cut, mastered, captioned video plus a REVIEW.md that
explains every cut. Short-form sibling: `edit-style` (reels). Transcription setup: `use-local-whisper`.
Thumbnails: `thumbnail-generator`. Per-platform captions for clips: `reel-captions`.

## Requirements (check first, install only after the user says yes)

```bash
ffmpeg -version | head -1                       # any 6.x+; libass only needed for --burn-captions
whisper-cli --help >/dev/null && echo WHISPER_OK   # whisper.cpp (brew install whisper-cpp)
ls ~/models/whisper/ggml-small.en.bin           # or set paths.whisper_model
python3 -m pip install -r scripts/requirements.txt  # numpy, pillow, opencv-python-headless
which claude                                     # optional: titles + chapter names
```

Model: `curl -L -o ~/models/whisper/ggml-small.en.bin https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.en.bin`
(466 MB; `ggml-base.en` on slow machines, multilingual `ggml-small` for non-English). Another transcriber is
fine too: pass `--words words.json` as `[{"w": "word", "s": 0.12, "e": 0.40, "p": 0.9}]`.
Claude.ai has no ffmpeg: there, take a pasted transcript with timestamps and return the cut list, retake table,
chapters and an SRT only. Say clearly that nothing was rendered.

## Setup (once)

Copy `config.example.json` to `~/longform/config.json`, set `paths.inbox`, `paths.outbox`, `paths.whisper_model`,
your names in `transcribe.prompt` and `publish.word_fixes`, and optionally `publish.cta_line` + `publish.cta_keywords`
(the draft flags a video with no mid-video call to action). Every threshold below lives in that file.

## Run it

```bash
S=~/.claude/skills/longform-edit/scripts/longform_edit.py
python3 $S ~/longform/inbox/<slug>/ --config ~/longform/config.json             # one video
python3 $S --config ~/longform/config.json                                      # every inbox folder with no REVIEW.md yet
python3 $S <folder> --plan-only      # cut plan + REVIEW.md in ~1 min, no render
python3 $S <folder> --mic voice.wav  # separate mic, synced by cross-correlation (clap at the start helps)
python3 $S <folder> --kind camera    # talking head: every silence is idle (auto-detected from motion or file name)
python3 $S <folder> --burn-captions  # also <slug>.captioned.mp4 with 2-5 word captions burned in
python3 $S <folder> --no-llm         # heuristic chapter titles, no claude CLI call
```

Inbox: `<inbox>/<slug>/` holding one video (largest wins) and optionally one audio file (used as the voice) and a
`config.json` with per-video overrides. Output: `<outbox>/<slug>/`. A 15 min raw takes roughly 6-12 min; run it in the
background and tail `<outbox>/<slug>/run.log`. Re-runs are cached: only changed stages redo.

## What it decides (details and every number in references/method.md)

1. **Retakes, keep the last take.** An explicit cue said as its own phrase ("let me say that again", "retake",
   "scratch that", 22 cues in config) cuts the abandoned attempt plus the cue. A line restarted from the top (same
   opening words, similarity >= 0.8, within 45 s) cuts the earlier attempt. Back-to-back repeated phrases lose the
   first copy. um/uh separated by silence are cut. Anything weaker is **flagged, not cut**.
2. **Dead space, strategically.** Every silence >= 0.7 s is checked against the picture (frame diff at 8 fps,
   cursor-sized blobs ignored, webcam bubble masked, net first-to-last change catches slow typing).
   Static screen: tightened to 0.28 s mid-sentence / 0.40 s at a sentence end, breath kept. Cursor only: 0.6 s.
   Real on-screen action: kept, idle trimmed either side; if it runs > 4.5 s it plays at 1.5-3x with the last 0.9 s
   at 1x so the result lands. Cuts only land in measured silence, never mid-word.
3. **Voice master, no music bed.** HPF 75 Hz, FFT denoise from the measured floor, mud cut, presence, air, de-ess,
   2.5:1 compression, gain to -14 LUFS, limiter to <= -1.5 dBTP, filter latency measured and removed.
4. **Captions from the FINAL audio.** The final render is re-transcribed; the SRT is built from that, never from the
   source transcript, with cue starts snapped to speech onsets. Every word is covered (gated).
5. **Publish draft.** Chapters (structural cues like "the first", "next", long pauses, big screen changes; >= 3,
   first at 0:00, each >= 40 s), 3 title options, description, pinned comment, tags and fact-check flags via the
   `claude` CLI when present, heuristic otherwise. 3 thumbnail candidate frames (sharpest, most colourful per third).

## Gates (exit 2 and `<slug>.FAILED-GATES.mp4` if any fails)

| gate | passes when |
|---|---|
| frames | every chunk has exactly the EDL frame count; video and audio length within 1.5 frames |
| words | final re-transcription recalls >= 93% of the kept source words, no lost run >= 6 words |
| av_sync | 10 probes: audio lag <= 25 ms and the frame matches the source better than +-0.5 s |
| captions | per chapter, cue start vs audio onset: median <= 0.12 s, p95 <= 0.25 s |
| caption_coverage | >= 98% of final words sit inside a caption |
| loudness | -14 +-1 LUFS integrated, true peak <= -1 dBTP |

## After it runs (the agent's job, do not skip)

1. **Exit code.** 0 = all gates passed. 2 = never hand the file over as done; REVIEW.md says which gate and why.
2. **Look at `contact-sheet.jpg` and `cuts-sheet.jpg`** (open the images): picture present in every tile, no
   black frames, the before/after of each edit point looks like a continuous state.
3. **Read REVIEW.md**: retakes cut (before/after text), flagged-not-cut list, on-screen actions kept, loudness,
   caption sync per chapter, A/V probes, words check. To change a decision write `<outbox>/<slug>/overrides.json`
   and re-run the same command (times are SOURCE seconds, the `src` column):
   ```json
   {"keep_retakes": ["R03"], "cut_retakes": ["R07"], "keep_ranges": [[312.0, 330.5]],
    "force_cut": [{"s": 100.2, "e": 104.9, "why": "cough"}]}
   ```
4. **PUBLISH.md is a draft.** Rewrite weak titles, fact-check every flagged number (measured, same source, same
   window), fix name spellings in `publish.word_fixes` and re-run so the SRT is right.
5. **Never upload or schedule.** Hand back the paths; the human publishes.

## Report back in this shape

```
LONGFORM EDIT: <slug>
Runtime   14:32 -> 11:05 (24% cut): 6 retakes, 11 fillers, 3 speed-ups, 41 pauses tightened
Gates     6/6 PASS (words 97.8%, max A/V lag 4 ms, captions median 0.05 s, -14.0 LUFS / -1.6 dBTP)
Flags     R04 at 03:12 restart? similarity 0.62, kept; "saves 10 hours" at 07:40 needs a source
Files     <outbox>/<slug>/<slug>.mp4, .srt, chapters.txt, PUBLISH.md, REVIEW.md, thumbs/
Looked at contact-sheet.jpg and cuts-sheet.jpg: clean. Nothing uploaded.
```

## When something is missing

- No whisper model: stop and print the download line above; or accept `--words` from any other transcriber.
- No opencv: runs anyway, but every silence is treated as idle (says so in run.log); install it for screen recordings.
- No `claude` CLI: heuristic chapter titles, flagged in PUBLISH.md as needing a rewrite.
- ffmpeg without libass: `--burn-captions` is skipped with a note; the SRT still ships (upload it as YouTube CC).
- Mic sync confidence below 4: stops and asks for a clap at the start or for the mic to be dropped.

## Recording habits that make the edit better

Say "retake" (or "let me say that again") as its own sentence before redoing a line: it is the only cue trusted to
cut a whole sentence. During a loading wait either stay silent with the cursor still (cut) or narrate (kept).
A silent stare at a static chart gets tightened: say something while showing it. One continuous take per file.

Optional stages (graphics panels, scene switching, style profiles, external camera sync, retake reveals) are
described in `references/optional-stages.md`; they are not in these scripts.

Files in this skill

  • SKILL.md8.6 KB
  • config.example.json4.5 KB
  • references/method.md5.8 KB
  • references/optional-stages.md4.3 KB
  • scripts/lf/common.py5.3 KB
  • scripts/lf/pipeline.py27.6 KB
  • scripts/lf/plan.py12.1 KB
  • scripts/lf/publish.py18.2 KB
  • scripts/lf/render.py11.9 KB
  • scripts/lf/retakes.py10.5 KB
  • scripts/lf/screen.py6.9 KB
  • scripts/lf/transcribe.py3 KB
  • scripts/lf/verify.py9.5 KB
  • scripts/longform_edit.py298 B
  • scripts/requirements.txt36 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.