---
title: "How to add a video inside text with Claude (tested prompt and script)"
description: "A black card fades in over the shot, and the footage keeps playing only inside the tall letters \"PURE\" and \"GLOW\" cut out of it. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/video-inside-text
---

# How to add a video inside text with Claude

A black card fades in over the shot, and the footage keeps playing only inside the tall letters "PURE" and "GLOW" cut out of it.

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 a video inside text to input.mp4
   Lines: ["PURE", "GLOW"]
   ```

## 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 video inside text 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                                                                 |
| --------- | ------------------ | ---------------------------------------------------------------------------- |
| `LINES`   | `["PURE", "GLOW"]` | The words the video shows through, one per line.                             |
| `WIDTH`   | `0.90`             | Widest line as a share of the frame width.                                   |
| `STRETCH` | `1.6`              | How many times taller than normal the letters are drawn.                     |
| `CENTERS` | `[0.36, 0.64]`     | Where each line's middle sits, 0-1 down the frame.                           |
| `CARD`    | `(10, 10, 14)`     | Color everywhere outside the letters.                                        |
| `START`   | `1.0`              | Second the card starts to fade in.                                           |
| `FADE`    | `0.5`              | Seconds the fade takes.                                                      |
| `SMOOTH`  | `4`                | How much larger the card is drawn before shrinking, for smooth letter edges. |

## Without the skill

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

```
Make the video in input.mp4 play inside text. Use Python with Pillow (not ffmpeg's drawtext) to draw one overlay image the size of the video: a solid (10, 10, 14) near-black card with the words "PURE" and "GLOW" cut out of it as fully transparent holes, one word per line, in Arial Black (or another heavy bold font). Size the font so the wider word is 90% of the frame width, then stretch each word 1.6 times taller, and center the words horizontally with their middles at 36% and 64% down the frame. Draw it at 4x size and shrink it for smooth edges. With ffmpeg, put the card over every frame, fading the card in from fully transparent starting at 1.0 seconds over 0.5 seconds, so the plain video shows for the first second and only the letters show video from 1.5 seconds to the end. Keep the audio, the original size and length, 30fps H.264 yuv420p, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `video-inside-text.py` and run:

```
python3 video-inside-text.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Video inside text: a black card fades in and the footage keeps playing only inside two lines of huge letters.

Usage: python3 video-inside-text.py input.mp4 output.mp4
Needs ffmpeg and Pillow (pip install pillow).
"""
import io
import subprocess
import sys
from pathlib import Path

from PIL import Image, ImageDraw, ImageFont

LINES = ["PURE", "GLOW"]         # the words the video shows through, one per line
WIDTH = 0.90                     # widest line as a share of the frame width
STRETCH = 1.6                    # letters drawn this many times taller than normal
CENTERS = [0.36, 0.64]           # where each line's middle sits (0-1 down the frame)
CARD = (10, 10, 14)              # color everywhere outside the letters
START = 1.0                      # second the card starts to fade in
FADE = 0.5                       # seconds the fade takes
SMOOTH = 4                       # draw this many times larger, then shrink, for smooth letter edges
FONTS = ["/System/Library/Fonts/Supplemental/Arial Black.ttf",    # macOS
         "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",  # Linux
         "C:/Windows/Fonts/ariblk.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(w, h):
    """The card with see-through letters cut out of it."""
    W, H = w * SMOOTH, h * SMOOTH
    probe_font = ImageFont.truetype(FONT_FILE, 100)
    widest = max(probe_font.getlength(line) for line in LINES)
    font = ImageFont.truetype(FONT_FILE, round(100 * WIDTH * W / widest))
    letters = Image.new("L", (W, H))
    for line, y in zip(LINES, CENTERS):
        word = Image.new("L", (W, H))
        ImageDraw.Draw(word).text((W / 2, H / 2), line, font=font, anchor="mm", fill=255)
        word = word.crop(word.getbbox())
        word = word.resize((word.width, round(word.height * STRETCH)), Image.LANCZOS)
        letters.paste(word, (round((W - word.width) / 2), round(H * y - word.height / 2)))
    big = Image.new("RGBA", (W, H), CARD + (255,))
    big.putalpha(letters.point(lambda v: 255 - v))
    return big.resize((w, h), Image.LANCZOS)

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).split(","))
png = io.BytesIO()
card(w, h).save(png, "PNG")
subprocess.run(["ffmpeg", "-y", "-v", "error", "-i", src, "-loop", "1", "-f", "png_pipe", "-i", "-",
                "-filter_complex", f"[1:v]format=rgba,fade=in:st={START}:d={FADE}:alpha=1[card];"
                                   "[0:v][card]overlay=shortest=1,fps=30,format=yuv420p[v]",
                "-map", "[v]", "-map", "0:a?", "-c:v", "libx264", "-crf", "18", "-c:a", "copy", out],
               input=png.getvalue(), check=True)
```

## 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)
