Last Thursday, I discussed
youtube-dl, a tool that allows you to
easily download various kinds of media from the web. What happens once you have
that media? Or what happens if you want to do something with media you already
ffmpeg is almost always the answer. It can take nearly any form of audio
or video media and convert it to almost any other form. It can extract clips,
transcode media, rotate it, crop it, downsample, upsample, etc.
is truly omnivorous.
In fact, many media players and/or transcoders that you may know and love are
actually just graphical front-ends for
ffmpeg. Handbrake and Plex
are two examples that spring to mind.
I’ve spoken about
ffmpeg many times in the past, and I’ve often been asked to
write a primer on how to use it. To cover every nook and cranny of
take forever, so instead I’ll just cover a handful of examples I find myself
The easiest way to install
ffmpeg is to use Homebrew:
brew install ffmpeg
There are some nuances to installation if you want support for certain sub-sets of functionality, but the above will at least get you started.
Let’s say you downloaded a file using
youtube-dl and it ended up in a format
you didn’t expect:
The resulting file is of type
.mkv; let’s say the full filename is
input.mkv just to make things easier. MKV files are not a format that
Apple OSes tends to like. Let’s suppose you want to convert that into something
more Apple-friendly, like a
.mp4. That’s simple to do:
ffmpeg -i input.mkv output.mp4
We’re using the
-i parameter to specify the input file to
ffmpeg, and then
we’re simply specifying the output file. By virtue of the
ffmpeg is smart enough to divine what to do.
Similarly, if we wanted to extract the audio from this video after we’ve already downloaded it, we could do so as such:
ffmpeg -i input.mkv output.mp3
Again, the presence of
.mp3 will tell
ffmpeg all it needs to know.
If you actually watch the video, there’s an intro section and an outro section
that we really don’t need. The intro ends at 46 seconds. We can
ffmpeg to start the output at that point:
ffmpeg -i input.mkv -ss 00:00:46 output.mp3
Here, we’re using the oddly-named
-ss parameter to set the
into the input we wish to seek before we start “recording”, so to speak.
However, we haven’t gotten rid of our outro yet, which lasts for the last six
seconds of the video. We can handle that using the
-to option, which sets when
to stop processing the input file, in the time system of the input file. Since
output.mp3 is 4:34 seconds, then we need to subtract 6 from that, to land on
ffmpeg -i output.mp3 -to 00:04:28 trimmed.mp3
What if we wanted to do both at once? We can use the
-to parameter to set
the end point (again, in terms of the input), in addition to the
-ss to set
the start time. Note, though, we’re using the original file as the input again.
Thus, we have to change the end point for the
-to since we’re starting from
the full file, not the one with the intro clipped. Finally, we land on this
ffmpeg -i input.mkv -ss 00:00:46 -to 00:05:13 trimed.mp3
In one shot, we’ve:
- Stripped the audio
- Transcoded the video
- Trimmed the beginning
- Trimmed the end
Pretty cool stuff, and pretty easy, once you learn to speak
What if you download a different file, but it has bars on the top/bottom or left/right?
In this case, we’d like to remove the small black bars on the left and right sides of the video. We know we need to take off about 10 pixels total; 5 on both the left and right sides. We can do so by using a video filter:
ffmpeg -i input.mp4 -vf "crop=in_w-10:in_h" cropped.mp4
crop parameter to the
-vf (video filter) parameter indicates what the
resolution of the width and then height of the output video should be. We use
in_h macros to indicate the source width and height; then we
10 from the width.
Continuing with the above example, we can make this ever-so-slightly faster. We
know that we want the final file to be in the same format—
the source was. Since we’re not doing any sort of modifications to the audio, we
ffmpeg to copy the audio codec:
ffmpeg -i input.mp4 -vf "crop=in_w-10" -acodec copy cropped.mp4
Since the audio is far easier to process than the video, this isn’t the best
example, as the time savings are marginal. However, in some cases, you may be
able to get away with copying the video codec using
-vcodec copy. In those
cases, that is a big time savings.
It’s beyond the scope of this article, but a nice way to figure out if you can
-vcodec copy is to run a command with no output:
ffmpeg -i input.mp4
That will tell you what the video and audio streams are:
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 819 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc (default) Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
In our case, we know that the video is
h264, which means that we can
-vcodec copy is possible if we’re converting to
Variable Bit Rates
Related to codecs, when left to its own devices,
ffmpeg will encode
a constant 128kbps. That’s sufficient, but I prefer to use a variable bit rate.
To do so, we use a less intuitive incantation:
ffmpeg -i input.mkv -codec:a libmp3lame -qscale:a 2 output.mp3
This is… completely bonkers. Ridiculous incantations like these—if not the
ones that preceded it—are why
ffmpeg gets a bad name. However, the sheer
ffmpeg makes it an indispensible tool that I can’t imagine living
I’ve set up a folder in the Apple Notes app with a series of “recipes” for
As I find a new task I want to accomplish, I determine what the recipe is, and then
write it down as a new note in that folder. You may find the same tactic is useful
for you. Regardless, most of that “recipe book” has been recreated above.
I know the command line is scary, but
ffmpeg is worth getting over it. Everything
you do in
ffmpeg is non-destructive, so the only harm in playing around is
wasting time and listening to your computer’s fans scream. At first I never did
anything more than transcoding using ffmpeg, but over time, I’ve gotten to be
pretty confident with it.