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 a film strip border to input.mp4 Edge text: RCH 400 12A
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 a film strip border 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 |
|---|---|---|
RAIL | 0.12 | Width of each sprocket rail as a share of the frame width. |
PICTURE | 0.72 | Picture width as a share of the frame width. |
GAP | 0.03 | Black frame line between film frames. |
HOLE_W, HOLE_H | 0.05, 0.07 | Sprocket hole size as a share of the frame width. |
PITCH | 0.12 | Spacing between sprocket holes. |
FILM | (18, 16, 14) | Film base color. |
HOLE | (250, 247, 240) | Sprocket hole color. |
EDGE_TEXT | RCH 400 12A | Edge print up the left rail. |
EDGE_COLOR | (235, 165, 40) | Edge print color. |
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
Put input.mp4 inside a film strip. Scale the video to 72% of the frame width (388x690 on a 540x960 clip, keeping its aspect) and center it, with corners rounded to 1.2% of the frame width. Fill everything around it with film base color (18, 16, 14). Repeat the same scaled video directly above and below it with a 3%-of-width (16 px) black frame line between them, so slivers of the neighboring film frames show at the top and bottom edges. Down each side, in a rail 12% of the frame width, draw a column of cream (250, 247, 240) sprocket holes 5% of the frame width wide and 7% tall with slightly rounded corners, one every 12% of the frame width, centered in the rail and spread evenly from top to bottom. Add small amber (235, 165, 40) edge print "RCH 400 12A" in a bold mono font at 2.6% of the frame width, rotated to read up the left side just inside the rail, beside the middle of the picture. Keep the strip on screen for the whole clip. Use Python with Pillow to draw the strip (draw any text with Pillow, not ffmpeg's drawtext) and ffmpeg to composite it, keep the audio and the original size, and save it as output.mp4.Run it without Claude
This is the exact script we tested. Save it as film-strip-border.py and run:
python3 film-strip-border.py input.mp4 output.mp4Show the script
#!/usr/bin/env python3
"""Film strip border: the video plays in one frame of a black film strip, with sprocket holes down both sides.
Usage: python3 film-strip-border.py input.mp4 output.mp4
Needs ffmpeg and Pillow (pip install pillow).
"""
import subprocess
import sys
import tempfile
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
RAIL = 0.12 # width of each sprocket rail as a share of the frame width
PICTURE = 0.72 # picture width as a share of the frame width (centered, original aspect)
GAP = 0.03 # black frame line between film frames, as a share of the frame width
HOLE_W, HOLE_H = 0.05, 0.07 # sprocket hole size as a share of the frame width
PITCH = 0.12 # distance from one hole to the next, as a share of the frame width
FILM = (18, 16, 14) # film base color
HOLE = (250, 247, 240) # sprocket holes (light shining through)
EDGE_TEXT = "RCH 400 12A" # edge print running up the left rail
EDGE_COLOR = (235, 165, 40) # amber edge print
FONTS = ["/System/Library/Fonts/Supplemental/Courier New Bold.ttf", # macOS
"/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf", # Linux
"C:/Windows/Fonts/courbd.ttf"] # Windows
FONT_FILE = next((f for f in FONTS if Path(f).exists()), None) or sys.exit("No mono font found: add one to FONTS")
def strip(w, h, pic_w, pic_h, top):
"""The film around the picture: rails with holes, frame lines, and a clear window for each film frame."""
img = Image.new("RGBA", (w, h), FILM)
draw = ImageDraw.Draw(img)
x0, pitch = (w - pic_w) // 2, pic_h + round(w * GAP)
for y in range(top - pitch, h, pitch): # this frame and the neighbors above and below it
draw.rounded_rectangle([x0, y, x0 + pic_w - 1, y + pic_h - 1], radius=round(w * 0.012), fill=(0, 0, 0, 0))
hw, hh, step = round(w * HOLE_W), round(w * HOLE_H), w * PITCH
for cx in (w * RAIL / 2, w * (1 - RAIL / 2)):
y = (h % step) / 2 + (step - hh) / 2
while y + hh <= h:
draw.rounded_rectangle([cx - hw / 2, y, cx + hw / 2, y + hh], radius=round(hw * 0.2), fill=HOLE)
y += step
font = ImageFont.truetype(FONT_FILE, round(w * 0.026))
box = font.getbbox(EDGE_TEXT)
label = Image.new("RGBA", (box[2], box[3]))
ImageDraw.Draw(label).text((0, 0), EDGE_TEXT, font=font, fill=EDGE_COLOR)
label = label.rotate(90, expand=True) # reads up the left rail, beside the middle of the picture
img.alpha_composite(label, (round(w * (RAIL + 0.005)), top + (pic_h - label.height) // 2))
return img
src, out = sys.argv[1:3]
w, h = map(int, subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
"stream=width,height", "-of", "csv=p=0", src], text=True).strip().split(","))
pic_w = round(w * PICTURE) // 2 * 2
pic_h = round(pic_w * h / w) // 2 * 2
top, pitch = (h - pic_h) // 2, pic_h + round(w * GAP)
x0 = (w - pic_w) // 2
with tempfile.TemporaryDirectory() as tmp:
film = f"{tmp}/film.png"
strip(w, h, pic_w, pic_h, top).save(film)
# the picture, plus copies above and below so the neighboring film frames peek in at the edges
subprocess.run(["ffmpeg", "-y", "-v", "error", "-i", src, "-loop", "1", "-i", film, "-filter_complex",
f"[0:v]fps=30,scale={pic_w}:{pic_h},split=3[p][a][b];"
f"color=black:s={w}x{h}:r=30[bg];"
f"[bg][p]overlay={x0}:{top}:shortest=1[v1];"
f"[v1][a]overlay={x0}:{top - pitch}[v2];"
f"[v2][b]overlay={x0}:{top + pitch}[v3];"
f"[v3][1:v]overlay=0:0:shortest=1,format=yuv420p[v]",
"-map", "[v]", "-map", "0:a?", "-c:v", "libx264", "-crf", "18", "-c:a", "copy", out], check=True)





