ImageMagick and FFmpeg: manipulate images and videos like a ninja

ImageMagick (accessible via the command line program convert) is a software suite for converting and editing images. And FFmpeg (aka ffmpeg) is pretty much the same but for videos.

And, oh my God, they’re handy.

I probably use one or other of the tools every week – either at work with mySociety, or personally, converting videos for the media server on my Synology NAS.

For a while, I had a text note on my laptop with a bunch of my most commonly used convert and ffmpeg command line snippets. But open is better (and not to mention, easier to find) so here it is. I’ll update the list over time, as I discover new tricks. If you have any suggestions, tweet them to me!

Resize an image to fit within the specified bounds

convert before.png -resize 500x500 after.png

Concatenate a series of images (before1.png, before2.png…) into an animated gif

convert -delay 100 -loop 0 before*.png after.gif

-delay is specified in 1/100ths of a second, and a -loop value of 0 means loop forever.

Convert one media format into another

ffmpeg -i before.avi after.mp4

The input and output formats are auto-detected from the file extensions.

This command even works with weird formats like WMV and loads of others, even on a Mac:

ffmpeg -i before.wmv -c:v libx264 -c:a libfaac -crf 23 -q:a 100 after.mp4

Because mp4 is a so-called wrapper format, you can choose the specific video and audio codecs via -c:v and -c:a respectively. In this case we’ve asked for H.264 video and AAC audio. -q:a specifies the AAC audio quality, and -crf is the H.264 video quality.

Convert the audio format of a file, leaving video format as-is

Sometimes, you’ll have device (like a TV) that can play the images in a video fine, but can’t play the audio. Or vice-versa.

In cases like this, you can save time by only transcoding the channel that’s causing a problem – leaving the other channel(s) unchanged. For example, to convert a mkv file containing h264 video (or whatever) and some unknown audio format, into an mkv file with the same h264 video channel but AAC audio:

ffmpeg -i before.mkv -c:v copy -c:a libfaac -q:a 100 after.mkv

-c:v copy tells ffmpeg to just use whatever video codec the original file uses, while -c:a libfaac tells it to convert the audio channel into AAC. In this case, we specify a fairly low audio quality using -b:a 128k (-b for bitrate).

Extract the audio from a video

ffmpeg -i before.avi -vn -ab 256 after.mp3

-vn disables video output, and -ab specifies the audio bit rate.

Convert all the FLAC files in the current directory into MP3s

for i in *.flac; do ffmpeg -i "$i" -q:a 0 "${i%.flac}.mp3"; done

-q:a specifies MP3 audio quality, where 0 is a variable bit rate of 220–260 kbit/s. ${i%.flac} is a Bash operator that returns the variable i without the .flac at the end.