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 an equalizer icon to input.mp4 Title, artist: Golden Hour, Summer Drive
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 an equalizer icon 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 |
|---|---|---|
TITLE, ARTIST | Golden Hour, Summer Drive | The song title and the line under it. |
START | 0.5 | Second the card slides in. |
BPM | 120 | Tempo the bars bounce to; set it to your track's. |
SPEEDS | (1.0, 1.5, 0.75, 1.25) | Bounces per beat for each of the four bars. |
LOW | 0.25 | Shortest a bar gets, as a share of its full height. |
BAR_COLOR | (255, 205, 40) | Bar color. |
Y | 0.84 | Card center, as a share of the frame height. |
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 "now playing" card with an animated equalizer icon to input.mp4 (540x960, 30fps, a 120 BPM drum loop). The card is a dark (18, 18, 22) rounded pill at 84% opacity, 80% of the frame width by 9% of the frame height (432x86 pixels), fully rounded ends, centered horizontally with its center 84% of the way down. On it, starting 1.15 card-heights from its left edge, draw "Golden Hour" in bold white at 30% of the card height, its middle at 38% down the card, and under it "Summer Drive" in bold gray (185, 185, 195) at 21% of the card height, its middle at 70% down the card. At the card's left draw four yellow (255, 205, 40) bars with rounded ends, each 10% of the card height wide with gaps of 6.5% of the card height, the first starting 38% of the card height from the card's left edge, all standing on a shared baseline so that a full bar (48% of the card height) is centered vertically in the card. Bar i's height is full x (0.25 + 0.75 x |cos(pi x (beat x speed_i + phase_i))|), where beat = seconds x 120 / 60, speeds are 1.0, 1.5, 0.75, 1.25 and phases 0, 0.35, 0.6, 0.2, so the first bar is full height on every beat and at its shortest halfway between beats. Nothing is on screen before 0.5 seconds; the card then fades in while sliding up from 5% of the frame height lower over 0.4 seconds with an ease-out (1 - (1 - p)^3), and stays to the end. Use Python with Pillow to draw the card, text and bars (don't rely on ffmpeg's drawtext filter) and ffmpeg to put them on the video, keep the audio, and save it as output.mp4.Run it without Claude
This is the exact script we tested. Save it as equalizer-icon.py and run:
python3 equalizer-icon.py input.mp4 output.mp4Show the script
#!/usr/bin/env python3
"""Equalizer icon: a "now playing" card slides up with four yellow bars bouncing to the beat beside the song title.
Usage: python3 equalizer-icon.py input.mp4 output.mp4
Needs ffmpeg and Pillow (pip install pillow).
"""
import json
import math
import subprocess
import sys
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
TITLE, ARTIST = "Golden Hour", "Summer Drive"
START = 0.5 # second the card slides in
SLIDE = 0.4 # seconds the slide takes
BPM = 120 # tempo the bars bounce to
SPEEDS = (1.0, 1.5, 0.75, 1.25) # bounces per beat, one per bar
PHASES = (0.0, 0.35, 0.6, 0.2) # where each bar starts in its bounce (0-1)
LOW = 0.25 # shortest a bar gets, as a share of its full height
BAR_COLOR = (255, 205, 40) # bar color
CARD_W, CARD_H = 0.80, 0.09 # card size as shares of the frame width and height
Y = 0.84 # card center (0 = top, 1 = bottom)
FONTS = ["/System/Library/Fonts/Supplemental/Arial Bold.ttf", # macOS
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", # Linux
"C:/Windows/Fonts/arialbd.ttf"] # Windows
FONT_FILE = next((f for f in FONTS if Path(f).exists()), None) or sys.exit("No bold font found: add one to FONTS")
def card():
"""The dark rounded card with the title and artist, and the box where the bars go."""
cw, ch = round(w * CARD_W), round(h * CARD_H)
img = Image.new("RGBA", (cw, ch))
draw = ImageDraw.Draw(img)
draw.rounded_rectangle([0, 0, cw - 1, ch - 1], radius=ch // 2, fill=(18, 18, 22, 215))
text_x = round(ch * 1.15)
draw.text((text_x, ch * 0.38), TITLE, font=ImageFont.truetype(FONT_FILE, round(ch * 0.30)), anchor="lm", fill="white")
draw.text((text_x, ch * 0.70), ARTIST, font=ImageFont.truetype(FONT_FILE, round(ch * 0.21)), anchor="lm",
fill=(185, 185, 195))
return img
def bars(img, t):
"""Four bars standing on a shared baseline at the card's left, each bouncing at its own speed."""
ch = img.height
draw = ImageDraw.Draw(img)
full = ch * 0.48
bar_w, gap = ch * 0.10, ch * 0.065
x = ch * 0.38
base = ch / 2 + full / 2
beat = t * BPM / 60
for speed, phase in zip(SPEEDS, PHASES):
level = LOW + (1 - LOW) * abs(math.cos(math.pi * (beat * speed + phase)))
draw.rounded_rectangle([x, base - full * level, x + bar_w, base], radius=bar_w / 2, fill=BAR_COLOR)
x += bar_w + gap
def overlay(t):
img = Image.new("RGBA", (w, h))
p = min(max((t - START) / SLIDE, 0), 1)
if p == 0:
return img
ease = 1 - (1 - p) ** 3
c = base_card.copy()
bars(c, t)
c.putalpha(c.getchannel("A").point(lambda a: round(a * ease)))
img.alpha_composite(c, (round((w - c.width) / 2), round(h * Y - c.height / 2 + (1 - ease) * h * 0.05)))
return img
def probe(path):
info = json.loads(subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
"stream=width,height,r_frame_rate:format=duration", "-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), float(info["format"]["duration"])
def render(src, out):
"""Draw overlay(t) on every frame of src and save to out, keeping the audio."""
ff = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-i", src,
"-f", "rawvideo", "-pix_fmt", "rgba", "-s", f"{w}x{h}", "-r", rate, "-i", "-",
"-filter_complex", "[0:v][1:v]overlay=shortest=1,format=yuv420p[v]",
"-map", "[v]", "-map", "0:a?", "-c:v", "libx264", "-crf", "18", "-c:a", "copy", out],
stdin=subprocess.PIPE)
for i in range(math.ceil(duration * fps)):
ff.stdin.write(overlay(i / fps).tobytes())
ff.stdin.close()
if ff.wait():
sys.exit("ffmpeg failed")
src, out = sys.argv[1:3]
w, h, rate, fps, duration = probe(src)
base_card = card()
render(src, out)





