---
title: "How to add a record scratch freeze with Claude (tested prompt and script)"
description: "A record scratch cuts the sound 1.5 seconds in and the shot freezes, drained almost to gray, under a yellow \"Yep, that's me.\" before the clip plays on from where it stopped. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/record-scratch-freeze
---

# How to add a record scratch freeze with Claude

A record scratch cuts the sound 1.5 seconds in and the shot freezes, drained almost to gray, under a yellow "Yep, that's me." before the clip plays on from where it stopped.

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 record scratch freeze to input.mp4
   Caption: Yep, that's me.
   Subline: You're probably wondering how I got here.
   ```

## 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 record scratch freeze 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                                                         |
| --------------- | ------------------------------------------- | -------------------------------------------------------------------- |
| `CAPTION`       | `Yep, that's me.`                           | The big yellow line.                                                 |
| `SUBLINE`       | `You're probably wondering how I got here.` | The smaller white line under it.                                     |
| `FREEZE_AT`     | `1.5`                                       | Second of the input the picture freezes on.                          |
| `HOLD`          | `2.5`                                       | Seconds the freeze holds.                                            |
| `GRAY`          | `0.25`                                      | Color left in the frozen frame (0 = black and white, 1 = untouched). |
| `CAPTION_COLOR` | `(255, 214, 0)`                             | Color of the big line.                                               |
| `SIZE`          | `0.12`                                      | Caption height as a share of the frame width.                        |
| `Y`             | `0.70`                                      | Center of the caption (0 = top, 1 = bottom).                         |
| `SCRATCH`       | `0.45`                                      | Seconds the scratch sound lasts.                                     |

## Without the skill

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

```
Make a record scratch freeze from input.mp4 (540x960, 30fps, 6 seconds). Play the input normally for the first 1.5 seconds. Then freeze on the input's frame at 1.5 seconds and hold it for 2.5 seconds, with its saturation turned down to 25% (Pillow's ImageEnhance.Color at 0.25). On the frozen frame draw "Yep, that's me." in bold yellow (255, 214, 0) text 65 pixels tall (12% of the frame width) with a 6-pixel black outline, centered across the frame with its center 70% of the way down, and under it "You're probably wondering how I got here." in bold white 27-pixel text with a 3-pixel black outline, centered and wrapped onto two lines no wider than 72% of the frame width. After the hold, play the input on from 1.5 seconds to the end, in full color and with no text, so the output is 8.5 seconds long. For the sound: the input's audio for the first 1.5 seconds, then a 0.45-second record scratch you synthesize with numpy (a sawtooth at 220 Hz plus up to 900 Hz times a speed curve sin(2*pi*t*2/0.45)*exp(-2t), mixed with softened white noise, loudness following the square root of the speed and cut off sharply at the end), then silence for the rest of the 2.5-second hold, then the input's audio from 1.5 seconds on. Draw the text with Python and Pillow (not ffmpeg's drawtext filter), use ffmpeg for the rest, keep the size, frame rate and audio, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `record-scratch-freeze.py` and run:

```
python3 record-scratch-freeze.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Record scratch freeze: a record scratch cuts the sound, the picture freezes, drained almost to gray, under a "Yep, that's me." caption.

