Transcoding video using FFmpeg
Here I will show you some of the possibilities I use a lot when transcoding video using FFmpeg.
In this post, I will not go over the working of the command line interface. I assume you already have basic knowledge before reading this post.
One of the things I hate about movies are the black bands that they usually place at the top and bottom of the files so they will fill your screens properly. So let’s delete them.
To do so, run the following command:
ffmpeg -ss 00:23:00 -i infile.mkv -frames:v 1 "myMovieTitle.jpg"
This line will tell FFmpeg to open our video file, grab 1 (one) frame and save it as myMovieTitle.jpg. This will give us the opportunity to figure out how big the black bands are so we can tell FFmpeg to delete them.
With that done, open up your single frame in Preview (or whichever image editor you prefer).
The bands are very visible here so zoom in enough and using the select tool, we can determine just how much band we have. The first thing we want to measure is the top band. In this case we will only need the height of the top band and the height of the video itself. In my example, the height of the top band is 132px and the height of the video is 816px. Write these down somewhere as we will need them in the future command.
With the measuring done let’s take a look at the command we will be using. I will first show the command as a whole and then I will go over every option so you fully understand what it is that you’re doing.
ffmpeg -i infile.mkv \ -c:v libx265 -preset medium -crf 21 -pix_fmt yuv420p10le -tag:v hvc1 \ -filter:v "crop=1920:816:0:132" \ -s:a 48k -ab 512k -acodec ac3 -ac 6 \ outFile.m4v
I assume this will look like quite a lot of gibberish if you have never used FFmpeg before but it’s actually quite easy.
The first line says:
ffmpeg -i infile.mkv \
Which just tells FFmpeg that we want our input file to be ‘infile.mkv’.
The following line will determine most of our video settings:
-c:v libx265 -preset medium -crf 21 -pix_fmt yuv420p10le -tag:v hvc1 \
with ‘-c:v libx265’ we tell FFmpeg that we want to convert our video into a H265 (HEVC) file. Do note that for these to work you will need a Mac running MacOS High Sierra or an iOS device running iOS11.
Next in line we find ‘-preset medium’. The preset can range from UltraFast to Placebo. Know that UltraFast is very fast encoding but requires a very high bitrate to maintain quality where Placebo encodes extremely slow but provides the best quality. In this example I’m going to use medium which is somewhere in between.
‘-crf 21’ tells us about the quality we want to encode with. CRF stands for Constant Rate Factor and has a range from 0 (lossless) to 51 (worst). What this does is instead of assigning a constant bitrate to your video we assign a constant quality. This will allow faster scenes to have a smaller bitrate and static scenes to have a higher bitrate just like our eyes work in real life. Usually the CRF is set to 24 but I prefer a higher quality so I will be using 21.
‘-pix_fmt yuv420p10le’ will handle the Chroma Subsampling. This is a very complicated matter. If you’d like to learn more about Chroma Subsampling, visit my other post (link) The only thing you need to know right now is that movies always use 4:2:0 and this has no visual impact. So that’s why in this case we’ll be using 4:2:0. But what does the rest mean? The ‘YUV’ you see in front of the ‘420’ is the color encoding system with Y being luma (black and white) and U and V being chrominance (colour), also explained in my Chroma Subsampling post . The last thing we find in this part of the command is ’10le’. When easily explained this allows us to save 10 bits of colour information per colour channel instead of 8 bits. So instead of 16,777,216 discrete colours, we have room for 1,073,741,824. That’s over a billion!
And last but not least you see ‘-tag:v hvc1’. This will add a tag to the video that will enable Apple devices to play the video. If you forget this tag, It will not play on your Mac or iOS device!
Remember when we where looking at the black bands and the height of the video? This is where we’ll need it!
-filter:v "crop=1920:816:0:132" \
This line will delete those black bands for us. It’s actually very easy. You only need to alter the numbers. To do so, let me explain what each number means.
The first number we find is: 1920, this is the width of your video file.
The second number is: 816, this is the height of the video we measured.
The third number is 0 and is the starting point to crop on the x-axle and as we want to use the whole width of the video we don’t need any cropping here.
The fourth number is 132 and is the starting point to crop on the y-axle. So that’s where the black band at the top ends and the video begins.
Basically what we told here is that out video is 1920px wide, 816px high and starts at 0px on the x-axle and at 132px on the y-axle and that we will not need any of the other information.
That’s it video wise. I know it’s a lot to grasp and I could probably write a post about every single section here (maybe I will) but keep going, we’re almost there!
The next line we encounter is:
-s:a 48k -ab 512k -acodec ac3 -ac 6 \
Where we will define all out audio.
The ’48K ‘ is our sampling. This is the standard rate used by professional digital video equipment so let’s keep it that way.
‘-ab 512k’ is our bitrate. We will allow 512kbps for this audio channel.
Then we will tell FFmpeg that we want to convert the audio into ac3, this will ensure that your Apple devices will be able to play it and the last part ‘-ac 6’ tells us that we have 6-channels.
So this is surround (5.1) audio.
For stereo audio, you can use:
-c:a aac -b:a 320k \
The last line is:
And this is simply our output file.
I hope this is all clear now. So let’s open up a Terminal window and complete our journey!
To make this easy, I can only ask you to place ffmpeg on your desktop, like this.
To access ffmpeg now, the first we’ll type into our terminal window is:
Now you have selected your desktop.
Now we can enter our Terminal command
ffmpeg -i /Users/myName/Movies/infile.mkv \ -c:v libx265 -preset medium -crf 21 -pix_fmt yuv420p10le -tag:v hvc1 \ -filter:v "crop=1920:816:0:132" \ -s:a 48k -ab 512k -acodec ac3 -ac 6 \ outFile.m4v
If you do not know the path to your file, simply drag and drop your file into Terminal and Terminal will fill it in for you.
Now that you have added all the information you can simply press return and watch FFmpeg do it’s magic.
This will take quite some time depending on which Mac you’re doing this on, be patient! For example, on my Mac Pro, a regular movie can take as long as 4 times the play time to be converted. On other devices, this may be less or even more.
That was easy, right? Now enjoy your video!