---
title: "How to add rolling credits with Claude (tested prompt and script)"
description: "The clip fades to black, then gray roles and white names glide up from the bottom of the screen at an even pace, like a film's end credits. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/rolling-credits
---

# How to add rolling credits with Claude

The clip fades to black, then gray roles and white names glide up from the bottom of the screen at an even pace, like a film's end credits.

Made by the script on this page, from our own test clip.

## Get this effect

1. ### Switch to Code in your [Claude Desktop App](https://claude.com/download)

2. ### Install the skill (once)

   ```
   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 rolling credits to input.mp4
   Credits: [("Directed by", "Maya Chen"), ...]
   ```

## 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 rolling credits 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                                |
| ---------------------- | ------------------------------------- | ------------------------------------------- |
| `CREDITS`              | `[("Directed by", "Maya Chen"), ...]` | The (role, name) pairs, top to bottom.      |
| `FADE_START`           | `1.0`                                 | Second the clip starts fading to black.     |
| `FADE`                 | `0.5`                                 | Seconds the fade takes.                     |
| `ROLL_START`           | `1.5`                                 | Second the first line enters at the bottom. |
| `SPEED`                | `200`                                 | Pixels the credits move up each second.     |
| `ROLE_SIZE, NAME_SIZE` | `0.042, 0.068`                        | Text heights as a share of the frame width. |
| `ROLE_COLOR`           | `(160, 160, 160)`                     | Color of the small role line.               |
| `NAME_COLOR`           | `(255, 255, 255)`                     | Color of the name line.                     |
| `GAP`                  | `1.6`                                 | Space between entries, in name heights.     |

## Without the skill

Don’t want to install the skill? Paste this prompt into Claude Code and Claude writes the script itself.

```
Add rolling end credits to input.mp4 (540x960). Play the clip untouched until 1.0 seconds, then fade it to solid black between 1.0 and 1.5 seconds and keep it black to the end. From 1.5 seconds, scroll five centered credits up from the bottom edge at a steady 200 pixels per second: "Directed by" / "Maya Chen", "Starring" / "The Glow Serum", "Cinematography" / "Leo Park", "Music" / "The Late Hours", "Edited with" / "Claude". Each role is in capitals, 23 pixels tall, gray (160, 160, 160), with its name 34 pixels below it in white (255, 255, 255) Arial Bold 37 pixels tall; entries start 131 pixels apart. The top of the first role line is at the bottom edge (y = 960) at 1.5 seconds and 200 pixels higher each second after, so at 6 seconds all five credits are on screen. Draw the credits once on a tall transparent image and move it each frame. Use Python with Pillow to draw the text (don't rely on ffmpeg's drawtext filter) and ffmpeg to put it on the video, keep the audio and the 6 second length at 30fps, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `rolling-credits.py` and run:

```
python3 rolling-credits.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Rolling credits: the clip fades to black and white names scroll steadily up the screen, like the end of a film.

Usage: python3 rolling-credits.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

CREDITS = [("Directed by", "Maya Chen"),       # (role, name) pairs, top to bottom
           ("Starring", "The Glow Serum"),
           ("Cinematography", "Leo Park"),
           ("Music", "The Late Hours"),
           ("Edited with", "Claude")]
FADE_START = 1.0          # second the clip starts fading to black
FADE = 0.5                # seconds the fade takes
ROLL_START = 1.5          # second the first line enters at the bottom
SPEED = 200               # pixels the credits move up each second
ROLE_SIZE, NAME_SIZE = 0.042, 0.068  # text heights as a share of the frame width
ROLE_COLOR = (160, 160, 160)  # small gray role line
NAME_COLOR = (255, 255, 255)  # big white name line
GAP = 1.6                 # space between entries, in name heights
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 credits_strip():
    """Every credit drawn once on a tall transparent strip as wide as the frame, centered."""
    role_font = ImageFont.truetype(FONT_FILE, round(w * ROLE_SIZE))
    name_font = ImageFont.truetype(FONT_FILE, round(w * NAME_SIZE))
    entry = role_font.size * 1.5 + name_font.size * (1 + GAP)
    strip = Image.new("RGBA", (w, math.ceil(entry * len(CREDITS))))
    draw = ImageDraw.Draw(strip)
    for i, (role, name) in enumerate(CREDITS):
        y = i * entry
        draw.text((w / 2, y), role.upper(), font=role_font, anchor="mt", fill=ROLE_COLOR)
        draw.text((w / 2, y + role_font.size * 1.5), name, font=name_font, anchor="mt", fill=NAME_COLOR)
    return strip

def overlay(t):
    """Black fading in over the clip, with the strip's top edge SPEED pixels higher every second after ROLL_START."""
    fade = min(max((t - FADE_START) / FADE, 0), 1)
    img = Image.new("RGBA", (w, h), (0, 0, 0, round(255 * fade)))
    if t >= ROLL_START:
        img.alpha_composite(strip, (0, round(h - (t - ROLL_START) * SPEED)))  # Pillow clips what falls off the frame
    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)
strip = credits_strip()
render(src, out)
```

## More text and titles

- [Animated text frame **Animated text frame**](https://www.recharm.com/effects/animated-text-frame)
- [Brush stroke text reveal **Brush stroke text reveal**](https://www.recharm.com/effects/brush-stroke-text-reveal)
- [Burning text **Burning text**](https://www.recharm.com/effects/burning-text)
- [Drop shadow text **Drop shadow text**](https://www.recharm.com/effects/drop-shadow-text)
- [Echo text **Echo text**](https://www.recharm.com/effects/echo-text)

## 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](https://www.recharm.com/get-started)
