47

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?

3
  • try magick out.gif -fuzz 30% -layers Optimize result.gif
    – Foad
    Apr 25, 2020 at 11:52
  • Why not use webp instead of gif. Webp can use more colores than gif and produces an animaed imagesequence with much lower size. Apr 19, 2021 at 0:05
  • "Why not use webp instead?" Because support for webp is still exceedingly spotty. Mar 1 at 8:24

6 Answers 6

26

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.

3
  • 13
    Weirdly, generating a palette tripled the size of the GIF, although it greatly increased the quality over the default palette. I found the best way is to generate the GIF with ffmpeg as per usual (possibly with a better palette as in this answer) then just run it through an optimization tool (there's ones online too) that can make unchanging parts of the frame transparent or apply other optimizations.
    – Jason C
    Oct 27, 2016 at 16:48
  • 23
    TFW 5 years later, you've got a question, you find a useful answer, you read a helpful comment and think "ah yeah; I noticed that, too", and then you realize that comment was yours. 😅
    – Jason C
    Dec 15, 2021 at 18:50
  • 1
    Generating a palette worked really well for me for a screen capture: reduced the size by 25%. Then running through gifsicle reduced it again, with an overall reduction of 70%.
    – z0r
    Apr 9, 2022 at 5:30
25

Below command helped me optimising my gif's. The parameters can change based on your specific requirements.

ffmpeg -y -i input.mp4 -filter_complex "fps=5,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=32[p];[s1][p]paletteuse=dither=bayer" output.gif

Note:

  • here scale and max_colors drastically impacts the output gif's filesize.

  • If you set a low values for scale and max_colors, setting up dither to bayer makes the output gif look a little better. Default value for dither is sierra2_4a

1
  • This is the one that finally worked for me. Thanks so much :) Mar 17, 2023 at 6:23
11

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.

1
  • 3
    you can just -filter_complex "paletteuse,scale=iw*.2:ih*.2" instead of -vf Dec 25, 2020 at 13:02
6
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

3
  • Where is $palette being set in your script?
    – confetti
    Aug 15, 2018 at 8:47
  • where the command is run
    – abc
    Aug 15, 2018 at 9:08
  • 1
    sorry . there was a mistake with palette file . fixed now .
    – abc
    Aug 27, 2018 at 11:45
1

What worked for me was specifying a lower frame rate than the 10 you're using (-r 10) for the output gif. Probably not what you want if you're after good quality. If you're after a better quality gif then it will be bigger in file size.

1

As a comment to ubershmekel response, ezgif.com indicates that for their compression:

GIF compressor optimizes GIFs using Gifsicle and Lossy GIF encoder, which implements lossy LZW compression.

I obtained similar sizes as with the ezgif "Lossy GIF compression" just doing

./gifsicle -O3 --lossy=35 -o lossy-compressed.gif input.gif
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .