Дисклеймер

  • Методы используемые в этой статье сжимают медиа файлы с большой потерей качества. Прежде чем удалить исходные файлы убедитесь, что сжатые вас удовлетворяют.

  • В статье могут присутствовать неточности.

  • Статья не покрывает все параметры и тонкости использования ffmpeg, за дополнительной информацией обращайтесь к документации или другим ресурсам.

TL;DR

Для сжатия аудио-файлов лучшим вариантом является использование кодека libopus в режиме vbr on с битовой частотой 48k. Это позволило сжать 22 ГБ аудио до 5 ГБ с приемлемым качеством звука.

ffmpeg -i input.mp3 -c:a libopus -b:a 48k -frame_duration 60 -vbr on output.opus

Введение

В данной статье представлены способы сжатия медиа файлов с целью уменьшения их размера. И используемые методы не являются методами сжатия без потерь, и они находятся на грани "ну в целом не мыло и глаз не режет" или "вроде бас нормальный и не шипит", но потерю качества можно легко заметить или услышать.

Моя мотивация. Со временем у меня собралось огромное количество мемов, видео записей событий и музыки. Которые в сумме занимают более 50 ГБ и мне нужно это хранить и передавать. У меня нет возможности увеличить свое электронное пространство и часто кидаю мемы, которые иногда весят более 10 МБ. И уменьшив размер медиа файлов у меня появится больше свободного места и передаваться эти файлы станут быстрее.

Сведения об ffmpeg

FFmpeg — инструмент для обработки мультимедийных данных, который позволяет кодировать, декодировать, транскодировать, мультиплексировать, демультиплексировать, потоково передавать, фильтровать и проигрывать практически любые аудио- и видео-форматы.

Установка. Если у вас Windows, следуйте инструкциям на страницах Download FFmpeg или Как установить программу FFmpeg в Windows. Иначе загружайте из пакетного менеджера.

Синопсис:

ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

Общие параметры:

  • -i url - Указывает URL входного файла.

  • -y - Перезаписывает выходные файлы без запроса.

  • -n - Не перезаписывает выходные файлы и немедленно завершает работу, если указанный выходной файл уже существует.

  • -c[:stream_specifier] codec или -codec[:stream_specifier] codec - Выбирает кодек (кодировщик при использовании перед выходным файлом или декодер при использовании перед входным файлом) для одного или нескольких потоков. codec — это имя декодера/кодировщика или специальное значение copy (только для выхода), указывающее, что поток не должен быть перекодирован. Для каждого потока применяется последняя соответствующая опция -c.

  • -filter[:stream_specifier] filtergraph - Создает фильтр-граф, указанный в filtergraph, и использует его для фильтрации потока.

Примеры использования:

ffmpeg -i input.mp4 -c:v libx264 -c:a aac output.mkv  # Конвертация MP4 в MKV с использованием кодеков libx264 и aac
ffmpeg -i input.mp4 -q:a 0 -map a output.mp3  # Извлечение аудиодорожки в формате MP3 с высоким качеством
ffmpeg -i input.mp4 -ss 00:01:00 -to 00:02:00 -c copy output.mp4  # Обрезка видео с 1 минуты до 2 минут без перекодирования
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4  # Изменение разрешения видео до 1280x720
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" output.mp4  # Наложение водяного знака на видео в позиции (10,10)

Сжатие аудио

Есть два формата в которые можно перекодировать MP3 для его сжатия, а именно: AAC и OPUS.

Общие параметры аудио кодеков

  • -b - Устанавливает битовую частоту в битах/с.

  • -acodec codec - Устанавливает аудио-кодек. Это псевдоним для -codec:a.

  • -aq q - Устанавливает качество аудио (специфично для кодека, VBR). Это псевдоним для -q:a.

Из MP3 в AAC

Кодировщики:

  • Fraunhofer FDK AAC libfdk_aac

  • audiotoolbox Encoder aac_at (обычно доступен только на MacOS)

  • Native FFmpeg AAC Encoder aac (По умолчанию)

