Reduce Generated GIF Size Using FFMPEG
I'm developing android application that converts mp4
files into gifs
using ffmpeg
.
Problem is that generated gifs are huge in size. And another problem is that I can't use anything else than ffmpeg
(e.g.imagemagick
for convert
, or even palletes
for now) to reduce generated gif size.
this is the command I'm using:
ffmpeg -y -i file.mp4 -pix_fmt rgb24 -r 10 -s 320x480 file.gif
So is there any other way to optimize conversion?
The standard way to use ffmpeg for GIFs is
Generate a palette from the video
ffmpeg -y -i file.mp4 -vf palettegen palette.png
Then,
ffmpeg -y -i file.mp4 -i palette.png -filter_complex paletteuse -r 10 -s 320x480 file.gif
More options documented here.
I tried all these techniques and I ended up using https://ezgif.com
I have no idea what magic they're using under the hood, but their compression level knob, palette optimization and resolution reduction resulted in the highest visual quality and smallest file size.
I tried -vf palettegen
and -filter_complex paletteuse
but that removed the ability to -vf "scale=iw*.2:ih*.2"
in the same run so I had to do that separately. And ffmpeg created larger files for 0.3
scale than 0.5
which is odd. After an hour of fiddling, I tried ezgif and it worked nicely.
vid=
start_time=00:00:01
duration=5
height=ih/2 # input height halved , can replace with pixils .
width=-2 # keeps aspect ratio . can replace with pixils .
fps=25 # frames per a second .
filters="fps=$fps,scale=$width:$height:flags=lanczos"
ffmpeg -ss $start_time \
-t $duration \
-i "$vid" \
-vf "$filters,palettegen" \
-y palette.png &&
ffmpeg -ss $start_time \
-t $duration \
-i "$vid" \
-i palette.png \
-lavfi "$filters [x]; [x][1:v] paletteuse" \
-y "$vid".gif &&
rm palette.png
link to documentation
more info