| "what's in this file", "how long is it", "is it 4K" |
probe.py input.mp4 |
| "cut from 1:20 to 2:05", "trim the first 10 seconds" |
cut.py input.mp4 --start 1:20 --end 2:05 |
| "keep only these parts", "remove the middle" |
cut.py input.mp4 --segments 0-1:00,1:30-2:00 |
| "make it exactly 60 seconds", "fit it in 30s" |
fit.py input.mp4 --duration 60 (speed) or --method trim |
| "make it vertical / for TikTok / 9:16", "square for Instagram" |
fit.py input.mp4 --aspect 9:16 --fit pad (or --fit crop) |
| "resize to a specific height, width follows" |
fit.py input.mp4 --height 1080 (or --width, or both for an exact frame) |
| "crop to this exact box/rectangle" (known x/y/width/height, not an aspect ratio) |
crop.py input.mp4 --x 100 --y 0 --width 1080 --height 1920 |
| "are there black bars on this?", "what's the crop rectangle to remove the letterboxing" |
cropdetect.py input.mp4 |
| "this old footage is interlaced / combed on motion" |
deinterlace.py input.mp4 |
| "this footage is grainy/noisy, clean it up" |
denoise.py input.mp4 --strength medium |
| "blur/pixelate this face/plate/region" (known x/y/width/height) |
redact.py input.mp4 --x 820 --y 140 --width 240 --height 240 --mode pixelate |
| "pull a flat clip out of this 360/spherical video, looking this way" (known yaw/pitch/fov, not "find the interesting part") |
sphere.py insta360.mp4 --yaw 90 --pitch 0 --h-fov 100 --v-fov 70 |
| "the horizon is tilted, straighten this out" (known degrees, not "auto-level") |
straighten.py tilted.mp4 --degrees -2.5 |
| "turn this image into a N-second clip", "title card / end slate" |
insert.py title.png --duration 3 |
| "slow zoom on a photo", "Ken Burns effect" |
insert.py photo.jpg --duration 6 --zoom in --pan right --width 1920 --height 1080 |
| "rotate this 90 degrees", "mirror it horizontally" |
fit.py input.mp4 --rotate 90 / fit.py input.mp4 --flip h |
| "reverse this clip", "play it backwards" |
reverse.py input.mp4 |
| "stabilize this shaky footage" |
stabilize.py input.mp4 |
| "make a blank/colour background clip" |
background.py -o bg.mp4 --duration 3 --width 1920 --height 1080 --color 0x101010 |
| "turn these numbered frames into a video" |
sequence.py --dir frames --pattern "frame_%04d.png" --fps 24 |
| "make a waveform/spectrum video for this podcast/track" |
waveform.py podcast.wav -o waveform.mp4 |
| "hold on this frame for a couple seconds", "freeze the last frame" |
freeze.py clip.mp4 --hold 2 |
| "add some black at the start before the title card" |
pad.py clip.mp4 --start 1.5 |
| "speed up here, slam into slow-mo there, then speed back up" (known segments) |
speedramp.py action.mp4 --segment 0-3:1.0 --segment 3-4:0.25 --segment 4-8:2.0 |
| "loop this background clip to fill 30 seconds" |
loop.py bg_loop.mp4 --duration 30 |
| "put these videos in a 4x2 grid with the filename on each" |
grid.py t1.mp4 t2.mp4 t3.mp4 t4.mp4 t5.mp4 t6.mp4 t7.mp4 t8.mp4 --cols 4 --rows 2 |
| "add subtitles from this SRT", "burn in captions" |
caption.py input.mp4 --srt subs.srt |
| "caption it with these lines" (plain text with times) |
caption.py input.mp4 --text cues.txt |
| "add subtitles but keep them toggleable / editable", "mux in an SRT, don't burn it" |
caption.py input.mp4 --srt subs.srt --mode mux |
| "put our logo top-right", "add a watermark" |
overlay.py input.mp4 --image logo.png --position top-right --scale 200 |
| "add a title for the first 4 seconds" |
overlay.py input.mp4 --text "Title" --position top --start 0 --end 4 --fade 0.4 |
| "put this webcam clip in the corner", "picture-in-picture" |
overlay.py input.mp4 --video webcam.mp4 --position bottom-right --scale 480 |
| "remove the green screen", "chroma key this" |
overlay.py bg.mp4 --video greenscreen.mp4 --chromakey 0x00ff00 |
| "sync the lav mic to the camera", "line up the two cameras" |
sync.py camera.mp4 mic.wav --replace-audio / sync.py camA.mp4 camB.mp4 --trim-second |
| "fix the audio levels", "normalise to -14 LUFS" |
loudness.py input.mp4 (-I -16 --tp -1.5 for podcasts, -I -23 for broadcast) |
| "export for YouTube / Reels / X", "give me a ProRes master", "make it HEVC" |
`export.py input.mp4 --preset youtube |
| "make a GIF preview" |
export.py input.mp4 --preset gif |
| "make a small/low-res proxy for an analysis pass", "a cheap preview file" |
proxy.py input.mp4 [--width 640 --no-audio] — not a delivery preset, see export.py for those |
| "cut out the pauses / dead air", "tighten it up", "jump cuts" |
silence.py input.mp4 [--threshold -40 --min-silence 0.8] |
| "stitch these clips together", "add a crossfade between them" |
join.py a.mp4 b.mp4 c.mp4 --transition fade --duration 0.5 |
| "show me what it looks like", "check the captions are readable" |
look.py output.mp4 then view the PNG |
| "what would you run?", "don't render yet" |
any script with --dry-run |
| "make a 60 s highlight from this hour", "find the good bits" |
scenes.py long.mp4 --highlights 6 --target 60 --edl picks.txt → cut.py --segments |
| "is this OK to upload?", "check it meets the Reels spec" |
check.py final.mp4 --platform reels |
| "set it up so I can tweak and re-render", "several changes to the same edit" |
render.py --init project.json, edit, render.py project.json |
| "add a lower third with my name", "title card", "countdown intro", "progress bar" |
graphics.py input.mp4 --template lower-third --name "..." --title "..." --start 2 --end 8 |
| "use our brand fonts/colours/logo" |
pass --brand brand.json to caption/overlay/graphics, or "brand" in project.json |
| "send me a summary of what you did" |
report.py --before raw.mov --after final.mp4 --platform youtube -o report.html |
| "do this to every file in the folder", "process the whole shoot" |
batch.py FOLDER --recipe batch.json (steps or a render project; cached) |
| "transcribe it and caption it" |
caption.py input.mp4 --transcribe --animate pop --karaoke (needs a local whisper; otherwise --text) |
| "three cameras, cut between them" |
multicam.py camA.mp4 camB.mp4 camC.mp4 --switch "0-20:0,20-40:1,40-60:2" |
| "it's an iPhone Dolby Vision clip and players show it wrong" |
color.py clip.mov --to-sdr or color.py clip.mov --strip-dovi (keep HDR, drop the DV layer) |
| "does it look like Log / S-Log / flat footage?" |
probe.py clip.mp4 --analyze (looks_like_log) then color.py --lut |
| "test the tool on my real files" |
verify.py ~/Footage --report verify.md |
| "show me progress", "quick preview first" |
any encoding script with --progress and/or --fast |
| "the colours look washed out / it's an iPhone HDR video" |
color.py input.mov --to-sdr (probe shows hdr: true) |
| "apply this LUT", "convert the S-Log / V-Log footage" |
color.py input.mp4 --lut grade.cube [--lut-strength 0.7] |
| "the colours are tagged wrong" |
color.py input.mp4 --retag bt709 (stream copy; re-encodes only if the copy can't carry the retagged colour info — check reencoded in --json) |
| "brighten it a touch / punch up the contrast and saturation / fix the white balance" |
color.py input.mp4 --correct --exposure 0.3 --contrast 1.1 --saturation 1.05 --temperature 5600 --tint -0.05 (typed, no filter string) |
| "clean up the audio", "remove the hiss / room noise" |
audio.py input.mp4 --voice (speech) or --denoise |
| "add background music under the talking" |
audio.py input.mp4 --music bed.mp3 --duck --fade-out 3 |
| "convert the 5.1 to stereo" |
audio.py input.mov --downmix |
| "swap in the narration track" |
audio.py input.mp4 --replace narration.wav |
| "pull the audio out of this video", "give me the sound as WAV" |
audio.py input.mp4 -o input.wav (any audio extension drops the picture; --audio-stream 1 picks another track) |
| "compress the voice", "limit the peaks to -1 dB", "gate the room noise" |
audio.py input.mp4 --compress --comp-threshold -20 --comp-ratio 4 / --limit --limit-ceiling -1 / --gate --gate-threshold -45 (typed acompressor / alimiter / agate options, range-checked) |
| "the audio drifts out of sync over the hour" |
sync.py camera.mp4 recorder.wav --fix-drift --replace-audio |
| "smooth slow motion", "half speed but fluid" |
fit.py input.mp4 --duration 2x --smooth interpolate (slow) or --smooth blend |
| "TikTok-style captions with the words popping / highlighted" |
caption.py input.mp4 --text cues.txt --animate pop --karaoke |
| "it's a phone video with variable frame rate" |
nothing extra: every re-encoding script conforms VFR to constant fps automatically; fit.py --fps 30 to pick the rate |