Профили:

  • aac_low (1): Low Complexity AAC (LC) (По умолчанию) - Высокая совместимость, низкое потребление процессорной мощности. Аудио приемлемо звучит с битовой частотой 128k.

  • aac_he (4): High Efficiency AAC (HE-AAC) - Низкая совместимость, высокое потребление процессорной мощности, хорошо звучит на низких битовых частотах. Аудио приемлемо звучит с битовой частотой 64k.

  • aac_he_v2 (28): High Efficiency AAC version 2 (HE-AACv2) - Улучшенная версия HE-AAC, лучшее качество звука на низких битовых частотах. Аудио приемлемо звучит с битовой частотой 32k.

Какой кодек выбрать? Если доступен выбирайте aac_at, иначе libfdk_aac.

  • Для AAC-LC: aac_atlibfdk_aac > (aac).

  • Для HE-AAC неясно, что лучше: aac_at или libfdk_aac.

Какой профиль выбрать? Выбирайте HE-AACv2.

Я выбрал aac_at c профилем HE-AACv2, если вы собираетесь использовать libfdk_aac я думаю у вас не будет большого отличия.

Параметры

  • -q:a - Устанавливает качество для режима переменной битовой частоты (VBR).

  • -profile:a - Устанавливает аудио профиль.

  • -b:a - Устанавливает битовую частоту в битах/с. Если битовая частота не указана явно, она автоматически устанавливается на подходящее значение в зависимости от выбранного профиля. Если включен режим VBR, эта опция игнорируется.

Параметры aac_at

  • -aac_at_mode - Устанавливает режим управления битовой частотой. Возможные значения варьируются от -1 до 3:

    • auto (-1): VBR, если указано глобальное качество; CBR в противном случае (По умолчанию)

    • cbr (0): Постоянная битовая частота

    • abr (1): Средняя битовая частота в долгосрочной перспективе

    • cvbr (2): Ограниченная переменная битовая частота

    • vbr (3): Переменная битовая частота

Параметры libfdk_aac

  • -vbr - Устанавливает режим VBR, от 1 (низшее качество) до 5 (высокое качество). Значение 0 отключает VBR, и включается CBR (постоянная битовая частота). В настоящее время только профиль aac_low поддерживает кодирование VBR.

    • 0: отключить VBR (По умолчанию)

    • 1: 32 кбит/с на канал

    • 2: 40 кбит/с на канал

    • 3: 48-56 кбит/с на канал

    • 4: 64 кбит/с на канал

    • 5: около 80-96 кбит/с на канал

Из MP3 в OPUS

При малых битовых частотах OPUS звучит хорошо только в стерео, в моно звучит хуже чем AAC.

Кодировщик доступен только один libopus. Он не поддерживает кодирование, основанное на качестве.

Параметры

  • -b:a - Устанавливает битовую частоту в битах/с.

  • -vbr - Устанавливает режим VBR. Опция -vbr в FFmpeg имеет следующие допустимые аргументы, с эквивалентными опциями в opusenc в скобках:

    • off (hard-cbr): Использует кодирование с постоянной битовой частотой.

    • on (vbr): Использует кодирование с переменной битовой частотой (по умолчанию).

    • constrained (cvbr): Использует кодирование с ограниченной переменной битовой частотой.

  • -frame_duration - Устанавливает максимальный размер кадра или длительность кадра в миллисекундах. Аргумент должен быть одним из следующих значений: 2.5, 5, 10, 20, 40, 60. Меньшие размеры кадров обеспечивают меньшую задержку, но меньшее качество при заданной битовой частоте. Размеры больше 20 мс интересны только при достаточно низких битовых частотах. Значение по умолчанию — 20 мс.

Пример команд

