---
title: "How to add a film strip border with Claude (tested prompt and script)"
description: "The video plays inside one frame of a black film strip, with cream sprocket holes running down both edges and slivers of the next frames peeking in above and below. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/film-strip-border
---

# How to add a film strip border with Claude

The video plays inside one frame of a black film strip, with cream sprocket holes running down both edges and slivers of the next frames peeking in above and below.

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 film strip border to input.mp4
   Edge text: RCH 400  12A
   ```

## 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 film strip border 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                                               |
| ---------------- | ----------------- | ---------------------------------------------------------- |
| `RAIL`           | `0.12`            | Width of each sprocket rail as a share of the frame width. |
| `PICTURE`        | `0.72`            | Picture width as a share of the frame width.               |
| `GAP`            | `0.03`            | Black frame line between film frames.                      |
| `HOLE_W, HOLE_H` | `0.05, 0.07`      | Sprocket hole size as a share of the frame width.          |
| `PITCH`          | `0.12`            | Spacing between sprocket holes.                            |
| `FILM`           | `(18, 16, 14)`    | Film base color.                                           |
| `HOLE`           | `(250, 247, 240)` | Sprocket hole color.                                       |
| `EDGE_TEXT`      | `RCH 400 12A`     | Edge print up the left rail.                               |
| `EDGE_COLOR`     | `(235, 165, 40)`  | Edge print color.                                          |

## Without the skill

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

```
Put input.mp4 inside a film strip. Scale the video to 72% of the frame width (388x690 on a 540x960 clip, keeping its aspect) and center it, with corners rounded to 1.2% of the frame width. Fill everything around it with film base color (18, 16, 14). Repeat the same scaled video directly above and below it with a 3%-of-width (16 px) black frame line between them, so slivers of the neighboring film frames show at the top and bottom edges. Down each side, in a rail 12% of the frame width, draw a column of cream (250, 247, 240) sprocket holes 5% of the frame width wide and 7% tall with slightly rounded corners, one every 12% of the frame width, centered in the rail and spread evenly from top to bottom. Add small amber (235, 165, 40) edge print "RCH 400  12A" in a bold mono font at 2.6% of the frame width, rotated to read up the left side just inside the rail, beside the middle of the picture. Keep the strip on screen for the whole clip. Use Python with Pillow to draw the strip (draw any text with Pillow, not ffmpeg's drawtext) and ffmpeg to composite it, keep the audio and the original size, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `film-strip-border.py` and run:

```
python3 film-strip-border.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Film strip border: the video plays in one frame of a black film strip, with sprocket holes down both sides.

Usage: python3 film-strip-border.py input.mp4 output.mp4
Needs ffmpeg and Pillow (pip install pillow).
"""
import subprocess
import sys
import tempfile
from pathlib import Path

from PIL import Image, ImageDraw, ImageFont

RAIL = 0.12                  # width of each sprocket rail as a share of the frame width
PICTURE = 0.72               # picture width as a share of the frame width (centered, original aspect)
GAP = 0.03                   # black frame line between film frames, as a share of the frame width
HOLE_W, HOLE_H = 0.05, 0.07  # sprocket hole size as a share of the frame width
PITCH = 0.12                 # distance from one hole to the next, as a share of the frame width
FILM = (18, 16, 14)          # film base color
HOLE = (250, 247, 240)       # sprocket holes (light shining through)
EDGE_TEXT = "RCH 400  12A"   # edge print running up the left rail
EDGE_COLOR = (235, 165, 40)  # amber edge print
FONTS = ["/System/Library/Fonts/Supplemental/Courier New Bold.ttf",       # macOS
         "/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf",      # Linux
         "C:/Windows/Fonts/courbd.ttf"]                                   # Windows
FONT_FILE = next((f for f in FONTS if Path(f).exists()), None) or sys.exit("No mono font found: add one to FONTS")

def strip(w, h, pic_w, pic_h, top):
    """The film around the picture: rails with holes, frame lines, and a clear window for each film frame."""
    img = Image.new("RGBA", (w, h), FILM)
    draw = ImageDraw.Draw(img)
    x0, pitch = (w - pic_w) // 2, pic_h + round(w * GAP)
    for y in range(top - pitch, h, pitch):  # this frame and the neighbors above and below it
        draw.rounded_rectangle([x0, y, x0 + pic_w - 1, y + pic_h - 1], radius=round(w * 0.012), fill=(0, 0, 0, 0))
    hw, hh, step = round(w * HOLE_W), round(w * HOLE_H), w * PITCH
    for cx in (w * RAIL / 2, w * (1 - RAIL / 2)):
        y = (h % step) / 2 + (step - hh) / 2
        while y + hh <= h:
            draw.rounded_rectangle([cx - hw / 2, y, cx + hw / 2, y + hh], radius=round(hw * 0.2), fill=HOLE)
            y += step
    font = ImageFont.truetype(FONT_FILE, round(w * 0.026))
    box = font.getbbox(EDGE_TEXT)
    label = Image.new("RGBA", (box[2], box[3]))
    ImageDraw.Draw(label).text((0, 0), EDGE_TEXT, font=font, fill=EDGE_COLOR)
    label = label.rotate(90, expand=True)  # reads up the left rail, beside the middle of the picture
    img.alpha_composite(label, (round(w * (RAIL + 0.005)), top + (pic_h - label.height) // 2))
    return img

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).strip().split(","))
pic_w = round(w * PICTURE) // 2 * 2
pic_h = round(pic_w * h / w) // 2 * 2
top, pitch = (h - pic_h) // 2, pic_h + round(w * GAP)
x0 = (w - pic_w) // 2
with tempfile.TemporaryDirectory() as tmp:
    film = f"{tmp}/film.png"
    strip(w, h, pic_w, pic_h, top).save(film)
    # the picture, plus copies above and below so the neighboring film frames peek in at the edges
    subprocess.run(["ffmpeg", "-y", "-v", "error", "-i", src, "-loop", "1", "-i", film, "-filter_complex",
                    f"[0:v]fps=30,scale={pic_w}:{pic_h},split=3[p][a][b];"
                    f"color=black:s={w}x{h}:r=30[bg];"
                    f"[bg][p]overlay={x0}:{top}:shortest=1[v1];"
                    f"[v1][a]overlay={x0}:{top - pitch}[v2];"
                    f"[v2][b]overlay={x0}:{top + pitch}[v3];"
                    f"[v3][1:v]overlay=0:0:shortest=1,format=yuv420p[v]",
                    "-map", "[v]", "-map", "0:a?", "-c:v", "libx264", "-crf", "18", "-c:a", "copy", out], check=True)
```

## More retro and film

- [1950s color film look **1950s color film look**](https://www.recharm.com/effects/1950s-color-film-look)
- [35mm film look **35mm film look**](https://www.recharm.com/effects/35mm-film-look)
- [70s film look **70s film look**](https://www.recharm.com/effects/70s-film-look)
- [Camcorder date stamp **Camcorder date stamp**](https://www.recharm.com/effects/camcorder-date-stamp)
- [Camcorder viewfinder **Camcorder viewfinder**](https://www.recharm.com/effects/camcorder-viewfinder)

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