Get this effect
Switch to Code in your Claude Desktop App
Install the skill (once)
Show the prompt
Install the Recharm video effects skill: download https://recharm-growth-staging.s3.us-east-2.amazonaws.com/website/downloads/recharm-video-effects.zip and unzip it into ~/.claude/skillsAsk for the effect
Add spotlight focus to input.mp4 Second the spotlight starts closing in: 1.0 Seconds it takes to settle: 0.6
Several videos, several effects, one ask
Put your clips in the folder, mention them with @, and ask for everything at once. Claude runs one tested script after another on each clip, then joins them.
Add spotlight focus to @clip1.mp4, put a sale badge on @clip2.mp4, give @clip3.mp4 a VHS look, then join all three with crossfades.
Settings you can change
Ask Claude to change any of these, or edit them at the top of the script.
| Setting | Default | What it does |
|---|---|---|
START | 1.0 | Second the spotlight starts closing in. |
CLOSE | 0.6 | Seconds it takes to settle. |
X, Y | 0.5, 0.52 | Circle center, as shares of the frame width and height. |
RADIUS | 0.42 | Final circle radius as a share of the frame width. |
FEATHER | 0.08 | Width of the soft edge as a share of the frame width. |
DIM | 0.22 | Brightness kept outside the circle (0 is black, 1 is untouched). |
Without the skill
Don’t want to install the skill? Paste this prompt into Claude Code and Claude writes the script itself.
Show the prompt
Add a spotlight to input.mp4 with Python and numpy, using ffmpeg to read and write the frames. Before 1.0 seconds leave the video untouched. From 1.0 to 1.6 seconds (ease-out), a circle centered at 50% across and 52% down closes in from a radius of 105% of the frame width to 42% of the frame width (227 px on a 540-wide frame), while everything outside it fades to 22% of its brightness. Give the circle a soft edge 8% of the frame width wide; inside it the picture keeps its full brightness. Hold the spotlight to the end. There's no text to draw, but if you add any, draw it with Pillow, not ffmpeg's drawtext. Keep the audio and save it as output.mp4.Run it without Claude
This is the exact script we tested. Save it as spotlight-focus.py and run:
python3 spotlight-focus.py input.mp4 output.mp4Show the script
#!/usr/bin/env python3
"""Spotlight focus: the frame goes dark except a soft-edged bright circle that closes in on the product.
Usage: python3 spotlight-focus.py input.mp4 output.mp4
Needs ffmpeg and numpy (pip install numpy).
"""
import json
import subprocess
import sys
import numpy as np
START = 1.0 # second the spotlight starts closing in
CLOSE = 0.6 # seconds it takes to settle
X, Y = 0.5, 0.52 # circle center (0-1 across and down the frame)
RADIUS = 0.42 # final circle radius as a share of the frame width
FEATHER = 0.08 # soft edge width as a share of the frame width
DIM = 0.22 # brightness kept outside the circle (0 = black, 1 = untouched)
def ease_out(p):
p = min(max(p, 0), 1)
return 1 - (1 - p) ** 3
def light(t):
"""Per-pixel brightness multiplier at time t: 1 inside the circle, DIM outside."""
p = ease_out((t - START) / CLOSE) if t >= START else 0
if p == 0:
return None
radius = w * RADIUS * (2.5 - 1.5 * p) # starts wide and closes in on the product
inside = np.clip((radius - dist) / (w * FEATHER) + 0.5, 0, 1)
dim = 1 - (1 - DIM) * p # the dark fades in as the circle closes
return (dim + (1 - dim) * inside)[:, :, None]
def probe(path):
info = json.loads(subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
"stream=width,height,r_frame_rate", "-of", "json", path]))
s = info["streams"][0]
num, den = s["r_frame_rate"].split("/")
return s["width"], s["height"], s["r_frame_rate"], float(num) / float(den)
src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
yy, xx = np.mgrid[0:h, 0:w]
dist = np.hypot(xx - w * X, yy - h * Y)
reader = subprocess.Popen(["ffmpeg", "-v", "error", "-i", src, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
stdout=subprocess.PIPE)
writer = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-i", src,
"-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{w}x{h}", "-r", rate, "-i", "-",
"-map", "1:v", "-map", "0:a?", "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p",
"-c:a", "copy", "-shortest", out], stdin=subprocess.PIPE)
i = 0
while True:
raw = reader.stdout.read(w * h * 3)
if len(raw) < w * h * 3:
break
img = np.frombuffer(raw, np.uint8).reshape(h, w, 3)
mask = light(i / fps)
writer.stdin.write(img.tobytes() if mask is None else (img * mask).astype(np.uint8).tobytes())
i += 1
writer.stdin.close()
if reader.wait() or writer.wait():
sys.exit("ffmpeg failed")





