The goal of this page is to list results I captured while looking for the VP9 video encoder best settings for converting a gif-like animated drawing based on a png sequence to a video. As gif is a lossless image format, the goal here is not to get the smallest video file, but more the best compromise between the quality (prio 1), the file size (prio 2) and the encoding time (prio 3).
Note The input png sequence images have been captured thanks to the Python Turtle Country Flags 🐍 🐢 from here.
Table of contents
- Quick outcomes without wasting time reading more (TLDR) 😄
- Extra notes
- Visual results
- Detailed results
- Related documentations
- How to use the scripts
- How to update input files
- APNG or WebP instead of vp9 ?
- Wrap up
- Any questions or comments are welcome 🐦
- 🏅 Forget gif format, use instead webm vp9 video format. You may think about using apng or webp image formats but results are not as good as vp9 for both quality and file size.
- 🥇 Best command that is perfect in most cases ✔️:
ffmpeg -framerate my_fps_value -pattern_type glob -i '*.png' -c:v libvpx-vp9 output.webm
- 🥈 Best command for the best quality 🌈 (file size close to 2. but slower encoding in 2-pass):
# ffmpeg vp9 encode lossless speed 0 2-pass
ffmpeg -framerate my_fps_value -y -i '*.png' -pass 1 -c:v libvpx-vp9 -lossless 1 -speed 0 -f webm /dev/null
ffmpeg -framerate my_fps_value -i '*.png' -pass 2 -c:v libvpx-vp9 -lossless 1 -speed 0 output.webm
- 🥉 Best command for the smallest file size 💪 (quality is less good than 2. and 3. but acceptable) :
# ffmpeg vp9 encode quality good speed 0 crf 10
ffmpeg -framerate my_fps_value -pattern_type glob -i '*.png' -c:v libvpx-vp9 -quality good -speed 0 -crf 10 output.webm
Note HTML code for using a video as a gif animation image:
<video autoplay loop muted playsinline title="your alternate text">
<source src="your_file.webm" type="video/webm">
</video>
Note ffmpeg input file syntax: Hereafter examples that may help you using the ffmpeg syntax (ffmpeg related documentation):
export fps=20
ffmpeg -framerate $fps -i your_files_%04d.png output.webm # The printf way
ffmpeg -framerate $fps -pattern_type glob -i '*.png' output.webm # The wildcad way
Note I added this above note because it took me times to understand the ffmpeg syntax and there are still odd things that still does not work on my side like. For instance, you can not do
export myfile="'*.png'"
and use$myfile
instead of*.png
because you will have anNo such file or directory
error message :-(
Note
⚠️ Github does not support video in markdown files, even if it is with the<video>
html tag :-(!!! If you want to better see the differences between the 3 winners, please open the related README.html.
Type | Size | % | Quality | Filename | sec | % |
---|---|---|---|---|---|---|
gif | 2,288,891 | 213% | Perfect | imagemagick_default.gif | 103,5 | 442% |
gif | 816,729 | 12% | Perfect | imagemagick_layers_optimize.gif | 42,9 | 125% |
gif | 931,165 | 27% | Perfect | ezgif_lossy_200pc.gif ezgif online optimizer (lossy 200%) | na | na |
gif | 1,923,835 | 163% | Perfect | gifsicle_o1.gif | 1,1 | -94% |
gif | 1,099,891 | 51% | Perfect | gifsicle_o2.gif | 1,3 | -93% |
gif | 1,058,821 | 45% | Perfect | gifsicle_o3.gif | 1,6 | -92% |
gif | 730,476 | 100% | Perfect | gifsicle_o3_colors_256.gif | 1,8 | -90% |
gif | 1,865,002 | 155% | Bad | ffmpeg_default.gif | 2,3 | -88% |
vp9 | 294,570 | -60% | Good | ffmpeg_default.webm | 19,1 | 100% |
vp9 | 290,069 | -60% | Good | ffmpeg_default_2_pass.webm | 43,1 | 126% |
vp9 | 294,570 | -60% ✔️ |
Good ✔️ |
ffmpeg_vp9_default.webm | 19,1 | 0% |
vp9 | 290,069 | -60% | Good | ffmpeg_vp9_default_2_pass.webm | 43,1 | 126% |
vp9 | 440,770 | -40% | Perfect | ffmpeg_vp9_lossless.webm | 31,7 | 66% |
vp9 | 315,926 | -57% | Perfect | ffmpeg_vp9_lossless_2_pass.webm | 41,9 | 119% |
vp9 | 342,858 | -53% | Perfect | ffmpeg_vp9_lossless_speed_0.webm | 42,2 | 121% |
vp9 | 297,484 | -59% | Perfect 🌈 |
ffmpeg_vp9_lossless_speed_0_2_pass.webm | 55,5 | 191% |
vp9 | 289,051 | -60% | Good | ffmpeg_vp9_quality_good_speed_0.webm | 27,7 | 45% |
vp9 | 286,179 | -61% | Good | ffmpeg_vp9_quality_good_speed_0_2_pass.webm | 60,2 | 215% |
vp9 | 393,069 | -46% | Medium | ffmpeg_vp9_quality_good_speed_5.webm | 14,2 | -26% |
vp9 | 343,217 | -53% | Medium | ffmpeg_vp9_quality_good_speed_5_2_pass.webm | 32,2 | 68% |
vp9 | 289,051 | -60% | Good | ffmpeg_vp9_quality_good_speed_0_cfr_0.webm | 27,8 | 45% |
vp9 | 234,628 | -68% | Good | ffmpeg_vp9_quality_good_speed_0_cfr_0_2_pass.webm | 38,5 | 101% |
vp9 | 180,735 | -75% 💪 |
Medium | ffmpeg_vp9_quality_good_speed_0_cfr_10.webm | 24,3 | 27% |
vp9 | 211,367 | -71% | Medium | ffmpeg_vp9_quality_good_speed_0_cfr_10_2_pass.webm | 37,5 | 96% |
vp9 | 91,638 | -87% | Low | ffmpeg_vp9_quality_good_speed_0_cfr_63.webm | 23,2 | 21% |
vp9 | 85,450 | -88% | Low | ffmpeg_vp9_quality_good_speed_0_cfr_63_2_pass.webm | 32,5 | 70% |
Note All results are in results.ods file.
Few comments
- vp9
-quality best
is not recommended in the vp9 documentation,-quality realtime
is for steaming, here only-quality good
is usefull then. - ffmpeg by default uses vp9 on my linux configuration. If you have a doubt, please add
-c:v libvpx-vp9
. - we may play more with
-speed x
too but not really necessary here as the animation is very simple and short. Moreover, gif images are lossless so better to use-speed 0
to get the best quality. - gifsicle works only on gif file as input.
- ezgif.com online gif optimizer has been evaluated too but results are lower than
gifsicle -O3
.
Warnings
⚠️ ffmpeg gif output is not correct! Maybe I should try the latest ffmpeg version...⚠️ Measured times depend on my hw configuration, your results will differ probably.⚠️ If it works in my case, it does not necessarily mean that it will work in all your cases, even if I sincerely think that my advices remain valid in many cases, anyway, hope it helps 😄.
Video
- ffmpeg: VP9
- VP9 on Google developers: basics, bitrate-modes & vod settings
Gif
- ImageMagick and its
convert
tool: https://imagemagick.org/script/convert.php - ezgif online gif converter: https://ezgif.com/, based on gifsicle & lossygif tools.
- gifsicle gif optimizer tool: https://www.lcdf.org/gifsicle/ and the related gifsicle man page
- lossygif: https://kornel.ski/lossygif
The encode_test.sh script contains all the different commands, that may help you if you are looking for details.
./encode_test.sh -h
./encode_test.sh 2>&1 | tee `date +"%F_%Hh%Mm%Ss"`.log
Simply update the content of the input
directory with your png files.
Note You can also use
-i dirname
parameter to use to preferred directory.
You can update the input.7z
file with the input
directory content thanks to following commands:
rm input.7z
7z a input.7z input
Before selecting vp9, I have considered both apng and webp image formats. But results are clearly not (maybe not yet) as good as vp9 ones for both quality (lossless) and filesize (lossy).
APNG
time gif2apng ${output}/imagemagick_default.gif -o ${output}/gif2apng_default.png
WebP
export t=`echo "1000/$fps" | bc`
time img2webp -loop 0 -d $t ${input}/*.png -o ${output}/img2webp_default.webp
time img2webp -loop 0 -d $t -lossless ${input}/*.png -o ${output}/img2webp_lossless.webp
time img2webp -loop 0 -d $t -min_size ${input}/*.png -o ${output}/img2webp_min_size.webp
time img2webp -loop 0 -d $t -mixed ${input}/*.png -o ${output}/img2webp_mixed.webp
time img2webp -loop 0 -d $t -mixed -m 6 ${input}/*.png -o ${output}/img2webp_mixed_m6.webp
Documentations
- WebP: img2webp
- APNG: gif2apng or ezgif online apng
We may have better results using different vp9 encoder parameters...
If you have any comments or questions, feel free to send me an email at coolcornucopia@outlook.com 📧.
--
Peace
coolcornucopia 😄