---
title: "How to add shooting stars with Claude (tested prompt and script)"
description: "The scene dims to a night-blue sky, then white meteors with tapering, blue-glowing tails streak down and to the left across the top of the frame, one after another. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/shooting-stars
---

# How to add shooting stars with Claude

The scene dims to a night-blue sky, then white meteors with tapering, blue-glowing tails streak down and to the left across the top of the frame, one after another.

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 shooting stars to input.mp4
   Meteors: 8 meteors from 0.8s to 4.3s
   ```

## 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 shooting stars 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                                                                              |
| ----------------------- | ----------------------------- | ----------------------------------------------------------------------------------------- |
| `NIGHT`                 | `(8, 12, 40)`                 | Color the picture is darkened toward.                                                     |
| `DARK_TOP, DARK_BOTTOM` | `0.85, 0.45`                  | How dark the sky gets at the top and bottom edges (0 = not at all, 1 = fully night blue). |
| `METEORS`               | `8 meteors from 0.8s to 4.3s` | When each meteor appears and where it starts, as shares across and down the frame.        |
| `FLIGHT`                | `0.9`                         | Seconds each meteor takes to cross.                                                       |
| `ANGLE`                 | `25`                          | Degrees below horizontal the meteors fall at.                                             |
| `CURVE`                 | `0.06`                        | How much the path bends downward. 0 is a straight line.                                   |
| `TAIL`                  | `0.5`                         | Tail length as a share of the path.                                                       |
| `GLOW`                  | `(150, 190, 255)`             | Color of the glow around each streak.                                                     |

## Without the skill

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

```
Add shooting stars to input.mp4. From 0.3s to 0.7s, darken the picture linearly toward night blue (8, 12, 40) with a vertical gradient: 85% of the way there at the top edge, 45% at the bottom edge; it stays dark to the end. Then 8 meteors cross the frame, appearing at 0.8, 1.2, 1.7, 2.2, 2.7, 3.2, 3.7 and 4.3 seconds and starting at (across, down, as shares of the frame) (0.98, 0.06), (0.75, 0.02), (1.05, 0.16), (0.90, 0.12), (0.65, 0.03), (1.02, 0.14), (0.80, 0.08) and (1.00, 0.12). Each takes 0.9 seconds to travel 80% of the frame width heading down and to the left at 25 degrees below horizontal, with an extra drop of 6% of the frame height at the end that grows with the square of the progress, so the path arcs. Draw each with Pillow as a pure white (255, 255, 255) head 8px across and a tail covering the last 50% of the path behind it, tapering from 5px wide and full brightness at the head to 1px and dark at the end, plus a pale blue (150, 190, 255) glow made by blurring the white streaks with a Gaussian radius of 6 and tripling its strength (capped at full). Each meteor fades in over the first 15% of its flight and out over the last 35%. Before 0.3s the video must be unchanged and nothing is drawn. Use Python with numpy and Pillow for the frames and ffmpeg to read and write them (no drawtext), keep the size, 30fps, length and audio, and save it as output.mp4.
```

## Run it without Claude

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

```
python3 shooting-stars.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Shooting stars: the sky darkens to night blue and white meteors with glowing tails arc down across it.

Usage: python3 shooting-stars.py input.mp4 output.mp4
Needs ffmpeg, numpy and Pillow (pip install numpy pillow).
"""
import json
import math
import subprocess
import sys

import numpy as np
from PIL import Image, ImageDraw, ImageFilter

NIGHT = (8, 12, 40)           # color the picture is darkened toward
DARK_TOP, DARK_BOTTOM = 0.85, 0.45  # how far toward NIGHT at the top and bottom edges (0 = not at all, 1 = fully)
DARK_IN = (0.3, 0.7)          # seconds the darkening fades in between
METEORS = [(0.8, 0.98, 0.06), (1.2, 0.75, 0.02), (1.7, 1.05, 0.16),   # (second it appears, start across, start down)
           (2.2, 0.90, 0.12), (2.7, 0.65, 0.03), (3.2, 1.02, 0.14),
           (3.7, 0.80, 0.08), (4.3, 1.00, 0.12)]
FLIGHT = 0.9                  # seconds each meteor takes to cross
TRAVEL = 0.8                  # distance each meteor travels, as a share of the frame width
ANGLE = 25                    # degrees below horizontal, heading down and to the left
CURVE = 0.06                  # extra drop at the end of the path, as a share of the frame height (the arc)
TAIL = 0.5                    # tail length, as a share of the path
WIDTH = 5                     # head width in pixels; the tail tapers to 1
GLOW = (150, 190, 255)        # pale blue glow around each streak

def probe(path):
    info = json.loads(subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
                                               "stream=width,height,r_frame_rate", "-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)

def path_point(x0, y0, s):
    """Where a meteor that starts at (x0, y0) is after s (0-1) of its path: a straight line bending downward."""
    a = math.radians(ANGLE)
    return (w * (x0 - s * TRAVEL * math.cos(a)),
            h * y0 + w * s * TRAVEL * math.sin(a) + h * CURVE * s * s)

def streaks(t):
    """Every meteor in flight at time t, drawn white on black as a grayscale image."""
    img = Image.new("L", (w, h))
    draw = ImageDraw.Draw(img)
    for born, x0, y0 in METEORS:
        p = (t - born) / FLIGHT
        if not 0 < p < 1:
            continue
        fade = min(1, p / 0.15, (1 - p) / 0.35)   # quick fade in, slower fade out
        steps = 40
        for k in range(steps):                    # tail end first, so the brighter head draws on top
            s0 = p - TAIL * (1 - k / steps)
            s1 = p - TAIL * (1 - (k + 1) / steps)
            if s1 <= 0:
                continue
            near = (k + 1) / steps                # 0 at the tail's end, 1 at the head
            draw.line([path_point(x0, y0, max(s0, 0)), path_point(x0, y0, s1)],
                      fill=round(255 * fade * near ** 1.5), width=max(1, round(WIDTH * near)))
        hx, hy = path_point(x0, y0, p)
        r = WIDTH * 0.8
        draw.ellipse([hx - r, hy - r, hx + r, hy + r], fill=round(255 * fade))
    return img

def frame_at(img, t):
    """One frame: darkened toward NIGHT, then the meteors' blue glow and white cores on top."""
    dark = min(max((t - DARK_IN[0]) / (DARK_IN[1] - DARK_IN[0]), 0), 1)
    shade = dark * np.linspace(DARK_TOP, DARK_BOTTOM, h, dtype=np.float32)[:, None, None]
    out = img * (1 - shade) + np.array(NIGHT, np.float32) * shade
    core = streaks(t)
    glow = np.asarray(core.filter(ImageFilter.GaussianBlur(6)), np.float32)[..., None] / 255 * 3
    core = np.asarray(core, np.float32)[..., None] / 255
    out = out + (np.array(GLOW, np.float32) - out) * np.clip(glow, 0, 1)
    out = out + (255 - out) * core
    return out.clip(0, 255).astype(np.uint8)

src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
reader = subprocess.Popen(["ffmpeg", "-v", "error", "-i", src, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
                          stdout=subprocess.PIPE)
writer = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{w}x{h}",
                           "-r", rate, "-i", "-", "-i", src, "-map", "0:v", "-map", "1:a?",
                           "-c:v", "libx264", "-crf", "16", "-pix_fmt", "yuv420p", "-c:a", "copy", "-shortest", out],
                          stdin=subprocess.PIPE)
i = 0
while raw := reader.stdout.read(w * h * 3):
    img = np.frombuffer(raw, np.uint8).reshape(h, w, 3).astype(np.float32)
    writer.stdin.write(frame_at(img, i / fps).tobytes())
    i += 1
writer.stdin.close()
if reader.wait() or writer.wait():
    sys.exit("ffmpeg failed")
```

## More overlays and light

- [Anamorphic streak **Anamorphic streak**](https://www.recharm.com/effects/anamorphic-streak)
- [Aurora **Aurora**](https://www.recharm.com/effects/aurora)
- [Blood splatter **Blood splatter**](https://www.recharm.com/effects/blood-splatter)
- [Bokeh lights **Bokeh lights**](https://www.recharm.com/effects/bokeh-lights)
- [Camera flash **Camera flash**](https://www.recharm.com/effects/camera-flash)

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