artemis

art "semaphore" everfree

serotonergic daydream

prismatic swarm

fractal multitudes

evershifting

theta delta ampersand

bi/pan/poly

this user is a furry


Do you talk to the computer as if it could hear you? Does it ever talk back?



breaking the serenity of dawn - [ffmpeg builtin] breaking the serenity of dawn
[ffmpeg builtin] breaking the serenity of dawn
breaking the serenity of dawn
00:00
breaking the serenity of dawn - [libfdk_aac] breaking the serenity of dawn
[libfdk_aac] breaking the serenity of dawn
breaking the serenity of dawn
00:00

ffmpeg's builtin AAC encoder has trouble sometimes with certain audio. libfdk_aac is basically always really good. Compare these two audio files. These are the same bitrate (96k). But listen to all that artifacting on the ffmpeg builtin encoder! (and fsr it thinks the song is longer? idk...). I used 96k to make it easy to hear even if you're not sensitive to this stuff, but it persists surprisingly high up the bitrate!

Not all songs artifact like this through the builtin encoder, but I've had it bite me a bunch and I'd rather just not use it. If you're transcoding for a platform that supports opus, well, just use that instead. But if you're not... here's how you get the cool encoder I used for the second one the easiest way possible.


Here's the command we're ultimately going to want to run to encode stuff:

# replace 128k with whatever bitrate you want
ffmpeg -i input.whatever -c:a libfdk_aac -b:a 128k output.aac

(btw: if you want to learn more about options you can use while encoding your audio files check out this page for some recipes https://trac.ffmpeg.org/wiki/Encode/AAC#fdk_aac )

But if you have ffmpeg installed and you go and try and run this now, it probably won't work, because chances are your version of ffmpeg didn't come with libfdk_aac.

So why isnt libfdk_aac the default encoder? And how come your linux distribution probably doesn't include it? Simple, licensing. The libfdk_aac encoder is open source, but the license terms forbid redistributing binary pre-compiled versions of it. So we have to build it from source ourselves. Sounds like a pain in the ass, right? Yeah, but it's not so bad.

If you're on arch linux, you can go grab ffmpeg-full or ffmpeg-libfdk_aac from the AUR, and you're done.

Similar on on gentoo, you can just set the fdk USE flag on ffmpeg.

Everywhere else... Nix to the rescue!!!! Did you know you can install nix even on a non-NixOS machine? You can! https://nixos.org/download.html has instructions and you need it installed for this method.

But how does Nix help us? Well, Nix isn't just a system for declaring system configurations or whatever nonsense, it's also a build system, and it's one of the easiest to use ones when someone else already wrote the build script for you. I'm taking this technique from Xe Iaso's post, Video Compression for Mere Mortals. What we're gonna do is slightly reconfigure the ffmpeg build to include the fdk AAC encoder the way Xe did there. Then nix will go ahead and build it for us without any extra hassle.

Open up a file ffmpeg_fdk.sh, and put this in it:

#!/usr/bin/env nix-shell
#! nix-shell -i bash -p "with import <nixpkgs> {}; pkgs.ffmpeg-full.overrideAttrs (old: { configureFlags = old.configureFlags ++ [ \"--enable-libfdk_aac\" \"--enable-nonfree\" ]; buildInputs = old.buildInputs ++ [ pkgs.fdk_aac ]; })"
exec ffmpeg "$@"

Save that and make it executable chmod +x ffmpeg_fdk.sh

Now you have a shell script that lets you use the fdk encoder! The first time you run this it will take a while (maybe a long while depending on how fast your computer is) because it will compile ffmpeg from source. But every time after that it will use the version it already compiled. Now you can just run:

./ffmpeg_fdk.sh -i input.whatever -c:a libfdk_aac -b:a 128k output.aac

That simple! :D


You must log in to comment.

in reply to @artemis's post:

I found this last night looking at the ffmpeg tag and realize this had been posted basically the day before I sat down and compiled ffmpeg "the hard way" on a machine for the exact same reason, having found that libfdk_aac was way way way more efficient.

Looking forward to playing around with nix for the occasional edge case like this. Thank you!