Skip to content

Instantly share code, notes, and snippets.

@hathibelagal-dev
Created December 30, 2025 04:01
Show Gist options
  • Select an option

  • Save hathibelagal-dev/65fdbdd84cfafbba2845ce9d3a9b6483 to your computer and use it in GitHub Desktop.

Select an option

Save hathibelagal-dev/65fdbdd84cfafbba2845ce9d3a9b6483 to your computer and use it in GitHub Desktop.
Camera shake using FFMPEG
ffmpeg -i input.mp4 -vf "
crop=iw-24:ih-24:
12+12*(random(1)-0.5):
12+12*(random(2)-0.5),
scale=iw:ih" output.mp4
@hathibelagal-dev
Copy link
Author

In that “realistic default” command, amplitude is controlled by just one number.

Here’s the command again, annotated:

ffmpeg -i input.mp4 -vf "
crop=iw-24:ih-24:
12+12*(random(1)-0.5):
12+12*(random(2)-0.5),
scale=iw:ih" output.mp4

The one number that matters

This part appears twice (X and Y):

12*(random(...) - 0.5)

👉 That 12 is the shake amplitude (in pixels)

  • It defines how far the frame can move from center

  • Actual motion range is roughly:

    ± (amplitude / 2) pixels
    

How to change the shake strength

🔹 Subtle, barely noticeable (tripod-like handheld)

6*(random(1)-0.5)

Full command:

crop=iw-24:ih-24:
12+6*(random(1)-0.5):
12+6*(random(2)-0.5)

🔹 Natural handheld (phone / DSLR)

12*(random(1)-0.5)

(this is your current setting)


🔹 Strong handheld / action cam

24*(random(1)-0.5)

🔹 Violent shake (impact, chaos)

48*(random(1)-0.5)

⚠️ At this point, you must increase the crop margin (next section).


Important: match crop margin to amplitude

You also need enough padding so the frame doesn’t hit edges.

Rule of thumb

crop margin ≥ amplitude

So if you use:

24*(random()-0.5)

Then change:

crop=iw-48:ih-48

Example (strong shake, safe margins)

ffmpeg -i input.mp4 -vf "
crop=iw-48:ih-48:
24+24*(random(1)-0.5):
24+24*(random(2)-0.5),
scale=iw:ih" output.mp4

Cheat sheet

Look | Amplitude | Crop margin -- | -- | -- Ultra subtle | 4–6 | 12–16 Natural handheld | 10–14 | 24 Strong handheld | 20–28 | 48 Impact / chaos | 40–60 | 80–120

Bonus: make shake “heavier” (less jittery)

If you want weight instead of jitter, lower randomness per second:

random(floor(t*10))

instead of:

random(1)

Example:

12*(random(floor(t*10))-0.5)

This updates shake ~10 times per second, which feels more like a real camera.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment