Resolve autocut
Official skill registry for OpenVole — behavioral recipes for AI agents
npx -y skills add openvole/volehub --skill resolve-autocutAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Auto-edit gaming footage with DaVinci Resolve — kid-safe guardian pass (bleeps/PII), two-track gaming cuts, cold-open hooks, captioned Shorts, thumbnails, QC, and an unattended watch-folder loop
SKILL.md
11.7 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it
Resolve Autocut
Turn raw gameplay recordings into edited videos with DaVinci Resolve. You do the
judgment (thresholds, which moments matter, titles); the bundled scripts do the
grunt work (silence detection, cutting, rendering). Run each script with
skill_run_script — pass name: "resolve-autocut", a script path, and args. Every
script returns one JSON object; check ok and stop on ok:false, reporting the error.
Requires DaVinci Resolve Studio running with a project open for the timeline/render steps. The ffmpeg steps (analyze, captions, shorts, thumbnails, QC, normalize) work without it.
The core pipeline (what the human mostly wants)
- Analyze — detect silence → keep-list, and loudness peaks → highlight moments:
scripts/analyze.py <video.mp4> --out cutlist.jsonTune per game if cuts feel wrong:--db -35(silence threshold),--min-silence 0.6,--pad 0.15(breathing room around cuts). Louder games → lower--db(e.g. -30). Two-track gaming recordings (mic and game as separate audio streams, OBS-style): pass--mic-stream N --game-stream M— a segment is kept when there's speech or in-game action, and cut only when both are dead, so a loud fight without commentary survives..mkvtrack titles auto-detect;.mp4/.movusually lose titles, so pass the flags — and checktwo_trackandwarningin the result: awarningmeans it fell back to single-track and you should re-run with explicit streams.--action-sense 0.35tunes how loud (vs the game's own baseline) counts as action; lower protects more. Highlight moments carry asourcetag (mic= reaction,game= action) — great for picking shorts. Per-game presets: when the human approves thresholds for a game, remember them (agent memory) keyed by the game —db,pad,min_silence,action_sense,mic/game streams— and start the next video of that game from those instead of the defaults. - Build the timeline in Resolve from the keep-list (adds highlight markers):
scripts/build_timeline.py --cutlist cutlist.json --timeline "Auto Cut"Source is.mkv/.webm? Resolve won't import it reliably — remux to.movfirst (scripts/remux.py <in.mkv>) and run the pipeline on the result. See Resolve-friendly source. On the first run for a new game, STOP HERE and ask the human to eyeball the cuts — bad thresholds eat punchlines. Re-analyze with adjusted--db/--padif needed. - Render the reviewed timeline (only after the human approves):
scripts/render.py --outdir <drafts_dir> --name <VideoName> --preset "<preset>"
The payoffs (add these on top)
- Captions —
scripts/transcribe.py <video> --outdir captions --model base→.srt+.json. Add to the timeline withbuild_timeline.py --srt captions/<name>.srt. Add--wordsfor word-level timestamps (required by the guardian pass). pyenv shims can hide the whisper binary — setWHISPER_CMDto the env's real path (e.g.~/.pyenv/versions/<env>/bin/whisper). - Guardian pass (kid-channel safety) — auto-bleep profanity, flag PII, before anyone reviews:
scripts/guardian.py <video> --transcript captions/<name>.json --pii-file pii.txtTranscribe with--wordsfirst, and prefer--model baseor better — bleep accuracy is capped by transcript accuracy. Built-in EN+TR wordlists (--lang en,tr); extend per channel with--extra-words. The PII file is hashed: each linesha256(term) label, so the sensitive terms never exist in plaintext — add entries withguardian.py --pii-file pii.txt --add "<term>" --label school(never write terms by other means), and matches are reported as the label only (school @ 4:12). PII is flagged, never auto-muted unless--mute-pii— a human decides what an identity leak means. Matching is exact on the transcript: if a name was flagged with an odd spelling,--addthat variant.--mode mutesilences instead of a 1 kHz tone. When anything matches, a redacted transcript (<name>.redacted.json— profanity →[bleep], PII →[label]) is written: every later text step (titles, chapters, shorts--captions) must use it, or the raw term can end up burned into the video or in the model's context. Writes<name>.guarded.<ext>+<name>.guardian.json; run it on the source beforebuild_timelineso cuts happen on the guarded file (duration is unchanged, so cutlist timings stay valid), and lead your report with the safety summary (bleeps applied, PII flags with timestamps). Two-track sources: bleep the mic —guardian.py --stream <mic>edits only that stream and passes the game track through untouched; transcribe the same stream (transcribe.py --stream <mic>), since whisper alone reads only the first stream. - Shorts / Reels — vertical 9:16 (1080x1920) clips at the loudest moments:
scripts/shorts.py <video> --cutlist cutlist.json --count 3(or--at <sec>for exact spots). Combine loud moments with transcript keywords ("no way", "let's go", laughter) to pick the best. Recorded a facecam alongside? Add--overlay cam.mp4to composite it into a corner of each short, cut to the same moment (both sources assumed start-aligned at 0). Tune with--overlay-scale 0.30(Shorts read best ~0.3-0.4 of the narrow frame),--overlay-corner,--overlay-margin. The short's audio comes from the base<video>track — point that at whichever file carries the commentary. Moments are picked best-first by score from the cutlist (two-track cutlists tag each withmic/game— reactions vs action). Add--captions captions/<name>.json(a--wordstranscript — the mic one on two-track sources) to burn big word-by-word captions in the vertical style;--caption-size 96,--caption-pos 0.70tune it. Caption text is rendered with Pillow and composited as image overlays, so it works on slim ffmpeg builds that lack ass/subtitles/drawtext (current Homebrew bottles do). - Cold open — prepend the best moment as a ~5s teaser before everything (gaming retention 101):
scripts/hook.py --cutlist cutlist.json→cutlist.hook.json; build the timeline from that file instead.--pick game|micchooses action vs reaction,--atforces a moment,--duration/--leadshape the teaser. The moment plays again in context later — that's the point. - Punch-ins — add
--punch-in --zoom 1.08tobuild_timeline.pyto zoom on loud moments. - Overlay / picture-in-picture — composite a second clip onto a corner, cut in lockstep with the
base track:
build_timeline.py --cutlist cutlist.json --overlay clip.mp4. Works for a facecam, reaction cam, or webcam bug recorded alongside the gameplay. The overlay is assumed to start aligned at 0 and is clamped if it ends early. Tune with--overlay-scale 0.25,--overlay-corner bottom-left|bottom-right|top-left|top-right, and--overlay-margin 0.03. - Titles / description / tags / chapters — read
captions/<name>.jsonand the analyze result; write these yourself from the transcript. Chapters = timestamps of topic/scene changes. - Thumbnails —
scripts/thumbnails.py <video> --cutlist cutlist.json --count 5, then pick the best frame and propose a caption. - Loudness —
scripts/normalize.py <video> --lufs -14(YouTube target) before rendering, if the source is quiet/inconsistent. - Intro / outro / music — pass
--intro intro.mov --outro outro.movtobuild_timeline.py. - QC —
scripts/qc.py <video>flags black frames, freezes, and dead audio; run it on the draft before telling the human it's ready. - Big capture? Make a proxy first — a raw recording is often far more bitrate than a YouTube edit
needs (e.g. a 9 GB gameplay file).
scripts/proxy.py <in>transcodes it to a compact 1080p H.264.mp4(usually a fraction of the size) that's also Resolve-friendly, so it replaces the remux step. Analyze/edit on the proxy; publish from it, or relink to the original in Resolve for the final export (cuts are frame-accurate). Tune with--height 1080and--crf 21(lower = better/larger). - Resolve-friendly source — DaVinci Resolve won't reliably import
.mkv/.webm(often no audio). Remux to a.movfirst:scripts/remux.py <in.mkv>— copies the video stream when it's already edit-friendly (H.264/HEVC/ProRes/…) and converts audio to PCM. For VP9/AV1 sources add--transcode(defaults to ProRes;--video-codec h264|dnxhrto choose). The ffmpeg steps (analyze, captions, shorts, thumbnails, QC) read.mkvdirectly — only the Resolve steps need this. - No DaVinci Resolve Studio? Export a timeline to import. The free version can't be scripted
(so
build_timeline.py/render.pywon't connect), but it can import a timeline. Build the cut — including a synced second-track overlay — as FCPXML and import it by hand:scripts/export_fcpxml.py --cutlist cutlist.json [--overlay cam.mp4 --overlay-scale 0.25]→ in Resolve, File > Import > Timeline. The cuts and both tracks come in ready at the overlay's scale; Resolve ignores FCPXML transform position on import, so the overlay lands centered — set its Transform position once, then Paste Attributes (Transform) to the other overlay clips. Then render.
The unattended loop (watch folder)
For a recurring "drop a recording, review a draft later" workflow, drive the pipeline from a
watch folder with scripts/next_drop.py — it owns the state so no file is processed twice and
a file still being recorded is never grabbed (two-scan size stability + --min-age):
next_drop.py --drop <dir> --claim→ the next stable, unprocessed recording (ornext: null— then do nothing and end quietly).- Run the full pipeline on it, write a
REPORT.mdnext to the outputs (safety summary first), then--done <file> --note "…"— or--fail <file>on a blocker, and don't retry failed files without being asked. - Process one recording per run; the next run takes the next file. Never publish — the loop produces drafts and reports, a human ships.
Wire it to the agent's heartbeat (HEARTBEAT.md + heartbeat.enabled) for a true evening loop.
Rules
- Pass absolute paths for videos and outputs. Put working files (cutlist.json, captions/, shorts/, thumbs/) in the space workspace or the footage folder — never inside the skill dir.
- Long jobs:
transcribe.pyandrender.pycan be slow. Use a small whisper--modelfor long videos, andrender.py --wait-seconds 0to queue a long render without blocking. - Never auto-publish. Produce drafts, report what you did (cuts made, duration before/after, markers, shorts, QC issues), and let the human approve the final render/upload.
- Kid-channel footage: guardian first. Run the guardian pass before building the timeline and put its result (bleeps applied, PII flags) at the top of your report. Never skip it because the footage "seems clean" — the pass is cheap and the transcript already exists for captions.
- If Resolve isn't running, the timeline/render scripts return a clear error — do the ffmpeg steps, then ask the human to open Resolve.