Usage: python3 record-scratch-freeze.py input.mp4 output.mp4
The output is 2.5 seconds longer than the input: the freeze is held in, then the clip plays on from where it stopped.
Needs ffmpeg, Pillow and numpy (pip install pillow numpy).
"""
import subprocess
import sys
import tempfile
import wave
from pathlib import Path

import numpy as np
from PIL import Image, ImageDraw, ImageEnhance, ImageFont

CAPTION = "Yep, that's me."
SUBLINE = "You're probably wondering how I got here."
FREEZE_AT = 1.5            # second of the input the picture freezes on
HOLD = 2.5                 # seconds the freeze holds
GRAY = 0.25                # color left in the frozen frame (0 = black and white, 1 = untouched)
CAPTION_COLOR = (255, 214, 0)   # yellow
SIZE = 0.12                # caption height as a share of the frame width
Y = 0.70                   # center of the caption (0 = top, 1 = bottom)
SCRATCH = 0.45             # seconds the scratch sound lasts
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")
RATE = 48000               # sample rate of the scratch sound

def freeze_card(still):
    """The frozen frame drained of most of its color, with the caption and a smaller white line under it, both outlined in black."""
    img = ImageEnhance.Color(still.convert("RGB")).enhance(GRAY)
    w, h = img.size
    draw = ImageDraw.Draw(img)
    big = ImageFont.truetype(FONT_FILE, round(w * SIZE))
    small = ImageFont.truetype(FONT_FILE, round(w * SIZE * 0.42))
    draw.text((w / 2, h * Y), CAPTION, font=big, anchor="mm", fill=CAPTION_COLOR,
              stroke_width=round(big.size * 0.09), stroke_fill="black")
    draw.multiline_text((w / 2, h * Y + big.size * 1.05), wrap(SUBLINE, small, w * 0.72), font=small, anchor="ma",
                        align="center", fill="white", stroke_width=round(small.size * 0.12), stroke_fill="black")
    return img

def wrap(text, font, width):
    """Break text into lines no wider than width."""
    lines, line = [], ""
    for word in text.split():
        trial = f"{line} {word}".strip()
        if font.getlength(trial) <= width or not line:
            line = trial
        else:
            lines.append(line)
            line = word
    return "\n".join(lines + [line])

def scratch_sound(path):
    """A record scratch: a buzzy tone and hiss whose speed swings back and forth twice, like a hand dragging the vinyl, then cut."""
    t = np.arange(round(SCRATCH * RATE)) / RATE
    speed = np.sin(2 * np.pi * (2 / SCRATCH) * t) * np.exp(-t * 2)       # two forward-back strokes, slowing
    phase = np.cumsum(220 + 900 * speed) / RATE
    tone = 2 * (phase % 1) - 1                                            # sawtooth that bends with the speed
    hiss = np.convolve(np.random.default_rng(1).standard_normal(len(t)), np.ones(6) / 6, "same")
    sound = (0.6 * tone + 0.5 * hiss) * np.abs(speed) ** 0.5 * np.minimum(1, (SCRATCH - t) * 40)
    with wave.open(path, "wb") as f:
        f.setnchannels(1)
        f.setsampwidth(2)
        f.setframerate(RATE)
        f.writeframes((np.clip(sound, -1, 1) * 0.8 * 32767).astype(np.int16).tobytes())

src, out = sys.argv[1:3]
with tempfile.TemporaryDirectory() as tmp:
    still_png, card_png, scratch_wav = (str(Path(tmp) / n) for n in ("still.png", "card.png", "scratch.wav"))
    subprocess.run(["ffmpeg", "-y", "-v", "error", "-i", src, "-vf", f"select=gte(t\\,{FREEZE_AT}),setpts=N/TB",
                    "-frames:v", "1", still_png], check=True)
    freeze_card(Image.open(still_png)).save(card_png)
    scratch_sound(scratch_wav)
    graph = (f"[0:v]fps=30,split[v0][v1];[v0]trim=end={FREEZE_AT},setpts=PTS-STARTPTS[before];"
             f"[v1]trim=start={FREEZE_AT},setpts=PTS-STARTPTS[after];"
             f"[1:v]fps=30,format=yuv420p,setsar=1[hold];"
             f"[0:a]asplit[a0][a1];[a0]atrim=end={FREEZE_AT},asetpts=PTS-STARTPTS[sbefore];"
             f"[a1]atrim=start={FREEZE_AT},asetpts=PTS-STARTPTS[safter];"
             f"[2:a]apad=whole_dur={HOLD}[shold];"
             f"[before][sbefore][hold][shold][after][safter]concat=n=3:v=1:a=1[joined][a];[joined]format=yuv420p[v]")
    subprocess.run(["ffmpeg", "-y", "-v", "error", "-i", src, "-loop", "1", "-t", str(HOLD), "-i", card_png,
                    "-i", scratch_wav, "-filter_complex", graph, "-map", "[v]", "-map", "[a]",
                    "-c:v", "libx264", "-crf", "18", "-c:a", "aac", out], check=True)
```

## More hook openers

- [Blur-to-focus reveal **Blur-to-focus reveal**](https://www.recharm.com/effects/blur-to-focus-reveal)
- [Breaking news banner **Breaking news banner**](https://www.recharm.com/effects/breaking-news-banner)
- [Camera shake **Camera shake**](https://www.recharm.com/effects/camera-shake)
- [Color reveal **Color reveal**](https://www.recharm.com/effects/color-reveal)
- [Countdown intro **Countdown intro**](https://www.recharm.com/effects/countdown-intro)

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