Дисклеймер
-
Методы используемые в этой статье сжимают медиа файлы с большой потерей качества. Прежде чем удалить исходные файлы убедитесь, что сжатые вас удовлетворяют.
-
В статье могут присутствовать неточности.
-
Статья не покрывает все параметры и тонкости использования
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_at
≥libfdk_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
Источники
Автор: KDmasterLOL