---
title: "How to add a best seller badge with Claude (tested prompt and script)"
description: "A gold laurel-wreath medal reading \"Best Seller\" drops in from above, swings round to a slight tilt with a small bounce and settles to the left of the bottle's neck. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/best-seller-badge
---

# How to add a best seller badge with Claude

A gold laurel-wreath medal reading "Best Seller" drops in from above, swings round to a slight tilt with a small bounce and settles to the left of the bottle's neck.

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 best seller badge to input.mp4
   Top line, bottom line: BEST, SELLER
   ```

## 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 best seller badge 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                                  |
| ----------------------- | ---------------- | --------------------------------------------- |
| `TOP_LINE, BOTTOM_LINE` | `BEST, SELLER`   | The two lines on the medal.                   |
| `START`                 | `0.6`            | Second the badge starts to drop in.           |
| `SETTLE`                | `0.6`            | Seconds it takes to land and settle.          |
| `SIZE`                  | `0.36`           | Badge width as a share of the frame width.    |
| `X, Y`                  | `0.19, 0.36`     | Where the badge settles, 0-1 across and down. |
| `GOLD`                  | `(240, 190, 50)` | Wreath, rim and lettering color.              |
| `NAVY`                  | `(25, 35, 75)`   | Medal center color.                           |
| `TILT`                  | `-8`             | Degrees it rests at.                          |

## Without the skill

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

```
Add a best seller badge to input.mp4. Draw it with Python and Pillow (don't use ffmpeg's drawtext filter), at 3x size and scaled down for smooth edges, 36% of the frame width across: a gold (240, 190, 50) disc 60% of the badge across with a navy (25, 35, 75) center 53% across and a thin gold ring inside it; "BEST" in bold gold letters 12.5% of the badge tall with "SELLER" 7.5% tall under it and three small gold stars above; around the disc a gold laurel wreath, two branches of 10 pairs of pointed leaves on a thin stem rising from the bottom and nearly meeting at the top. At 0.6 seconds it fades in over 0.24 seconds while dropping from a quarter of the frame height above its spot, shrinking from 1.5x and turning from 22 to -8 degrees (clockwise tilt) over 0.6 seconds with a slight overshoot, then it stays still, centered at 19% across and 36% down, beside the bottle. Keep the audio and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `best-seller-badge.py` and run:

