DEV Community

Voor AI
Voor AI

Posted on

How to Reverse a Video With FFmpeg (and Prove the Last Frame Became the First)

Reversing a clip in FFmpeg looks like a one-liner until you ask a sharper question: did the last decoded frame actually become the first frame of the output? Stream copy cannot answer that. A lossy H.264 round-trip can look right while failing a byte-level check. This article shows both a PNG-sequence proof that is exact at the ends, and the everyday reverse filter path with a PSNR sanity check.

If you need a brand-new forward clip instead of reversing someone else's footage, generate one on Grok AI Video Generator on Voor.

Reverse proof contact sheet: source first/last vs reversed first/last

What we are proving

Source clip used in the tests: forward.mp4, 1280×720, 24 fps, 72 frames, 3.000 s.

Pass criteria:

  1. Geometry preserved after reverse.
  2. sha256(source[0]) == sha256(reversed[-1]) on PNG frames.
  3. sha256(source[-1]) == sha256(reversed[0]) on PNG frames.
  4. Filter-based H.264 reverse stays visually close to the PNG-path reverse (PSNR average ≥ 30; we measured ~47).

Method A — PNG sequence (exact ends)

# 1) explode
ffmpeg -i forward.mp4 -fps_mode passthrough f-%04d.png

# 2) rebuild in reverse order (copy/rename into rev/f-0001.png …)
ffmpeg -framerate 24 -i rev/f-%04d.png \
  -c:v libx264 -pix_fmt yuv420p -r 24 reversed.mp4
Enter fullscreen mode Exit fullscreen mode

In Python the same idea is: extract → list(reversed(pngs)) → rebuild. That is what reverse_via_pngs() in the companion module does.

Method B — filter reverse (delivery one-liner)

ffmpeg -i forward.mp4 -vf reverse -an \
  -c:v libx264 -pix_fmt yuv420p reversed_filter.mp4
Enter fullscreen mode Exit fullscreen mode

Notes:

  • reverse is a filter, so -c copy is not an option.
  • Audio is dropped here on purpose (-an). To reverse audio too, add areverse in a filter graph.
  • Re-encoding changes pixels; do not expect SHA equality against the source.

FFmpeg reverse commands used in the article

Minimal helper

def reverse_filter_h264(src, dest, ffmpeg="ffmpeg"):
    subprocess.run(
        [ffmpeg, "-y", "-i", str(src), "-vf", "reverse", "-an",
         "-c:v", "libx264", "-pix_fmt", "yuv420p", str(dest)],
        check=True,
    )
Enter fullscreen mode Exit fullscreen mode

Pytest results (2026-11-06)

....                                                                     [100%]
4 passed in 1.36s
Enter fullscreen mode Exit fullscreen mode

The suite checks geometry, exact PNG end-swap, PSNR between PNG-path and filter-path outputs, and a non-empty delivery file.

When not to reverse

  • Copyrighted music videos you do not have rights to alter.
  • Clips where reversed motion implies a false real-world event.
  • Any case where you actually need a new forward shot — generate one instead of reversing.

Voor alternative

Open Grok AI Video Generator, write a forward brief (or attach a still), and generate a new clip rather than reversing a source you should not republish.

Disclosure

This article was drafted with an autonomous assistant. All FFmpeg commands and pytest checks were run locally on the sample clip before publishing.

Top comments (0)