---
title: "How to add a snow with Claude (tested prompt and script)"
description: "Round white snowflakes drift down in from the top edge and keep falling past the product, the big close ones dropping faster than the small far ones as they sway side to side. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/snow
---

# How to add a snow with Claude

Round white snowflakes drift down in from the top edge and keep falling past the product, the big close ones dropping faster than the small far ones as they sway side to side.

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 snow to input.mp4
   Second the first flakes appear at the top edge: 0.3
   Number of flakes: 230
   ```

## 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 snow 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.3`          | Second the first flakes appear at the top edge.                             |
| `COUNT`   | `230`          | Number of flakes.                                                           |
| `RADIUS`  | `(2.0, 7.5)`   | Radius of the farthest and nearest flakes, in pixels.                       |
| `SPEED`   | `(0.14, 0.42)` | Fall speed of the farthest and nearest flakes, in frame heights per second. |
| `OPACITY` | `(0.6, 1.0)`   | How solid the farthest and nearest flakes are.                              |
| `SHADE`   | `0.18`         | Strength of the soft shadow round each flake.                               |
| `SWAY`    | `12`           | Side-to-side drift, in pixels.                                              |

## Without the skill

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

```
Add falling snow to input.mp4. Use 230 round white (255, 255, 255) flakes, each given a random depth: far flakes have a 2 pixel radius, 60% opacity and fall at 0.14 frame heights per second, near flakes a 7.5 pixel radius, full opacity and 0.42 frame heights per second, with most flakes far away. Give each flake a solid middle with a soft edge and a faint soft shadow (18% darker at most, about 1.5 times the flake's radius) so it shows on a light background, and sway it side to side by 12 pixels over 2.5 to 5 seconds. Nothing shows before 0.3 seconds; then the flakes fall in from above the top edge (spread over one frame height above it, so the bottom of the frame only fills in after about 2 seconds), and each one wraps back to the top once it passes the bottom, so it keeps snowing to the end. Use Python with numpy to draw it and ffmpeg to put it on the video (don't rely on ffmpeg's drawtext filter), keep the audio, and save it as output.mp4.
```

## Run it without Claude

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

```
python3 snow.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Snow: soft white snowflakes drift down from the top of the frame, big near ones falling fast and small far ones slowly.

Usage: python3 snow.py input.mp4 output.mp4
Needs ffmpeg and numpy (pip install numpy).
"""
import json
import subprocess
import sys

import numpy as np

START = 0.3              # second the first flakes appear at the top edge
COUNT = 230              # number of flakes
RADIUS = (2.0, 7.5)      # radius of the farthest and nearest flakes, in pixels
SPEED = (0.14, 0.42)     # fall speed of the farthest and nearest flakes, in frame heights per second
OPACITY = (0.6, 1.0)     # how solid the farthest and nearest flakes are
SHADE = 0.18             # faint soft shadow round each flake, so it stands out on light backgrounds
SWAY = 12                # side-to-side drift, in pixels
SEED = 7                 # change for a different arrangement

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 snow(t):
    """How much white covers each pixel at time t, and how much its shadow darkens it (both 0-1), or None before the snow starts."""
    if t < START:
        return None
    white, shade = np.zeros((h, w), np.float32), np.zeros((h, w), np.float32)
    span = h + 2 * MARGIN
    for f in flakes:
        fallen = f["y"] + f["speed"] * h * (t - START)  # starts above the frame, so the snow falls in from the top
        if fallen < -MARGIN:
            continue
        y = (fallen + MARGIN) % span - MARGIN  # wraps back to the top once it passes the bottom
        x = (f["x"] + SWAY * np.sin(2 * np.pi * t / f["sway"] + f["phase"])) % w
        r = int(f["radius"] * 2.2) + 1
        x0, y0, x1, y1 = max(int(x) - r, 0), max(int(y) - r, 0), min(int(x) + r + 1, w), min(int(y) + r + 1, h)
        if x0 >= x1 or y0 >= y1:
            continue
        yy, xx = np.mgrid[y0:y1, x0:x1].astype(np.float32)
        d = np.sqrt((xx - x) ** 2 + (yy - y) ** 2) / f["radius"]
        flake = np.clip(1.6 - d, 0, 1) ** 1.5  # solid middle with a soft edge
        shadow = np.exp(-(d / 1.5) ** 2)       # a soft shadow a little wider than the flake
        white[y0:y1, x0:x1] = np.maximum(white[y0:y1, x0:x1], f["opacity"] * flake)
        shade[y0:y1, x0:x1] = np.maximum(shade[y0:y1, x0:x1], SHADE * f["opacity"] * shadow)
    return white[..., None], shade[..., None]

src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
MARGIN = RADIUS[1] * 3
rng = np.random.default_rng(SEED)
flakes = []
for _ in range(COUNT):
    depth = rng.uniform() ** 1.6  # 0 = far, 1 = near; most flakes are far away
    flakes.append({"x": rng.uniform(0, w),
                   "y": -MARGIN - rng.uniform(0, h + 2 * MARGIN),  # spread over one screen's height above the frame
                   "speed": SPEED[0] + (SPEED[1] - SPEED[0]) * depth * rng.uniform(0.85, 1.15),
                   "radius": RADIUS[0] + (RADIUS[1] - RADIUS[0]) * depth,
                   "opacity": OPACITY[0] + (OPACITY[1] - OPACITY[0]) * depth,
                   "sway": rng.uniform(2.5, 5), "phase": rng.uniform(0, 2 * np.pi)})

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)
    flakes_now = snow(i / fps)
    if flakes_now is not None:
        white, shade = flakes_now
        img = (img * (1 - shade) * (1 - white) + 255 * white).astype(np.uint8)  # shade a little, then mix toward white
    writer.stdin.write(img.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)
