Encoding video files can be a complete drag. Even with the fastest CPUs out on the market, the process can take up to about as long as the video itself (e.g. thirty minutes of encoding for a thirty-minute video). No matter what encoding programs offer you, they are always limited by the power of your chips.
To solve this issue, NVIDIA cards have a nifty little trick that they’ve been using since the release of the GeForce 600 series graphics cards back in 2012 called NVENC. This allows you to use the GPU to encode video streams. Using NVENC, not only can you convert videos more quickly than with a conventional CPU, but you can also stream video through software like Open Broadcaster Software (OBS) while reducing or completely eliminating stutter and lag. Since Linux doesn’t have NVENC by default, you’re going to have to get it working by hand. I explain here how you can do this in distributions that are based on Ubuntu.
First Things First
To get NVIDIA’s NVENC working on Ubuntu, you first need to download the NVIDIA Video Codec software development kit (SDK) from this site. You will need to make an account, but the process is pretty straightforward. You don’t need all the files in the ZIP, so we’re now going to navigate to “Samples/common/inc.” Copy everything you see there to your “/usr/local/include” folder. You need to copy these files so that “ffmpeg” (an encoder frequently found with linux distros) will recognize NVENC and incorporate it.
Configuring Source Code Repositories
The next step will involve recompiling your current version of ffmpeg. This means that you’re going to need the build dependencies for the software, and for that you will have to configure Linux to allow downloading from source code repositories in your software sources.
In Ubuntu, you can navigate to “System Settings -> Software & Updates,” then click “Source code” under “Ubuntu Software.” In Linux Mint (the distribution I’m using because I’m lazy), this can be done by accessing the Update Manager, clicking “Edit,” clicking “Software Sources,” then checking the little box with “Enable source code repositories.” This method may vary depending on your desktop environment and distribution of Linux, so you may need to do a little soul searching to get this done.
Now for the tooth-grinding part of the process!
Since ffmpeg doesn’t build with many of its options automatically enabled (meaning they’re almost all opt-in rather than opt-out), you’ll have to find out how it was built in your system and then build it using the same configuration plus support for NVENC and AAC audio. This is where the headers you copied earlier come in. See, ffmpeg will take a little peek at your files in “/usr/local/include” to find any codecs it doesn’t find in its own pockets.
First, we build dependencies with
sudo apt-get build-dep ffmpeg
Next, we want to download the AAC audio codec with
sudo apt-get install libfdk-aac-dev
Once those things are done, we will need to get the source to ffmpeg’s current version with
sudo apt-get source ffmpeg
And when that’s done, you’re going to have to do a little hunting in your Home folder. Find a folder that starts with “ffmpeg.” It will have the version number right after it separated by a dash. Here’s mine:
Open your terminal in that folder. If you can’t do that, open the terminal and type:
where “<version>” represents the full version number you saw in that folder’s name. In my case, I would type
It will show you the entire configuration of your current ffmpeg installation. You’ll need to copy everything after “configuration:” without the bits below that massive wall of text. In my case, I’m copying this: (Your configuration might be different, so don’t copy what I’m showing you here.)
--prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
Now, paste whatever you got into gedit or some other text editor and add this to the end:
--enable-nonfree --enable-nvenc --enable-libfdk-aac
OK, now all you have to do is type
./configure <that massive wall of text>
where “<that massive wall of text>” represents the massive wall of text you just edited to add support for non-free codecs, NVENC, and AAC audio. This might take a while.
After all that is finished, type
Wait for that to be over with, then type
sudo make install
OK, so how do you know you’ve successfully gotten support for NVENC? It’s time to take ffmpeg out for a spin and encode a video with it.
To do this, you will need a video file to convert. Let’s say that our video is in “/home/miguel/Desktop/test.mkv,” and we want to encode it as “/home/miguel/Desktop/test.mp4.” Here’s how we go about doing that with ffmpeg and its newfound love for NVENC:
time ffmpeg -i /home/miguel/Desktop/test.mkv -acodec copy -vcodec nvenc /home/miguel/Desktop/test.mp4
You should see something like this:
And that’s it! We killed two birds with one stone: you learned how to get NVENC on your Linux system and how to encode a video using ffmpeg’s handy terminal command. If you get stuck somewhere or find a better way of doing this, be sure to leave a comment!