```
python3 best-seller-badge.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Best seller badge: a gold laurel-wreath medal reading "BEST SELLER" drops in and settles beside the product.

Usage: python3 best-seller-badge.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

TOP_LINE, BOTTOM_LINE = "BEST", "SELLER"
START = 0.6              # second the badge starts to drop in
SETTLE = 0.6             # seconds it takes to land and settle
SIZE = 0.36              # badge width as a share of the frame width
X, Y = 0.19, 0.36        # where the badge settles (0-1 across and down the frame)
GOLD = (240, 190, 50)    # wreath, rim and lettering color
NAVY = (25, 35, 75)      # medal center color
TILT = -8                # degrees it rests at
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 leaf(draw, cx, cy, angle, length, width, color):
    """A pointed leaf centered on (cx, cy), its long axis along angle (radians)."""
    ux, uy, vx, vy = math.cos(angle), math.sin(angle), -math.sin(angle), math.cos(angle)
    along = [i / 6 - 1 for i in range(13)]                          # tip to tip, -1 .. 1
    outline = [(s, 1) for s in along] + [(s, -1) for s in reversed(along)]
    draw.polygon([(cx + ux * s * length / 2 + vx * side * width / 2 * math.sqrt(1 - s * s),
                   cy + uy * s * length / 2 + vy * side * width / 2 * math.sqrt(1 - s * s)) for s, side in outline],
                 fill=color)

def badge():
    """The medal, drawn at 3x and scaled down for smooth edges."""
    d = round(w * SIZE) * 3
    img = Image.new("RGBA", (d, d))
    draw = ImageDraw.Draw(img)
    c, r = d / 2, d * 0.37                                  # center, and radius of the wreath's stems
    draw.arc([c - r, c - r, c + r, c + r], 100, 240, fill=GOLD, width=d // 90)
    draw.arc([c - r, c - r, c + r, c + r], -60, 80, fill=GOLD, width=d // 90)
    for side in (-1, 1):                                    # two laurel branches rising from the bottom
        for k in range(10):
            a = math.radians(90 - side * (12 + k * 14))     # round the side towards the top
            px, py = c + r * math.cos(a), c + r * math.sin(a)
            rising = a - side * math.pi / 2                 # the stem's direction, heading up
            for lean in (-1, 1):                            # a leaf to the outside and to the inside
                angle = rising + side * lean * 0.55
                length = d * (0.115 - k * 0.003)
                leaf(draw, px + math.cos(angle) * length / 2, py + math.sin(angle) * length / 2,
                     angle, length, d * 0.045, GOLD)
    draw.ellipse([d * 0.20, d * 0.20, d * 0.80, d * 0.80], fill=GOLD)
    draw.ellipse([d * 0.235, d * 0.235, d * 0.765, d * 0.765], fill=NAVY)
    draw.ellipse([d * 0.26, d * 0.26, d * 0.74, d * 0.74], outline=GOLD, width=d // 120)
    draw.text((c, d * 0.45), TOP_LINE, font=ImageFont.truetype(FONT_FILE, round(d * 0.125)), anchor="mm", fill=GOLD)
    draw.text((c, d * 0.575), BOTTOM_LINE, font=ImageFont.truetype(FONT_FILE, round(d * 0.075)), anchor="mm", fill=GOLD)
    for i in (-1, 0, 1):                                    # three small stars above the words
        star(draw, c + i * d * 0.06, d * 0.345 - (i == 0) * d * 0.01, d * 0.023, GOLD)
    return img.resize((d // 3, d // 3), Image.LANCZOS)

def star(draw, cx, cy, r, color):
    pts = [(cx + (r if i % 2 == 0 else r * 0.42) * math.sin(i * math.pi / 5),
            cy - (r if i % 2 == 0 else r * 0.42) * math.cos(i * math.pi / 5)) for i in range(10)]
    draw.polygon(pts, fill=color)

def overlay(t):
    """The badge drops from above, shrinking from 1.5x and turning to TILT, with a small bounce as it lands."""
    img = Image.new("RGBA", (w, h))
    if t < START:
        return img
    p = ease_out_back((t - START) / SETTLE)
    scale = 1.5 - 0.5 * p
    b = full.resize((round(full.width * scale), round(full.height * scale)), Image.LANCZOS)
    b = b.rotate(TILT + 30 * (1 - p), resample=Image.BICUBIC, expand=True)
    alpha = min(1, (t - START) / (SETTLE * 0.4))
    b.putalpha(b.getchannel("A").point(lambda a: round(a * alpha)))
    img.alpha_composite(b, (round(w * X - b.width / 2), round(h * Y - h * 0.25 * (1 - p) - b.height / 2)))
    return img

def ease_out_back(p):
    """0 -> 1 with a small overshoot past 1 before settling."""
    p = min(max(p, 0), 1)
    return 1 + 2.70158 * (p - 1) ** 3 + 1.70158 * (p - 1) ** 2

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)
full = badge()
render(src, out)
```

## More product shots

- [Animated feature callouts **Animated feature callouts**](https://www.recharm.com/effects/animated-feature-callouts)
- [Before/after slider **Before/after slider**](https://www.recharm.com/effects/before-after-slider)
- [Callout arrows and circles **Callout arrows and circles**](https://www.recharm.com/effects/callout-arrows-and-circles)
- [Carousel swipe **Carousel swipe**](https://www.recharm.com/effects/carousel-swipe)
- [Comparison table **Comparison table**](https://www.recharm.com/effects/comparison-table)

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