---
title: "How to add a camcorder viewfinder with Claude (tested prompt and script)"
description: "At half a second white corner brackets snap onto the frame with a blinking red REC dot top left, a battery icon top right, a running 00:00:00 counter bottom left and a \"JUN 14 1998\" date stamp bottom right, like looking through a 90s home-video camera. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/camcorder-viewfinder
---

# How to add a camcorder viewfinder with Claude

At half a second white corner brackets snap onto the frame with a blinking red REC dot top left, a battery icon top right, a running 00:00:00 counter bottom left and a "JUN 14 1998" date stamp bottom right, like looking through a 90s home-video camera.

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 camcorder viewfinder to input.mp4
   Date: JUN 14 1998
   ```

## 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 camcorder viewfinder 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                                                      |
| ----------- | ----------------- | ----------------------------------------------------------------- |
| `START`     | `0.5`             | Second the camcorder starts recording and the viewfinder appears. |
| `COLOR`     | `(255, 255, 255)` | Bracket, icon and text color.                                     |
| `REC_COLOR` | `(230, 30, 45)`   | Recording dot color.                                              |
| `INSET`     | `36`              | Corner brackets' distance from the frame edge, in pixels.         |
| `BATTERY`   | `3`               | Battery bars lit, out of 4.                                       |
| `DATE`      | `JUN 14 1998`     | Date stamp, bottom right.                                         |

## Without the skill

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

```
Add a camcorder viewfinder overlay to input.mp4, all lines and text in white (255, 255, 255) with a soft dark shadow (black, 3-pixel blur) behind them. Before 0.5 seconds the video is untouched; at 0.5s the whole overlay appears at once. Four L-shaped corner brackets, arms 60 pixels long and 4 pixels thick, corners 36 pixels in from each frame edge, and a small 28-pixel cross, 2 pixels thick, centered on the frame. Top left, 48 pixels below the top bracket's line and 34 pixels in from the left one: a red (230, 30, 45) dot with a radius of 3% of the frame width, lit for the first half of every second from 0.5s (on 0.5-1.0s, off 1.0-1.5s, and so on), with "REC" in bold white 12 pixels to its right (it stays when the dot blinks off). Top right at the same height, its right edge 34 pixels inside the right bracket: a battery outline 11% of the frame width wide and 5% tall, 3 pixels thick, with a small nub on the right and 3 of 4 bars filled. Bottom row, 48 pixels above the bottom bracket's line and 24 pixels inside the brackets: a running mm:ss:ff counter that starts at 00:00:00 at 0.5s on the left and "JUN 14 1998" right-aligned on the right. Text is bold, 5% of the frame width tall. Leave the middle of the footage unchanged. Draw it with Python and Pillow (don't use ffmpeg's drawtext filter), composite it with ffmpeg, keep the audio, and save it as output.mp4 at 30fps.
```

## Run it without Claude

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

```
python3 camcorder-viewfinder.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Camcorder viewfinder: a blinking red REC dot, battery icon, corner brackets, timecode and date stamp frame the video.

Usage: python3 camcorder-viewfinder.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, ImageFilter, ImageFont

START = 0.5                 # second the camcorder starts recording and the viewfinder appears
COLOR = (255, 255, 255)     # bracket, icon and text color
REC_COLOR = (230, 30, 45)   # recording dot color
INSET = 36                  # corner brackets' distance from the frame edge, in pixels
ARM = 60                    # length of each bracket arm, in pixels
LINE = 4                    # bracket thickness in pixels
BATTERY = 3                 # battery bars lit, out of 4
DATE = "JUN 14 1998"        # date stamp, bottom right
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 brackets(draw):
    """L-shaped brackets in the four corners and a small cross in the middle."""
    for sx, sy in [(1, 1), (-1, 1), (1, -1), (-1, -1)]:
        x = INSET if sx > 0 else w - 1 - INSET
        y = INSET if sy > 0 else h - 1 - INSET
        draw.line([(x, y + sy * ARM), (x, y), (x + sx * ARM, y)], fill=COLOR, width=LINE, joint="curve")
    cx, cy = w / 2, h / 2
    draw.line([(cx - 14, cy), (cx + 14, cy)], fill=COLOR, width=2)
    draw.line([(cx, cy - 14), (cx, cy + 14)], fill=COLOR, width=2)

def rec(draw, t):
    """Red dot (lit for the first half of every second) and "REC", top left inside the brackets."""
    r, x, y = round(w * 0.03), INSET + 34, INSET + 48
    if (t - START) % 1 < 0.5:
        draw.ellipse([x - r, y - r, x + r, y + r], fill=REC_COLOR)
    draw.text((x + r + 12, y), "REC", font=font, fill=COLOR, anchor="lm")

def battery(draw):
    """Battery outline with BATTERY of 4 bars lit, top right inside the brackets."""
    bw, bh = round(w * 0.11), round(w * 0.05)
    x1, y = w - INSET - 34, INSET + 48
    x0 = x1 - bw
    draw.rectangle([x0, y - bh / 2, x1, y + bh / 2], outline=COLOR, width=3)
    draw.rectangle([x1 + 1, y - bh / 5, x1 + 6, y + bh / 5], fill=COLOR)
    bar = (bw - 10 - 3 * 3) / 4
    for i in range(BATTERY):
        bx = x0 + 5 + i * (bar + 3)
        draw.rectangle([bx, y - bh / 2 + 5, bx + bar, y + bh / 2 - 5], fill=COLOR)

def stamps(draw, t):
    """Running recording time bottom left, the date stamp bottom right."""
    frames = round((t - START) * 30)
    y = h - INSET - 48
    draw.text((INSET + 24, y), f"{frames // 1800:02d}:{frames // 30 % 60:02d}:{frames % 30:02d}", font=font,
              fill=COLOR, anchor="lm")
    draw.text((w - INSET - 24, y), DATE, font=font, fill=COLOR, anchor="rm")

def overlay(t):
    img = Image.new("RGBA", (w, h))
    if t < START:
        return img
    draw = ImageDraw.Draw(img)
    brackets(draw)
    rec(draw, t)
    battery(draw)
    stamps(draw, t)
    shadow = Image.new("RGBA", (w, h), (0, 0, 0))
    shadow.putalpha(img.getchannel("A").filter(ImageFilter.GaussianBlur(3)).point(lambda a: min(160, a * 2)))
    shadow.alpha_composite(img)
    return shadow

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)
font = ImageFont.truetype(FONT_FILE, round(w * 0.05))
render(src, out)
```

## 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)
- [Color bars test pattern **Color bars test pattern**](https://www.recharm.com/effects/color-bars-test-pattern)

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