I often create digital animations by preparing all the frames in .png format (with minimal compression), that I need to convert to video format for upload to websites such as reddit, instagram, gfycat.

I know very little of all the different standards of compression, and these websites aren't very clear as to what format they accept, but I've found a recipe that usually works for me, and that creates files that get accepted by these websites:

# step 1
mencoder mf://frame*.png -mf w=$WIDTH:h=$HEIGHT:fps=$FPS:type=png \
         -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=16000:keyint=15:mbd=2:trell \
         -oac copy -o step1.avi

# step 2
mencoder step1.avi -o step2.mp4 -of lavf -lavfopts format=mp4 -ovc x264 -sws 9  \
         -x264encopts nocabac:level_idc=30:bframes=0:bitrate=2048:threads=auto:turbo=1:global_header:threads=auto:subq=5:frameref=6:partitions=all:trellis=1:chroma_me:me=umh

However I'm not completely sure what it does*, therefore I'm not able to:

  • make it a single instruction

  • tune the compression rate.

Indeed, I'd often prefer a less compressed result.

What route can I follow to go from PNG frames to a web-friendly video file (that I believe is a H.264/MPEG-4 MP4) that gives me the ability to tune compression?

* for instance: this is an example frame

enter image description here (note: honestly it seems to me that it looks much worse when watching it in VLC than when taking a snapshot through the VLC tool - this makes it very difficult to make the question understandable and the results comparable)

Even if in step 1 I have specified $WIDTH and $HEIGHT to match the ones of the original image, it has apparently changed both, and not preserved the aspect ratio. There is also more blur to the final image, that might be just an effect of such resize.

edit: see the actual system screenshot of the mplayer window below (would be the same with VLC). The tile grouts are very blurred compared to both the PNG source and the VLC "internal" screenshot feature

enter image description here


enter image description here

  • 1
    I'ld prefer to use ffmpeg (see here for instructions). – ridgy Jan 8 '18 at 13:42
  • @ridgy I used ffmpeg -r 24 -f image2 -s ${WIDTH}x$HEIGHT -start_number $FIRSTFRAME -i frame%04d.png -vcodec libx264 -crf 15 -pix_fmt yuv420p output.mp4 and it worked perfectly. Changing -crf has a clear and adjustable effect on the file size and the results are very good within the advised range 15-25 (better than my old recipe). If you answer the question, I'll accept the answer, or I'll answer it myself if you're not doing it today – Nicola Sap Jan 8 '18 at 16:10


As pointed out in the comments, ffmpeg offers a good one-step solution with a simple "quality" parameter: crf, or "constant rate factor" (read this post explaining crf).

See this post for simple instructions for going from PNG to H.264 using ffmpeg.

In short:

# Assuming the frames are called frame0000.png, frame0001.png ...
# $CRF (see above) to the desired value, then run:

ffmpeg -r $FPS -f image2 -s ${WIDTH}x$HEIGHT -start_number $FIRSTFRAME \
       -i frame%04d.png -vcodec libx264 -crf $CRF -pix_fmt yuv420p output.mp4

$CRF is 23 by default; values smaller than 23 give better quality and larger files, values larger than 23 increase the compression.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.