2014-03-19

Как склеить видео разных форматов, разного разрешения, аспекта, с разными прочими характеристиками

Работая с записями игровых стримов, столкнулся с необходимостью склеивать небольшие их кусочки в одно видео. Обычно с этим не возникает проблем, но в некоторых случаях приходится иметь дело с кусками, которые были записаны в разном разрешении, или разной частотой кадров, не говоря о разных кодеках. Обрабатывать видео в avidemux, в котором я это обычно делал, конечно было можно, но хотелось максимально автоматического решения. Оказалось что собрать такое самому не очень сложно, более того решение основано на совершенно бесплатных и мультиплатформенных утилитах: avconv (форк ffmpeg) и MP4Box.

Как же склеить разное видео? Алгоритм обработки следующий: привести исходные видеофрагменты к общему формату и характеристикам, затем собрать воедино. В качестве формата видеопотока был выбран H264, для аудио - mp3. Стоит учесть, что для успешного склеивания фрагментов, требуется не только общий формат, но и характеристики, такие как частота кадров или частота аудиопотока. Также надо иметь в виду, что в процессе видео подвергаются перекодированию, что не может не сказаться на качестве. Впрочем, для того видео, с которым нужно работать мне, это не критично, и вообще avconv весьма хорошо справляется с кодированием.

Итак, как же это юзать. Предположим мы имеем 2 видео: S1.flv и S2.flv. Переконвертим их командой:

avconv -i S1.flv -map 0 -vf "scale=iw*sar*min(1280/(iw*sar)\,720/ih):ih*min(1280/(iw*sar)\,720/ih),pad=1280:720:(ow-iw)/2:(oh-ih)/2" -c:a libmp3lame -ar 48000 -c:v libx264 -r 30 -bf 2 -g 30 -profile:v high -preset veryfast -level 42 O1.mp4

avconv -i S2.flv -map 0 -vf "scale=iw*sar*min(1280/(iw*sar)\,720/ih):ih*min(1280/(iw*sar)\,720/ih),pad=1280:720:(ow-iw)/2:(oh-ih)/2" -c:a libmp3lame -ar 48000 -c:v libx264 -r 30 -bf 2 -g 30 -profile:v high -preset veryfast -level 42 O2.mp4


Выглядит устрашающе, но на выходе мы получим 2 ролика с одинаковыми характеристиками и, даже, растянутых (или ужатых) до одинакового разрешения - 1280x720 - с добавленными черными полосами там, где это нужно. Последнее нужно для склеивания видео в один ролик, поэтому с черными полосами так или иначе придется смириться, а за процесс "скейлинга" отвечает замечательный параметр -vfзначение для которого вывел некто Kevin Locke, оно является практически ключевым местом всех преобразований и я очень рад что кто-то проделал эту работу за меня =). Параметры, с которыми можно попробовать поиграться:

-ar 48000 - частота аудиопотока
-r 30 - частота кадров видео
-g30 - частота ключевых кадров
-preset veryfast - скорость кодирования, для улучшения качества можно выбрать veryslow или один из прочих пресетов H264.

После конвертации мы получим два файла: O1.mp4 и O2.mp4, контейнер выбран не случайно и заточен под утилиту MP4Box. Синтаксис объединения таков:

MP4Box -add O1.mp4  -cat O2.mp4 out.mp4

Стоит отметить, что параметр -add указывается для первого файла, для всех последующих справедлив параметр -cat.
На выходе получаем out.mp4, содержащий в себе все видеофрагменты в порядке их указания.

Разумеется данное решение не совсем автоматично без скрипта, а так как хотелось еще и платформонезависимого решения, то пришлось навая скрипт на питоне. Да, питон не входит в дитрибутив винды, но и avconv с MP4Box (входит в пакет GPAC) поставить придется (http://win32.libav.org/win64/ и http://gpac.wp.mines-telecom.fr/downloads/) зато после этого выходит действительно "однокнопочное" решение - стоит в консоли зайти в директорию с набором flv-файлов (формат можно указать в начале скрипта) и выполнить:
python путь_к_скрипту
дальше можно откинуться на спинку кресла =)

Ссылка на актуальную версию скрипта: http://pastebin.com/hCfFSF5a

Ссылка на архив со всем необходимым: https://drive.google.com/file/d/0B3kqpI0yeB0iVG1hRmpBdEN5emM/edit?usp=sharing

Видео про то как все это поставить:



Upd: сделал бинарник, все-в-одном-экзешнике: avmerge_x64.7z , avmerge_x86.7z

Комментариев нет:

Отправить комментарий