17

Does anyone know if it is possible to encode a video using ffmpeg in reverse? (So the resulting video plays in reverse?)

I think I can by generating images for each frame (so a folder of images labelled 1.jpg, 2.jpg etc), then write a script to change the image names, and then re-encode the ivdeo from these files.

Does anyone know of a quicker way?

This is an FLV video.

Thank you

Community
  • 1
  • 1
bob
  • 293
  • 1
  • 4
  • 10

3 Answers3

19

No, it isn't possible using ffmpeg to encode a video in reverse without dumping it to images and then back again. There are a number of guides available online to show you how to do it, notably:

and

The latter of which follows:

Dump all video frames

$ ffmpeg -i input.mkv -an -qscale 1 %06d.jpg

Dump audio

$ ffmpeg -i input.mkv -vn -ac 2 audio.wav

Reverse audio

$ sox -V audio.wav backwards.wav reverse

Cat video frames in reverse order to FFmpeg as input

$ cat $(ls -r *jpg) | ffmpeg -f image2pipe -vcodec mjpeg -r 25 -i - -i backwards.wav -vcodec libx264 -vpre slow -crf 20 -threads 0 -acodec flac output.mkv

Use mencoder to deinterlace PAL dv and double the frame rate from 25 to 50, then pipe to FFmpeg.

$ mencoder input.dv -of rawvideo -ofps 50 -ovc raw -vf yadif=3,format=i420 -nosound -really-quiet -o - | ffmpeg -vsync 0 -f rawvideo -s 720x576 -r 50 -pix_fmt yuv420p -i - -vcodec libx264 -vpre slow -crf 20 -threads 0 video.mkv
Andrew Stubbs
  • 4,322
  • 3
  • 29
  • 48
  • 8
    Cheers, very helpful. A small change -- using `$(ls -r *jpg)` instead of `$(ls -t *jpg)` is better (for me at least) as the modification times are too coarse to give the correct ordering – simonb Feb 02 '12 at 20:25
  • @ChaitanyaChandurkar: Depends on how powerful the device is, processor architecture and clock speed etc etc – Mark K Cowan May 29 '14 at 13:57
  • 4
    For newer versions of ffmpeg you should replace -vpre slow to -preset slow in the last step. – Ruben Sep 18 '15 at 02:01
  • 3
    This is factually incorrect now. FFMPEG now has a `reverse` filter, as well as an `areverse` filter for audio. – Tynach Apr 09 '16 at 07:08
  • 2
    This method is still better than ffmpeg's reverse filter, which buffers all the frames in RAM, uncompressed. A 1080p video that is 33mb and 2 minutes long uses 10gb ram. – dequis Apr 20 '16 at 12:21
  • Tynach: I suggest you post that as an outright answer; maybe with a note that older versions of ffmpeg can't do that and with dequis' caution (which would mean: use one of the other solutions). For my purposes, your comment here was the best solution, as I used that ffmpeg filter to convert small .swf files that easily fit into memory. – Alex Hall Jul 16 '16 at 02:27
  • The original answer gave me very jerky video until I found @simonb's answer, ls -r solves the problem. – Shi B. Mar 07 '17 at 05:30
  • The `ls` method is not necessary. See http://stackoverflow.com/q/40475480/5726027 – Gyan Mar 07 '17 at 12:43
  • @dequis you don't need 10gb of physical ram if you create a swap file of say 9gb – Mattis Mar 19 '18 at 19:36
11

I've created a script for this based on Andrew Stubbs' answer

https://gist.github.com/hfossli/6003302

Can be used like so

./ffmpeg_sox_reverse.sh -i Desktop/input.dv -o test.mp4
hfossli
  • 22,616
  • 10
  • 116
  • 130
0

New Solution

A much simpler method exists now, simply use the command (adjusting input.mkv and reversed.mkv accordingly):

ffmpeg -i input.mkv -af areverse -vf reverse reversed.mkv

The -af areverse will reverse audio, and -vf reverse will reverse video. The video and audio will be in sync automatically in the output file reversed.mkv, no need to worry about the input frame rate or anything else.

On one video if I only specified the -vf reverse to reverse video (but not audio), the output file didn't play correctly in mkv format but did work if I changed it to mp4 output format (I don't think this use case of reversing video only but not audio is common, but if you do run into this issue you can try changing the output format). On large input videos that exceed the RAM available in your computer, this method may not work and you may need to chop up the input file or use the old solution below.

Old Solution

One issue is the frame rate can vary depending on the video, many answers depend on a specific frame rate (like "-r 25" for 25 frames per second). If the frame rate in the video is different, this will cause the reversed audio and video to go out of sync.

You can of course manually adjust the frame rate each time (you can get the frame rate by running ffmpeg -i video.mkv and look for the number in front of the fps, this is sometimes a decimal number like 23.98). But with some bash code you can easily extract the fps, store it in a variable, and automatically pass it to the programs.

Based on this I've created the following bash script to do that. Simply chmod +x it and run it ./make-reversed-video.sh input.mkv output.mkv. The code is as follows:

#!/bin/bash
#Partially based on https://nhs.io/reverse/, but with some modifications, including automatic extraction of the frame rate.

#Get parameters.
VIDEO_FILE=$1
OUTPUT_FILE=$2
TEMP_FOLDER=$3

echo Using input file: $VIDEO_FILE
echo Using output file: $OUTPUT_FILE

mkdir /tmp/create_reversed_video

#Get frame rate.
FRAME_RATE=$(ffmpeg -i "$VIDEO_FILE" 2>&1 | grep -o -P '[0-9\\. ]+fps' | grep -o -P '[0-9\\.]+')
echo The frame rate is: $FRAME_RATE

#Extract audio from video.
ffmpeg -i "$VIDEO_FILE" -vn -ac 2 /tmp/create_reversed_video/audio.wav

#Reverse the audio.
sox -V /tmp/create_reversed_video/audio.wav /tmp/create_reversed_video/backwards.wav reverse

#Extract each video frame as an image.
ffmpeg -i "$VIDEO_FILE" -an -qscale 1 /tmp/create_reversed_video/%06d.jpg

#Recombine into reversed video.
ls -1 /tmp/create_reversed_video/*.jpg | sort -r | xargs cat | ffmpeg -framerate $FRAME_RATE -f image2pipe -i - -i /tmp/create_reversed_video/backwards.wav "$OUTPUT_FILE"

#Delete temporary files.
rm -rf /tmp/create_reversed_video

I've tested it and it works well on my Ubuntu 18.04 machine on lots of videos (after installing the dependencies like sox). Please let me know if it works on other Linux distributions and versions.

Stan Hatko
  • 101
  • 2