| "cut from 1:20 to 2:05", "trim the first 10 s" | cut.py input.mp4 --start 1:20 --end 2:05 |
| "keep only these parts" | cut.py in.mp4 --segments 0-1:00,1:30-2:00 |
| "remove the middle" | cut.py in.mp4 --remove 1:00-1:30 |
| "frame-exact but keep the quality" (H.264) | cut.py in.mp4 --start 1:20.4 --end 2:05.1 --smart (re-encodes only the partial GOPs; smart.reason if it fell back) |
| "make it exactly 60 seconds" | fit.py in.mp4 --duration 60 (speed; --method trim) |
| "cut it and make it HEVC / AV1 / ProRes" | cut.py in.mp4 --start 0:10 --end 0:40 --codec hevc |
| "cut out the pauses", "jump cuts" | silence.py in.mp4 |
| "cut the ums and uhs" | silence.py in.mp4 --filler --words words.json |
| "just the real pauses, not inside a sentence" | silence.py in.mp4 --speech-aware |
| "a 60 s highlight from this hour" | scenes.py long.mp4 --highlights 6 --target 60 --edl picks.txt (then cut.py --segments with picks.txt's lines joined by commas) |
| "cut on the beat" | cut.py in.mp4 --segments ... --snap beats --snap-source beats.json (scenes.py --beats; a WAV/MP3 music bed too) |
| "speed up here, slow-mo there" | speedramp.py in.mp4 --segment 0-3:1.0 --segment 3-4:0.25 |
| "freeze the last frame" | freeze.py clip.mp4 --hold 2 |
| "smooth slow motion" | fit.py in.mp4 --duration 2x --smooth interpolate |
| "reverse this clip" | reverse.py in.mp4 |
| "loop it to fill 30 seconds", "seamless loop" | loop.py clip.mp4 --duration 30 (--crossfade 0.5 hides the seam) |
| "make it vertical / 9:16 / square" | fit.py in.mp4 --aspect 9:16 --fit pad (or crop, blur) |
| "resize to a height/width" | fit.py in.mp4 --height 1080 |
| "crop to this exact box" | crop.py in.mp4 --x 100 --y 0 --width 1080 --height 1920 |
| "rotate 90 degrees", "mirror it" | fit.py in.mp4 --rotate 90 (--flip h) |
| "the horizon is tilted" | straighten.py in.mp4 --degrees -2.5 |
| "flat view out of this 360 video" | sphere.py in.mp4 --yaw 90 --h-fov 100 --v-fov 70 |
| "this old footage is interlaced" | deinterlace.py in.mp4 |
| "it's grainy, clean it up" | denoise.py in.mp4 --strength medium |
| "blur this face/plate" (known box) | redact.py in.mp4 --x 820 --y 140 --width 240 --height 240 --mode pixelate |
| "remove this fixed logo" (known box) | redact.py in.mp4 --x 40 --y 20 --width 180 --height 60 --mode delogo |
| "stabilize this shaky footage" | stabilize.py in.mp4 |
| "are there black bars on this?" | cropdetect.py in.mp4 |
| "iPhone HDR / Dolby Vision looks washed out" | color.py clip.mov --to-sdr (--strip-dovi keeps HDR) |
| "apply this LUT", "convert the S-Log footage" | color.py in.mp4 --lut grade.cube |
| "the colours are tagged wrong" | color.py in.mp4 --retag bt709 |
| "brighten it", "fix white balance" | color.py in.mp4 --correct --exposure 0.3 --temperature 5600 |
| "burn in captions from this SRT" | caption.py in.mp4 --srt subs.srt |
| "caption it with these lines" | caption.py in.mp4 --text cues.txt |
| "keep the subtitles toggleable" | caption.py in.mp4 --srt subs.srt --mode mux |
| "captions are three lines on a Short" | caption.py in.mp4 --srt subs.srt --max-lines 2 (keep the template's value; the size shrinks) |
| "transcribe it and caption it", "words popping" | caption.py in.mp4 --transcribe --animate pop --karaoke |
| "our logo top-right", "a watermark" | overlay.py in.mp4 --image logo.png --position top-right --scale 200 |
| "a title for the first 4 seconds" | overlay.py in.mp4 --text "Title" --position top --start 0 --end 4 |
| "picture-in-picture" | overlay.py in.mp4 --video cam.mp4 --position bottom-right --scale 480 |
| "remove the green screen" | overlay.py bg.mp4 --video green.mp4 --chromakey 0x00ff00 |
| "a lower third", "hook card", "sticker", "meme text" | graphics.py in.mp4 --template lower-third --name "..." (or hook, sticker, meme) |
| "use our brand fonts/colours/logo" | --brand brand.json on caption/overlay/graphics |
| "sync the lav mic", "line up two cameras" | sync.py camera.mp4 mic.wav --replace-audio |
| "the audio drifts out of sync" | sync.py camera.mp4 rec.wav --fix-drift --replace-audio |
| "normalise to -14 LUFS", "streaming and broadcast versions" | loudness.py in.mp4 (--versions streaming,ebu-r128) |
| "clean up the audio", "remove the hiss" | audio.py in.mp4 --voice (or --denoise) |
| "music under the talking", "duck harder" | audio.py in.mp4 --music bed.mp3 --duck --fade-out 3 |
| "convert the 5.1 to stereo" | audio.py in.mov --downmix |
| "wider stereo" | audio.py band.wav --stereo-widen 0.5 |
| "swap in the narration track" | audio.py in.mp4 --replace narration.wav |
| "give me the sound as WAV" | audio.py in.mp4 -o in.wav |
| "compress the voice", "limit the peaks", "gate the noise" | audio.py in.mp4 --compress (or --limit, --gate) |
| "audiogram", "turn this podcast into a video" | render.py --template audiogram ep.m4a --image cover.png |
| "make this a Reel / TikTok / Short / YouTube" | render.py --template reels in.mp4 --cues cues.txt |
| "post it everywhere" | render.py --template all in.mp4 --cues cues.txt |
| "export for YouTube / Reels / X", "ProRes / DNxHR / alpha master", "key and fill" | export.py in.mp4 --preset youtube (prores, dnxhr-hq, prores4444, key-fill) |
| "under 25 MB" | export.py in.mp4 --preset youtube --max-mb 25 |
| "make a GIF preview" | export.py in.mp4 --preset gif |
| "the recording is corrupted" | export.py in.mp4 --preset copy --repair |
| "a small proxy file" | proxy.py in.mp4 --width 640 |
| "is this OK to upload?" | check.py final.mp4 --platform reels |
| "how much quality was lost" / "did anything else change?" | check.py final.mp4 --compare master.mp4 / check.py new.mp4 --compare old.mp4 --expect-changed 12-18 (or none) |
| "is it broadcast legal?" | check.py final.mp4 --levels ebu-r103 (clamp: color.py in.mp4 --correct --legalize ebu-r103) |
| "send me a summary of what you did" | report.py --before raw.mov --after final.mp4 -o report.html |
| "title card", "Ken Burns on a photo" | insert.py title.png --duration 3 (--zoom in --pan right) |
| "a blank colour clip" | background.py -o bg.mp4 --duration 3 --color 0x101010 |
| "grade it but keep the alpha" | color.py logo.mov --correct --exposure 0.3 --keep-alpha -o graded.mov |
| "lower third as a transparent layer" | background.py --transparent -o canvas.mov --duration 5 --width 1920 --height 1080, then graphics.py canvas.mov --template lower-third --name "Ada" --keep-alpha -o lt.mov |
| "numbered frames into a video" | sequence.py --dir frames --pattern "frame_%04d.png" --fps 24 |
| "waveform video for this track" | waveform.py ep.wav -o waveform.mp4 |
| "add black at the start" | pad.py clip.mp4 --start 1.5 |
| "cut to the product shot", "B-roll over this bit" | broll.py talk.mp4 --insert product.mp4 --at 12 --end 16 --audio b|mix |
| "add chapters", "set the title / artist" | metadata.py ep.mp4 --chapters chapters.txt (--title, --auto-chapters) |
| "a 4x2 grid of these videos" | grid.py t1.mp4 ... t8.mp4 --cols 4 --rows 2 |
| "stitch these clips", "add a crossfade" | join.py a.mp4 b.mp4 --transition fade --duration 0.5 |
| "join them without re-encoding" | join.py a.mp4 b.mp4 --copy --transition none |
| "several changes to one edit", 3+ steps | render.py project.json (--init writes one) |
| "I changed one stage, don't redo the rest" | render.py project.json --cache DIR |
| "open it in Premiere / Resolve / Final Cut" | render.py project.json --export-timeline edit.fcpxml |
| "every file in the folder", "use all the cores" | batch.py FOLDER --recipe batch.json --jobs auto |
| "three cameras, cut between them" | multicam.py a.mp4 b.mp4 c.mp4 --switch energy |
| "what's in this file", "is it Log?" | probe.py in.mp4 (--analyze) |
| "show me what it looks like", "title safe" | look.py out.mp4 --tiles 3x2, then view the PNG (--at T --guides title,action) |
| "static vs moving shots", "speech or music" | scenes.py in.mp4 --shots (--audio-peaks, --speech) |
| "where does the subject move" | cropdetect.py in.mp4 --motion-centre |
| "test the tool on my real files" | verify.py ~/Footage --report verify.md |