# Збірка ffmpeg з підтримкою AAC+ засобами FDK AAC

В рамках сетапу ретрансляції радіо "Культура" на радіо Pidpilne, був приємно здивований високою якістю звуку AAC+ при низьких бітрейтах (до 16) і вирішив поряд з онлайн-ретрансляціями ще й додати у цьому форматі дампи деяких подкастів з Youtube.

Але виявилось, що просто перекодувати потік з yt-dlp засобами ffmpeg з репозиторіїв Fedora не вийде, через ліцензійні обмеження GNU/GPL. Довелось зібрати ffmpeg з сорсу - код потрібних кодеків є відкритим, хоч і не вільним для поширення:

> License: nonfree and unredistributable

## Системні залежності

``` bash
sudo dnf remove ffmpeg
sudo dnf install fdk-aac-devel \
                 freetype-devel \
                 lame-devel \
                 libass-devel \
                 libvorbis-devel \
                 libvpx-devel \
                 openssl-devel \
                 opus-devel \
                 SDL2-devel \
                 x264-devel \
                 x265-devel
```
* для сабжу треба тільки `fdk-aac-devel` (або `fdk-aac-free-devel`)
* для кодування x264 та x265, ще може знадобитись пакунок `nasm`

Якщо потрібних пакетів не знайдено:

``` bash
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
```

Переконайтесь, що бібліотека `fdk-aac` розпізнається системою:

``` bash
$ pkg-config --modversion fdk-aac
2.0.3
```

### fdk-aac

> В мене варіант з сорсу не спрацював (ймовірно) через не правильну лінковку, тому згодом я встановив `fdk-aac-devel`, а даний приклад компіляції - просто лишаю для нотатки як є, може згодиться потім.

Опціонально, останню версію fdk-aac можна зібрати з початкового коду:

``` bash
git clone https://github.com/mstorsjo/fdk-aac.git
cd fdk-aac
./autogen.sh
./configure
make -j$(nproc)
sudo make install
```
* для видалення: `sudo make uninstall`

## ffmpeg

``` bash
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
./configure --enable-gpl \
            --enable-libass \
            --enable-libfdk-aac \
            --enable-libfreetype \
            --enable-libmp3lame \
            --enable-libopus \
            --enable-libvorbis \
            --enable-libvpx \
            --enable-libx264 \
            --enable-libx265 \
            --enable-nonfree \
            --enable-openssl
make -j$(nproc)
sudo make install
```
* для сабжу треба тільки `--enable-libfdk-aac`
* для видалення: `sudo make uninstall`

Якщо для роботи із зовнішніми програмами (yt-dlp, firefox) збірка виконується з конфігурацією `--enable-shared`, на Fedora додатково:

``` bash
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/ffmpeg-local.conf
/usr/local/lib
sudo ldconfig
```

## Тестування

``` bash
$ ffmpeg -encoders | grep fdk
A....D libfdk_aac           Fraunhofer FDK AAC (codec aac)

$ ffmpeg -hide_banner -h encoder=libfdk_aac
Encoder libfdk_aac [Fraunhofer FDK AAC]:
    General capabilities: dr1 delay small
    Threading capabilities: none
    Supported sample rates: 96000 88200 64000 48000 44100 32000 24000 22050 16000 12000 11025 8000
    Supported sample formats: s16
    Supported channel layouts: mono stereo 3.0 4.0 5.0 5.1 6.1(back) 7.1(wide) 7.1 5.1.2(back)
...
```

## Перекодування

Нижче - мої приклади з низькими бітрейтами та максимальною компактністю для "голосу".

### Моно (HE-AAC v1)

``` bash
ffmpeg -i input.wav -c:a libfdk_aac -profile:a aac_he -b:a 16k -ar 22050 output.m4a
```

### Стерео (HE-AAC v2)

``` bash
ffmpeg -i input.wav -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k -ar 22050 output.m4a
```

### Перевірка

На прикладі результату для "Стерео (HE-AAC v2)":

``` bash
$ ffprobe output.m4a
...
Audio: aac (HE-AACv2) (mp4a / 0x6134706D), 22050 Hz, stereo, fltp, 32 kb/s (default)
...
```

### yt-dlp

Довідка: на "вході" та "виході" використовується контейнер .m4a - він потрібен для збереження мета-інформації про відео:

``` bash
yt-dlp -x --audio-format m4a \
          --postprocessor-args "ffmpeg: -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k -ar 22050" \
          URL
```
* URL - ваше значення

Згодом, відмовився від варіанту вище, бо `yt-dlp` напихає своїх прихованих аргументів, через що при якості 16k звіт `ffprobe` показує ~50к. Розбиратись мені з цим стало не цікаво, тому замінив `--postprocessor-args` на `--exec` - це працює надійніше "інтеграцій" бо пускається окремим кроком, після отримання оригіналу:

``` bash
yt-dlp -x -o "%(title)s [%(id)s].%(ext)s" \
       --exec 'f={}; ffmpeg -i "$f" -c:a libfdk_aac -profile:a aac_he -b:a 16k -ar 16000 -ac 1 "${f%.*}.m4a" && rm "$f"' \
       URL
```
* у цьому прикладі не вказується `--audio-format`, оригінал як правило зберігатиметься в `.webm`; інакше буде додатковий крок перекодування

### Firefox

Тут в мене своя запара на базі допотопного ESR 115. Поки не вирішив але напрямок такий:

``` bash
$ LD_DEBUG=libs MOZ_LOG="FFmpeg:5" firefox
```

Це поки не допомогло:

* media.rdd-ffmpeg.enabled = false
* media.rdd-process.enabled = false
* media.rdd-ffvpx.enabled = false
* media.ffvpx.enabled = false
* security.sandbox.content.level = 0-3

=> https://linux.org.ua/index.php?topic=12377.0

## Посилання

=> https://trac.ffmpeg.org/wiki/Encode/AAC#fdk_aac

### Дивіться також

=> pidpilne.gmi Підпільне: ретрансляція українського мовлення