ffmpeg -i input.mp3 -c:a aac output.m4a # Явное указание кодека aac (aac), который используется по умолчанию
ffmpeg -i input.mp3 -c:a libopus output.m4a # Использование кодека libopus (opus)
ffmpeg -i input.mp3 -c:a libfdk_aac output.m4a # Использование кодека libfdk_aac (aac)
ffmpeg -i input.mp3 -c:a libfdk_aac -profile:a aac_he -b:a 64k output.m4a # Использование профиля AAC HE первой версии
ffmpeg -i input.mp3 -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k output.m4a # Использование профиля AAC HE второй версии
ffmpeg -i input.mp3 -c:a aac_at -profile:a 4 -b:a 64k output.m4a # Использование профиля AAC HE первой версии для кодека aac_at (aac)
ffmpeg -i input.mp3 -c:a aac_at -profile:a 28 -b:a 32k output.m4a # Использование профиля AAC HE второй версии для кодека aac_at (aac)
ffmpeg -i input.mp3 -q:a 10 output.m4a # Указание качества 10 (0-14, 0 - самое высокое качество)
ffmpeg -i input.mp3 -b:a 128k output.m4a # Указание битовой частоты

Таблица сравнения кодеков

Оригинальный файл

Кодек

Битовая частота (Качество)

Режим кодирования

Размер файла (МБ)

Относительный размер (%)

Качество на мой слух

11 - Drop Dead.mp3

mp3

192k

4.333

aac

192k

cbr

1.100

25

Идентично

aac

192k

abr

1.114

25

Идентично

opus

192k

cbr

4.356

100

Идентично

opus

192k

cvbr

4.342

100

Идентично

opus

192k

vbr

4.115

94

Идентично

aac

16k

cbr

0.468

10

Ужасно

aac

16k

abr

0.474

10

Ужасно

aac

16k

cvbr

0.497

11

Плохо

opus

16k

cbr

0.369

8

Плохо

opus

16k

cvbr

0.365

8

Плохо

opus

16k

vbr

0.324

7

Плохо

aac

32k

cbr

0.739

17

Средне

aac

32k

abr

0.746

17

Лучше среднего

aac

32k

cvbr

0.812

18

Похоже на оригинал

opus

32k

cbr

0.730

16

Лучше среднего

opus

32k

cvbr

0.725

16

Похоже на оригинал

opus

32k

vbr

0.663

15

Похоже на оригинал

aac

48k

cbr

1.100

25

Похоже на оригинал

aac

48k

abr

1.114

25

Похоже на оригинал

aac

48k

cvbr

1.194

27

Похоже на оригинал

opus

48k

cbr

1.094

25

Похоже на оригинал

opus

48k

cvbr

1.089

25

Похоже на оригинал

opus

48k

vbr

1.006

23

Похоже на оригинал

aac

0 (117.551k)

vbr

2.671

61

Похоже на оригинал

aac

7 (52.184k)

vbr

1.195

27

Похоже на оригинал

aac

14 (19.059k)

vbr

0.447

10

Хуже среднего

3 - This Is Halloween.mp3

mp3

192k

4.647

aac

192k

cbr

1.180

25

Идентично

aac

192k

abr

1.191

25

Идентично

opus

192k

cbr

4.672

100

Идентично

opus

192k

cvbr

4.669

100

Идентично

opus

192k

vbr

4.396

94

Идентично

aac

16k

cbr

0.502

10

Ужасно

aac

16k

abr

0.505

10

Ужасно

aac

16k

cvbr

0.538

11

Хуже среднего

opus

16k

cbr

0.396

8

Плохо

opus

16k

cvbr

0.392

8

Плохо

opus

16k

vbr

0.336

7

Плохо

aac

32k

cbr

0.793

17

Средне

aac

32k

abr

0.795

17

Лучше среднего

aac

32k

cvbr

0.866

18

Похоже на оригинал

opus

32k

cbr

0.783

16

Лучше среднего

opus

32k

cvbr

0.779

16

Похоже на оригинал

