Собственно говоря данный пример в основном относится к -filter_complex (он же -lavfi) но я также рассмотрю более общие вопросы использования ffmpeg. Собственно, все необходимо я разместил на GitHub. Итак, что понадобится:

ПО. Сам ffmpeg, imagemagick (делать прозрачный фон и не только), git (если нет), Linux. Для Debian (Ubuntu)

$ sudo apt install -y ffmpeg imagemagick git

Собственно mp3 файл, лучше с метаданными, скрипт может вытаскивать текст и добавлять его в видео.

Картинка, в принципе для данного примера любое изображение диска.

Поставить mktrans. В README.md инструкция для создания прозрачного фона. Изменить размер картинки можно с помощью convert из imagemagick или самого ffmpeg.

Поставить пример git clone https://github.com/zirf0/music_visual.git.

Теперь заглянем внутрь

flr_show-freq-vol - текст фильтра

music_vision.sh - основной скрипт

valk500tr.png - картинка с диском (у меня 500x500 с прозрачным фоном)

wagner.gif - гифка к этой статье. Тоже создана ffmpeg.

wagner_valkyries.mp3 - "Полет Валькирий" Вагнера

Начинаем разбирать фильтр

" [0:a]showfreqs=s=600x240:mode=line:colors=red|blue,pad=1920:1080:0:x=1000:y=350[vf];

[0:a]showvolume=p=1,scale=1280:40[vv]; [1:v]scale=500:500,rotate=a=0.4*t/2:ow=iw/1:oh=ow[disk];

[vf][disk]overlay=(W-w)-1300:(H-h)/2,scale=1920:1080[l1];

[l1][vv]overlay=x=700:y=800,scale=1920:1080[l2]; [l2]drawtext=fontfile=NimbusRoman-BoldItalic.otf:textfile=metadata.txt: fontcolor=white:fontsize=50:box=1:boxcolor=black@0.5:boxborderw=5:x=(w-text_w)-500:y=(h-text_h)-800, format=yuv420p[fin] "

Это текстовая строка, она вынесена из скрипта для удобства. Итак первая строка [0:a]...[vf] фильтр showfreqs из аудиопотока создает видео [vf] (video frequency - это я так назвал, чтобы понятнее было). Следующая строка работает аналогично, но выход фильтра showvolume обозначен как [vv]. Дальше [1:v]...[disk] применяет фильтр rotate к нашей картинке (да [1:v] видеопоток), вывод обозначен как [disk]. Теперь накладываем на [vf] [disk] с помощью фильтра overlay (координаты заданы двумя способами или x,y или из относительных значений, и так и так можно), вывод обозначен как [l1] (layer 1). Аналогично работает и следующая строка, накладывая [vv] на [l1]. Последняя пара [l2] ..[fin] накладывает текст, который берет из файла metadata.txt.

Перейдем к скрипту, я разберу только значимые строки, остальные затруднений не должны вызвать.

data=$(ffprobe -i $mp3 2>&1 | egrep "artist|title") # get some data from mp3 metadada

#Uncomment len to get real duration

#len=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $mp3 ) #duration of input, sec

len=20 # for test only

В переменную data попадают подстроки из метаданных, они записываются в файл metadata.txt, который был упомянут выше. len это длительность mp3 в секундах, по умолчание основной механизм закомментирован и длина устанавливается в 20 секунд. Кстати метод определение длительности не совсем точный в теории, но работает.

enc="-c:v h264 -crf 23 -preset medium -tune film -b:v 3M -c:a aac -b:a 192k" #executing string

exe=$(echo "ffmpeg -i $mp3 -loop 1 -i $disk -y -lavfi $filter -ss 00:00:00 -to $len $enc -shortest -map '[fin]' -map 0:a $out")

В переменной enc стоят значения по умолчанию для видеокодека H264. Для YouTube можно уточнить тут. В переменной exe командная строка ffmpeg, тут находится и [fin] из фильтра. Важен ключ -loop 1 перед картинкой, понятно почему. Потоки должны всегда быть соединены, то есть каждый выход должен попадать на вход. Зачем столь странная система - сброс переменной в файл и его запуск? По историческим причинам, отлаживать легче.

Теперь самое главное. Вы можете запустить ./music_vision.sh и получить 20 секунд видео. Но прежде, чем создавать видео, ознакомьтесь с нижеследующими материалами:

Журнал "Tester's Life", нужны номера за апрель 2014 и май 2016, там много про ffmpeg русским по белому.

https://github.com/SonicField/sonic-field-video. Море примеров. Например такой вывод.

Много примеров с видео результатов.

Документация ffmpeg.

Google. Рекомендации для видео YouTube.

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


  1. REPISOT
    08.11.2021 06:05

    Я не увидел, какую оконную функцию вы использовали для спектра. Видимо, по-умолчанию. Попробуйте Хемминга (hamming). Пики частот станут более явными.


    1. zirf Автор
      08.11.2021 07:14

      Спасибо, учту, да по умолчанию, то есть win_func=hanning подразумевается.