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 glitch on beat to input.mp4 Rough tempo, so the beat tracker doesn't lock onto every other beat: 120 Frames each glitch lasts, starting on the beat's frame: 4
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 glitch on beat 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 |
|---|---|---|
BPM_GUESS | 120 | Rough tempo, so the beat tracker doesn't lock onto every other beat. |
LENGTH | 4 | Frames each glitch lasts, starting on the beat's frame. |
SPLIT | 14 | How far red moves left and blue moves right, in pixels. |
TEARS | 5 | Horizontal bands torn sideways on each glitch frame. |
TEAR_SHIFT | 60 | Furthest a torn band slides sideways, in pixels. |
JUMP | 10 | Furthest the whole picture jumps, in pixels. |
SEED | 7 | Random seed; change it for a different but repeatable pattern of tears. |
RATE | 22050 | Audio sample rate the beat tracker uses. |
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 glitch on every beat to input.mp4. Use librosa to find the beats in its music track (start the beat tracker at 120 BPM and move each beat back to where its drum hit starts), and round each beat to a video frame. On each beat frame and the 3 frames after it (4 frames, about 0.13 seconds), glitch the picture: shift the whole frame by a random amount up to 10 pixels in each direction, slide 5 random horizontal bands (each 8 to 96 pixels tall) sideways by up to 60 pixels, then move the red channel 14 pixels left and the blue channel 14 pixels right (wrapping round the edges). Use a fixed random seed. Leave every other frame untouched. Keep the size, 30fps and the audio. Use ffmpeg and numpy and save it as output.mp4.Run it without Claude
This is the exact script we tested. Save it as glitch-on-beat.py and run:
python3 glitch-on-beat.py input.mp4 output.mp4Show the script
#!/usr/bin/env python3
"""Glitch on beat: librosa finds the beats in the music and on each one the picture splits into red and blue and tears.
Usage: python3 glitch-on-beat.py input.mp4 output.mp4 (the input needs a music track)
Needs ffmpeg, librosa and numpy (pip install librosa numpy).
"""
import json
import subprocess
import sys
import librosa
import numpy as np
BPM_GUESS = 120 # rough tempo, so the beat tracker doesn't lock onto every other beat
LENGTH = 4 # frames each glitch lasts, starting on the beat's frame
SPLIT = 14 # red moves this many pixels left and blue this many right
TEARS = 5 # horizontal bands torn sideways on each glitch frame
TEAR_SHIFT = 60 # furthest a torn band slides sideways, in pixels
JUMP = 10 # furthest the whole picture jumps, in pixels
SEED = 7 # change for a different (but repeatable) pattern of tears
RATE = 22050 # audio sample rate the beat tracker uses
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 beat_frames(path):
"""Video frame number of each beat, moved back to where its drum hit starts."""
pcm = subprocess.check_output(["ffmpeg", "-v", "error", "-i", path, "-ac", "1", "-ar", str(RATE), "-f", "f32le", "-"])
audio = np.frombuffer(pcm, np.float32)
hop = 256 # analysis step in samples (about 12ms), fine enough to land on the right video frame
strength = librosa.onset.onset_strength(y=audio, sr=RATE, hop_length=hop)
_, beats = librosa.beat.beat_track(onset_envelope=strength, sr=RATE, hop_length=hop, start_bpm=BPM_GUESS)
hits = librosa.frames_to_time(librosa.onset.onset_backtrack(beats, strength), sr=RATE, hop_length=hop)
return {round(t * fps) for t in hits}
def glitch(frame, rng):
"""Jump the whole picture, slide random bands sideways, then pull red and blue apart."""
img = np.roll(frame, [rng.integers(-JUMP, JUMP + 1), rng.integers(-JUMP, JUMP + 1)], axis=(0, 1))
for _ in range(TEARS):
y = rng.integers(0, h - 8)
band = slice(y, y + rng.integers(8, h // 10))
img[band] = np.roll(img[band], rng.integers(-TEAR_SHIFT, TEAR_SHIFT + 1), axis=1)
img[:, :, 0] = np.roll(img[:, :, 0], -SPLIT, axis=1)
img[:, :, 2] = np.roll(img[:, :, 2], SPLIT, axis=1)
return img
src, out = sys.argv[1:3]
w, h, rate, fps, duration = probe(src)
glitching = {b + i for b in beat_frames(src) for i in range(LENGTH)}
rng = np.random.default_rng(SEED)
reader = subprocess.Popen(["ffmpeg", "-v", "error", "-i", src, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
stdout=subprocess.PIPE)
writer = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{w}x{h}",
"-r", rate, "-i", "-", "-i", src, "-map", "0:v", "-map", "1: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
frame = np.frombuffer(raw, np.uint8).reshape(h, w, 3)
writer.stdin.write((glitch(frame, rng) if i in glitching else frame).tobytes())
i += 1
writer.stdin.close()
if writer.wait() or reader.wait():
sys.exit("ffmpeg failed")