opus

32k

vbr

0.702

15

Похоже на оригинал

aac

48k

cbr

1.180

25

Похоже на оригинал

aac

48k

abr

1.191

25

Похоже на оригинал

aac

48k

cvbr

1.256

27

Похоже на оригинал

opus

48k

cbr

1.174

25

Похоже на оригинал

opus

48k

cvbr

1.170

25

Похоже на оригинал

opus

48k

vbr

1.066

22

Похоже на оригинал

aac

0 (116.671k)

vbr

2.844

61

Похоже на оригинал

aac

7 (50.616k)

vbr

1.244

26

Похоже на оригинал

aac

14 (19.209k)

vbr

0.483

10

Хуже среднего

Заключение

Я решил использовать кодек libopus в режиме vbr on с битовой частотой 48k. И в итоге смог сжать 22 ГБ аудио в 5 ГБ.

Вот какой скрипт я использовал для этой задачи:

#!/opt/homebrew/bin/fish

function user_confirmation -d "Get confirmation from user" -a message
    set -q message[1]
    or set -f message "Do you want to continue?"

    while true
        read -l -P "$message [y/N] " answer

        switch $answer
            case Y y
                return 0
            case '' N n
                return 1
        end
    end
end

set COMPRESSED ./Compressed
set YANDEX_MUSIC ./YandexMusic
set YOUTUBE_MUSIC ./YoutubeMusic

if not test -d $YANDEX_MUSIC
    and not test -d $YOUTUBE_MUSIC
    echo One or all source directories not exist.
    exit 1
end

if not test -d $COMPRESSED
    mkdir $COMPRESSED
end

