ffmpeg: склеиваем два видео-файла в один и исправляем ошибку “width not divisible by 2”

Здоровья и благополучия!

1.mov + 2.mov = output.mp4

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

Итак, самый простой и верный вариант.

Имеется два видео-файлика, 1.mov и 2.mov, мы пытаемся их склеить в output.mp4

Лобовой метод с применением фильтра concat как со списком файликов так и с инжектом в команду не прокатил, возможно, версия моего виндового FFMPEG не подходила, возможно, ещё что. Но нам некогда возиться с апгрейдами, надо всё сделать быстро и в срок.

Итака, гуглим далее по stackoverflow – бездонная кладезь вопросов и ответов по IT-тематике, конечно, я не специально выбираю именно stackoverflow, Google мне туда указывает.

И вот вариант, который у меня прокатил:
1. Преобразуем mov файлы в mpg:

ffmpeg -i 1.mov -qscale 0 1.mpg
ffmpeg -i 2.mov -qscale 0 2.mpg

2. Выводим их в поток с отдачей ffmpeg для обработки в один файл:

cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4

Всё, на выходе получаем output.mp4, с которым далее и работаем.

width not divisible by 2

Иногда, при применении такой команды:

ffmpeg -i "output.mp4" -acodec aac -af "volume=11dB" -ab 64k -ac 1 -vcodec libx264 -vf scale="'if(gt(a,16/9),640,-1)':'if(gt(a,16/9),-1,360)'" -vb 400k -g 24 -r 24 -f mp4 "dest.mp4"

мы получали такую ошибку:

...
[libx264 @ 000000000429a9c0] width not divisible by 2 (203x360)
...
Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

Эта команда при конвертации в MP4 с аудио-битрейтом 64К и одним аудио-каналом и с видео-битрейтом 400К масштабирует видео в 640*360 пикселей (соотношение 16/9) с сохранением пропорций, т.е. подгонки ширины/высоты при необходимости.

Сперва мы не обращали на ошибку внимания, но потом она стала проявляться всё чаще и чаще, и мы решили что-то с этим сделать.

Оказывается, обходится она относительно легко, надо в соотв. формуле значение -1 (что означает исходную величину) заменить на формулу приведения к чётности: trunc(oh*a/2)*2) или trunc(ow/a/2)*2, и в итоге правильная команда должна выглядеть так:


ffmpeg -i "output.mp4" -acodec aac -af "volume=11dB" -ab 64k -ac 1 -vcodec libx264 -vf scale="'if(gt(a,16/9),640,trunc(oh*a/2)*2)':'if(gt(a,16/9),trunc(ow/a/2)*2,360)'" -vb 400k -g 24 -r 24 -f mp4 "14221.mp4_conv.mp4"

Всё, ошибка width not divisible by 2 больше не возникает, и мы радостно поднимаем бокалы с победой.

P.S.

Да, FFMPEG это мощнейший и до конца мною не изученный механизм обработки медиа, с которым можно буквально творить чудеса. Причём он постоянно развивается. И часто в поиске решения под него мы натыкаемся на ответы для старых версий, которые для новых версий не подходят, так как совместимость авторами часто нарушается.

Например, при кодировании в AAC (Advanced Audio Codec) мы использовали такую приставку: -acodec libvo_aacenc

При выполнении команд на другом сервере у нас могла вылезти такая ошибка:

Unknown encoder 'libvo_aacenc'

В этом случае название кодека возможно надо указывать так: -acodec aac

Вообще, решение подобных коллизий можно осуществлять так:
Для просмотра списков кодеков используем такую команду:
ffmpeg -codecs
Грепаем по части названия нужного нам кодека и смотрим, как он обозначается в FFMPEG, например, так:

~$ ffmpeg -codecs | grep aac
...
DEA.L. aac AAC (Advanced Audio Coding) (encoders: aac libvo_aacenc )
D.A.L. aac_latm AAC LATM (Advanced Audio Coding LATM syntax)

Часть вывода от FFMPEG с перечислением опций компилятора и поддерживаемых функций я опустил, для нас важны последние две строчки.
Буква D означает декодирование возможно, буква E – кодирование возможно (encoding), A – аудио-кодек.
Т.о. для AAC мы видим возможность кодирования/декодирования, а названия кодеков как они представлены ещё в FFPMPEG могут быть в подсказке (encoders: aac libvo_aacenc ).

Если всё внимательно читать и соображать, то можно любые вопросы решить и любые проблемы обойти, чтобы выйти победителем в этой нелёгкой схватке человек-компьютер.

Удачи на даче и в делах, любви в семье и в друзьях.
До встречи!