Converting mp4 to webm with ffmpeg

Sunday, March 19, 2023

I thought I'd share a little snippet I use every now and then.

FFmpeg is a pretty awesome library for dealing with audio and video streams. It can be used for lots of different applications in that space, and there are dozens of projects which use FFmpeg for core parts of their functionality, but the bit that I use the most is the command line interface. Whenever I need to convert some audio or video file between formats, ffmpeg is usually the quickest way to get it done.

FFmpeg's command line has about a billion different flags and options, so the commands can look pretty gnarly. But really they're pretty comprehensible once you learn the basics.

After I published my recent article on generating video with Stable Diffusion, I was looking at my Netlify dashboard for the page, and noticed that the two video files on the page were both about 3 MB in size. This made me remember that I had this snippet floating around in Notion, for converting video files to .webm. WebM is a web-first video format by Google, which has some pretty powerful compression, meaning that you can save a lot of bandwidth by using it instead of other larger formats.

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -n:a output.webm

The details of the command aren't important right now - here's the upshot:

~/src/bloog/site/media master
❯ ll *webm *mp4

-rw-r--r--  1 eric  staff   3.5M Mar  7 16:51 sd-ctte-intro.mp4
-rw-r--r--  1 eric  staff   1.2M Mar  7 16:52 sd-ctte-intro.webm

-rw-r--r--  1 eric  staff   3.5M Mar  7 16:51 sd-time-between-the-notes.mp4
-rw-r--r--  1 eric  staff   1.2M Mar  7 16:53 sd-time-between-the-notes.webm

So with just a quick conversion at the command line, I'm saving almost 2/3rds of the bandwidth on those two files. This also means that the page will load a little bit faster for users, especially on slow connections.

There is a very slight quality difference, but it's pretty hard to see. I've included both versions of the "Close to the Edge intro" video I created here, sacrificing precious megabytes of bandwidth just for you - take a look, and see how much you can tell the difference.

WebM version

mp4 version

To my eye, there is very little difference between the two - I think the mp4 version is slightly sharper than the webm, which seems to have lost a little bit of detail. But for the purpose of quickly sharing something like in my original post, I think that's not too big a deal, and I doubt I would notice if I wasn't really looking hard at both videos.

Alright, so now, let's take a brief look at what exactly that command is doing. It looks hairy, but really, it's a pretty straightforward invocation of ffmpeg. Here's that command again - we'll break each of the different flags onto their own lines to make things a little more readable.

    -i input.mp4
    -c:v libvpx-vp9
    -crf 30
    -b:v 0

So really, we've only got 5 flags to contend with.

  • The first flag, -i, specifies the input file we're working on. FFmpeg will infer the type of the input file for us, so there's no need to specify it.
  • The -c:v flag specifies a codec for video. In this case we're using the libvpx-vp9 codec, which has webm support.
  • The -crf flag is interesting - it's the "Constant Rate Factor". The higher you set this flag, the lower the quality of the output video will be. So if we were really unsatisfied with the resulting webm, this would be the first place to start tweaking.
  • The -n:a flag tells FFmpeg to discard the audio component of the stream. In this specific case this may not have been necessary, since I don't think the original file came with an audio stream. I've used this in the past though to strip audio out of a video file.
  • Lastly, we just specifiy the name of the output file.

While it looks nasty, this is actually a pretty simple command, and really useful. I've used this for a variety of different purposes - optimizing the bandwidth of the videos on this site is one use case. I've also used it to turn screen recordings of bugs or demos of features into small little clips that can be attached to a Slack thread or JIRA ticket for work related stuff.

FFMpeg is a great example of the kind of tool that I love to know. I don't use it every day, or even every month - but whenever I need a quick conversion between video or audio formats, or any kind of manipulation on media files, it's there, waiting on my PATH, ready to do the job.

Like many of the best tools, I don't know half of what ffmpeg is capable of, and probably never will. But that's OK, because just knowing it exists is really all you need. The rest of what you need to know is just a quick Google away.

If you liked this post, sign up for my email list via Substack so you can get notified whenever I publish a new post!