if user_confirmation "Do you want to reset COMPRESSED directory"
    rm -r $COMPRESSED/*

    read -l -P "Copy (c) or Move (m) from source directories? [C/m] " answer

    switch $answer
        case M m
            mv $YANDEX_MUSIC/* $COMPRESSED/
            mv $YOUTUBE_MUSIC/* $COMPRESSED/
        case '' C c
            cp -a $YANDEX_MUSIC/. $COMPRESSED
            cp -a $YOUTUBE_MUSIC/. $COMPRESSED
        case '*'
            exit 1
    end
    or exit 1
end

set files (find $COMPRESSED -type f -name '*.mp3')

for file in $files
    set new_file (path change-extension '' $file)
    ffmpeg -i "$file" -c:a libopus -b:a 48k -frame_duration 60 -vbr on "$new_file".opus
    and rm "$file"
end

Переписанный нейросетью скрипт для bash (не запускал):

#!/bin/bash

user_confirmation() {
    local message="${1:-Do you want to continue?}"

    while true; do
        read -p "$message [y/N] " answer

        case $answer in
            [Yy]* ) return 0;;
            [Nn]* | "" ) return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

COMPRESSED="./Compressed"
YANDEX_MUSIC="./YandexMusic"
YOUTUBE_MUSIC="./YoutubeMusic"

if [ ! -d "$YANDEX_MUSIC" ] && [ ! -d "$YOUTUBE_MUSIC" ]; then
    echo "One or all source directories do not exist."
    exit 1
fi

if [ ! -d "$COMPRESSED" ]; then
    mkdir "$COMPRESSED"
fi

if user_confirmation "Do you want to reset COMPRESSED directory"; then
    rm -r "$COMPRESSED"/*

    read -p "Copy (c) or Move (m) from source directories? [C/m] " answer

    case $answer in
        [Mm]* )
            mv "$YANDEX_MUSIC"/* "$COMPRESSED"/
            mv "$YOUTUBE_MUSIC"/* "$COMPRESSED"/
            ;;
        [Cc]* | "" )
            cp -a "$YANDEX_MUSIC"/. "$COMPRESSED"
            cp -a "$YOUTUBE_MUSIC"/. "$COMPRESSED"
            ;;
        * )
            exit 1
            ;;
    esac
else
    exit 1
fi

files=$(find "$COMPRESSED" -type f -name '*.mp3')

for file in $files; do
    new_file="${file%.mp3}"
    ffmpeg -i "$file" -c:a libopus -b:a 48k -frame_duration 60 -vbr on "${new_file}.opus"
    if [ $? -eq 0 ]; then
        rm "$file"
    fi
done

Источники

Комментарии (16)


  1. Alinaki
    13.01.2025 20:23

    Пережать mp3 в opus

    Скажи мне, что не понимаешь принципов пережатия, не говоря мне...


    1. MountainGoat
      13.01.2025 20:23

      Нигде и никогда не видел нормальной информации, насколько звук перегнанный из 320к mp3 в opus 64k будет хуже, чем 64k полученные из оригинала. Конечно, приняв за условие что mp3 не битый.

      Напомню, что половина поганости mp3 происходит из-за того, что раньше было распространено множество кодировщиков с просто бракованными алгоритмами. Один независимо от битрейта обрезал все частоты выше 16к Гц, другой вносил столько шумов, что фактически выход всегда был эквивалентен 16кб/с битрейта, независимо от размера файла и т.д.


      1. David_Osipov
        13.01.2025 20:23

        Вопрос не только в "поганых кодировщиках" прошлого, но и в принципиальных различиях в работе психоакустических моделей MP3 и Opus. Насколько "интеллектуальнее" Opus справляется с уже "упрощенным" MP3 потоком? Не усиливает ли повторное квантование артефакты, внесенные MP3? Но это только из того, что знаю и слышал - глубоко не копал на практике.


      1. gfiopl8
        13.01.2025 20:23

        Пережми и послушай сам. Если это музыка и ты не услышишь большую разницу то... возможно ты слушаешь через дешевые колонки из 1995.


      1. Alinaki
        13.01.2025 20:23

        64к будут погано звучать и там и там, тут ты прав. Если это уровень, к которому ты стремишься — не вопрос.


  1. dyadyaSerezha
    13.01.2025 20:23

    Завести 2-3 лишних аккаунта в гугле или мэйл.ру и 50 GB облака в кармане. Зачем так мучить себя пережатиями?


    1. aborouhin
      13.01.2025 20:23

      Тогда уж купить терабайт на Яндекс.Диске по цене чашки кофе в месяц и не мучить себя распределением файлов между разными аккаунтами, если мы про облачные хранилища :)

      P.S. А музыка с битрейтом 64k - это, конечно, для очень непритязательного слуха или для очень плохого устройства воспроизведения...


      1. David_Osipov
        13.01.2025 20:23

        Согласен. Музыку лучше жать (два канала) от 128 до 160k. Всё же 64k - это чисто для речи или моно.


        1. aborouhin
          13.01.2025 20:23

          У меня локальная коллекция вообще неcжата (FLAC'ов терабайта 2 давненько уже любовно собрано), но не буду утверждать, что я прямо такой аудиофил, что реально различу lossless и 320k, да и даже 192k... Просто если можно хранить без сжатия - зачем хранить со сжатием. Ну и, честно говоря, последние годы редко что-то из этой коллекции слушаю, стриминговые сервисы всё же гораздо удобнее...


      1. dyadyaSerezha
        13.01.2025 20:23

        У меня откуда-то 1 ТБ на мэйл.ру и бесплатно. Может, когда-то давно акция была... А насчёт кофе, чел же специально написал - не может. Может, он учитель или терапевт)


        1. jamiederinzi
          13.01.2025 20:23

          1Тб мэйл раздавал за участие в тестировании облака, когда оно только вышло. У меня такое же. И 250 на Яндексе в качестве извинения за то, что авто обновление ЯДиска однажды убило винду.


  1. Wesha
    13.01.2025 20:23

    Откуда-то пахнуло тёплым ламповым 1996-м годом, когда лишний десяток мегабайт неиллюзорно напрягал...


  1. ahabreader
    13.01.2025 20:23

    Вижу 2 хороших варианта:

    1. Всегда оставлять звук в изначальном lossy-формате, не перекодировать.

    2. Не думая выбирать Opus, доверяя графику с их сайта, где он на всех битрейтах не хуже, чем... чем AAC-LC и HE-AACv1, судя по всему. К тому же ffmpeg к libopus даёт хороший интерфейс, а с доступом к лучшему энкодеру AAC от Apple есть сложности (может быть проще не через ffmpeg).

    3. На битрейтах ниже 100kbps выбирать xHE-AAC, если имеется его поддержка и не волнует его огороженность. На графике в предыдущем пункте профиля xHE-AAC точно нет, а на низких битрейтах он лучше Opus'а (на 128kbps Opus и разные AAC примерно равны).

    ---

    aac_low ... Аудио приемлемо звучит с битовой частотой 128k.
    aac_he ... Аудио приемлемо звучит с битовой частотой 64k.
    aac_he_v2 ... Аудио приемлемо звучит с битовой частотой 32k.

    128kbps у AAC-LC оценивается как весьма хорошее качество, а остальные профили этот уровень дают на тех же 128kbps, лишь подтягивая качество на низких "явно непрозрачных" битрейтах и позволяя забраться без ушных кровотечений ещё пониже:

    В случае с HE-AACv1 это можно так объяснить: HE-AACv1 = AAC-LC + Spectral Band Replication, который восстанавливает высокие частоты, а их выкидыванием энкодер занимается на низких битрейтах.

    aac_he (4): High Efficiency AAC (HE-AAC) - Низкая совместимость

    Но есть обратная совместимость с AAC-LC - информация об SBR проигнорируется и файл проиграется как обычный AAC-LC, без высоких частот.

    А HE-AACv2 = AAC-LC + SBR + Parametric Stereo будет играться как моно AAC-LC. Тестовые файлы (первый HE-AACv1, второй HE-AACv2).

    И раз я начал говорить про самый новый профиль: USAC в xHE-AAC не опирается на AAC-LC, обратной совместимости нет.

    Размеры больше 20 мс интересны только при достаточно низких битовых частотах.

    Но почему? Используем Opus не для реального времени => задержка декодирования не важна => выкручиваем на максимум ради качества, не углубляясь в величину выигрыша (5%?.. 1%?..).


    1. MountainGoat
      13.01.2025 20:23

       не углубляясь в величину выигрыша (5%?.. 1%?..).

      А может быть 0.00...01%, при этом есть риск нарваться на декодер, не умеющий нестандартное значение.


  1. iliatee
    13.01.2025 20:23

    Для сжатия материала пользуюсь Shutter Encoder. Под капотом там конечно ffmpeg.

    Из полезного:

    В DaVinci на винде можно выводить только в DNx, который Мак никак не читает. Поэтому дополнительно перегоняю в ProRes, чтобы кому-нибудь отдать.

    Часто приходится перекладывать из контейнера в контейнер, потому что исходники открываются неправильно. Ну и эта программа может выполнять эту функцию.

    Иногда требуется обрезать видео, но не хочется лишний раз перекодировать из 264 в 264. Это ухудшает качество, так что можно обрезать без перекодирования в названной программе.

    Набор функций №1
    Набор функций №1
    Набор функций №2
    Набор функций №2


  1. RolexStrider
    13.01.2025 20:23

    Я для себя нашел опытным путем следующее решение: все что действительно стоящее - в FLAC в "холодном хранилище" на внешнем HDD, а все что "ношу с собой" - в Nextcloud, и тоже в Opus, правда 96k. Ни я, ни один из знакомых разницы с FLAC не слышит (на KOSS Porta Pro). Но это если жать из Lossless. Пережимать MP3 в Opus, да еще и 48k - это... даже не знаю чем и на чем слушать чтобы назвать "приемлемым".