How to add a laser beam with Claude

A red laser fires in from the left edge, its glowing tip racing across the frame past the bottle's neck in a quarter second, then the white-hot beam hangs there flickering before it fades.

Get this effect

  1. Switch to Code in your Claude Desktop App

  2. 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/skills
  3. Ask for the effect

    Add a laser beam to input.mp4
    Where the beam enters and leaves, as shares across and down the frame: (0.0, 0.30), (1.0, 0.42)
    Second the beam fires, and how many seconds its tip takes to cross the frame: 1.0, 0.25

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 laser beam 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.

SettingDefaultWhat it does
FROM, TO(0.0, 0.30), (1.0, 0.42)Where the beam enters and leaves, as shares across and down the frame.
START, SHOOT1.0, 0.25Second the beam fires, and how many seconds its tip takes to cross the frame.
END, FADE3.0, 0.4Second it has faded out by, and how many seconds the fade takes.
CORE, HALO2.5, 14Half-widths in pixels of the white-hot core and the red glow around it.
CORE_COLOR, HALO_COLOR(255, 240, 240), (255, 30, 50)Colors of the core and the glow.

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 laser beam to input.mp4. The beam is a straight line from the left edge 30% down the frame to the right edge 42% down. With d the distance in pixels from that line, draw a red (255, 30, 50) glow of strength 0.85*exp(-(d/14)^2) and, over it, a near-white (255, 240, 240) core of strength exp(-(d/2.5)^2); blend each over the frame as frame*(1-a) + color*a. Timing: every frame before 1.0 seconds is untouched. At 1.0 seconds the beam fires: its tip travels from the left edge to the right edge along the line over 0.25 seconds at constant speed, with nothing drawn past the tip (a soft 4-pixel end), and a round hot spot (Gaussian, sigma 10 pixels, same core and glow colors) rides on the tip while it moves. Once across, the beam holds, flickering by multiplying its strength by 1 - 0.08*sin(2*pi*15*t), and fades out linearly from 2.6 to 3.0 seconds; every frame from 3.0 seconds on is untouched. Use Python with numpy to draw and blend the beam and ffmpeg to read and write the video (no drawtext), keep the size, 30fps, length and audio, and save it as output.mp4.

Run it without Claude

This is the exact script we tested. Save it as laser-beam.py and run:

python3 laser-beam.py input.mp4 output.mp4
Show the script
#!/usr/bin/env python3
"""Laser beam: a thin red beam with a white-hot core shoots across the frame from the left edge, holds, then fades.

Usage: python3 laser-beam.py input.mp4 output.mp4
Needs ffmpeg and numpy (pip install numpy).
"""
import json
import subprocess
import sys

import numpy as np

FROM = (0.0, 0.30)          # where the beam enters (0-1 across and down the frame)
TO = (1.0, 0.42)            # where it leaves
START = 1.0                 # second the beam fires
SHOOT = 0.25                # seconds the beam's tip takes to cross the frame
END = 3.0                   # second it has faded out by
FADE = 0.4                  # seconds the fade-out takes
CORE = 2.5                  # half-width of the white-hot core, in pixels
HALO = 14                   # half-width of the red glow around it, in pixels
CORE_COLOR = (255, 240, 240)   # the core: near white with a touch of red
HALO_COLOR = (255, 30, 50)     # the glow: laser red


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)


def strength(t):
    """0-1: how bright the beam is at time t, with a fast laser flicker."""
    if t < START or t >= END:
        return 0.0
    fade = min((END - t) / FADE, 1)
    return fade * (1 - 0.08 * np.sin(t * 2 * np.pi * 15))


def beam(t):
    """Two masks (0-1) for time t: the core and the glow, cut off past the beam's tip, plus a hot spot at the tip."""
    tip = min((t - START) / SHOOT, 1)
    reached = np.clip((tip - along) * length / 4, 0, 1)    # soft 4-pixel end at the tip
    core = np.exp(-(across / CORE) ** 2) * reached
    glow = 0.85 * np.exp(-(across / HALO) ** 2) * reached
    if tip < 1:                                            # a flare rides on the tip while it travels
        spot = np.exp(-((along - tip) * length) ** 2 / (2 * 10 ** 2) - across ** 2 / (2 * 10 ** 2))
        core, glow = np.maximum(core, spot), np.maximum(glow, np.minimum(spot * 3, 0.85))
    return core[..., None], glow[..., None]


src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
y, x = np.mgrid[0:h, 0:w].astype(np.float32)
(ax, ay), (bx, by) = (FROM[0] * w, FROM[1] * h), (TO[0] * w, TO[1] * h)
length = np.hypot(bx - ax, by - ay)
along = ((x - ax) * (bx - ax) + (y - ay) * (by - ay)) / length ** 2   # 0 at the entry point, 1 at the exit
across = np.abs((x - ax) * (by - ay) - (y - ay) * (bx - ax)) / length  # pixels from the beam's center line
core_rgb, halo_rgb = np.array(CORE_COLOR, np.float32), np.array(HALO_COLOR, np.float32)

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 raw := reader.stdout.read(w * h * 3):
    img = np.frombuffer(raw, np.uint8).reshape(h, w, 3)
    t = i / fps
    s = strength(t)
    if s > 0:
        core, glow = beam(t)
        frame = img * (1 - glow * s) + halo_rgb * glow * s           # red glow
        frame = frame * (1 - core * s) + core_rgb * core * s         # white-hot core on top
        img = np.clip(frame, 0, 255).astype(np.uint8)
    writer.stdin.write(img.tobytes())
    i += 1
writer.stdin.close()
if reader.wait() or writer.wait():
    sys.exit("ffmpeg failed")

Find 3x winning ads

Recharm cuts your ad footage into tagged, searchable clips: hooks, testimonials, product shots. Find the shots that win, add the effect with Claude, and ship 3x more ad edits.

Start 14-day free trial