agentsclimarketplace

Resolve autocut

Skill openvole/volehub/skills/resolve-autocut

Official skill registry for OpenVole — behavioral recipes for AI agents

Install
npx -y skills add openvole/volehub --skill resolve-autocut

Assembled 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)

  1. Analyze — detect silence → keep-list, and loudness peaks → highlight moments: scripts/analyze.py <video.mp4> --out cutlist.json Tune 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. .mkv track titles auto-detect; .mp4/.mov usually lose titles, so pass the flags — and check two_track and warning in the result: a warning means it fell back to single-track and you should re-run with explicit streams. --action-sense 0.35 tunes how loud (vs the game's own baseline) counts as action; lower protects more. Highlight moments carry a source tag (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.
  2. 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 .mov first (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/--pad if needed.
  3. 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)

  • Captionsscripts/transcribe.py <video> --outdir captions --model base.srt + .json. Add to the timeline with build_timeline.py --srt captions/<name>.srt. Add --words for word-level timestamps (required by the guardian pass). pyenv shims can hide the whisper binary — set WHISPER_CMD to 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.txt Transcribe with --words first, and prefer --model base or 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 line sha256(term) label, so the sensitive terms never exist in plaintext — add entries with guardian.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, --add that variant. --mode mute silences 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 before build_timeline so 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.mp4 to 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 with mic/game — reactions vs action). Add --captions captions/<name>.json (a --words transcript — the mic one on two-track sources) to burn big word-by-word captions in the vertical style; --caption-size 96, --caption-pos 0.70 tune 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.jsoncutlist.hook.json; build the timeline from that file instead. --pick game|mic chooses action vs reaction, --at forces a moment, --duration/--lead shape the teaser. The moment plays again in context later — that's the point.
  • Punch-ins — add --punch-in --zoom 1.08 to build_timeline.py to 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>.json and the analyze result; write these yourself from the transcript. Chapters = timestamps of topic/scene changes.
  • Thumbnailsscripts/thumbnails.py <video> --cutlist cutlist.json --count 5, then pick the best frame and propose a caption.
  • Loudnessscripts/normalize.py <video> --lufs -14 (YouTube target) before rendering, if the source is quiet/inconsistent.
  • Intro / outro / music — pass --intro intro.mov --outro outro.mov to build_timeline.py.
  • QCscripts/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 1080 and --crf 21 (lower = better/larger).
  • Resolve-friendly source — DaVinci Resolve won't reliably import .mkv/.webm (often no audio). Remux to a .mov first: 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|dnxhr to choose). The ffmpeg steps (analyze, captions, shorts, thumbnails, QC) read .mkv directly — 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.py won'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 (or next: null — then do nothing and end quietly).
  • Run the full pipeline on it, write a REPORT.md next 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.py and render.py can be slow. Use a small whisper --model for long videos, and render.py --wait-seconds 0 to 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.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.