2

Я хочу объединить 2 или более видео, используя FFMPG, но после объединения видео возникает проблема синхронизации аудио / видео, для этого я использовал следующий код

ffmpeg -i input1.flv -qscale:v 1 intermediate1.mpg
ffmpeg -i input2.flv -qscale:v 1 intermediate2.mpg
ffmpeg -i input3.flv -qscale:v 1 intermediate3.mpg
ffmpeg -i input4.flv -qscale:v 1 intermediate4.mpg
cat intermediate1.mpg intermediate2.mpg intermediate3.mpg intermediate4.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi

Аудио дорожка в файле output.avi предшествует дорожке видео.

1 ответ1

3

Подобное использование cat может вызвать непредсказуемые проблемы. К счастью, есть два действительно полезных способа объединения файлов с помощью ffmpeg.

Concat демультиплексатор

Если все ваши входные данные относятся к одному и тому же типу файла (одни и те же кодеки и т.д.), Вы можете использовать демультиплексор concat. Вероятно, это более полезный ответ на ваш вопрос, поскольку он совместим с копией -c (и поэтому должен быть без потерь и занимать почти тривиально короткое время для завершения).

Сначала создайте файл с именем inputs.txt содержащий следующее:

file '/path/to/input1.flv'
file '/path/to/input2.flv'
file '/path/to/input3.flv'
file '/path/to/input4.flv'

Затем используйте следующую команду:

ffmpeg -f concat -i inputs.txt -c copy output.flv

Если это не работает или вы хотите объединить видео разных типов, вы можете использовать

Конкат- фильтр

ffmpeg -i input1.flv -i input2.flv -i input3.flv -i input4.flv \
-filter_complex '[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] [3:0] [3:1] concat=n=4:v=1:a=1 [v] [a]' \
-map '[v]' -map '[a]' -c:v libx264 -crf 22 -preset veryfast -c:a libfdk_aac -vbr 3 -afterburner 1 output.mp4

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

Я разобью раздел -filter_complex, чтобы было легче следить за ним.

'[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] [3:0] [3:1] 

Этот фрагмент сообщает ffmpeg, какие потоки отправлять в фильтр concat; в этом случае потоки 0 и 1 от входа 0 (ffmpeg начинает отсчет с 0, так что это первый и второй потоки из первого входного файла, в данном примере input1.flv), и потоки 0 и 1 от каждого входа до четвертый (ввод 3 в соответствии с ffmpeg, отсчет которого начинается с 0).

concat=n=4:v=1:a=1 [v] [a]'

Это сам фильтр concat. n = 4 говорит фильтру, что существует четыре входных файла; v = 1 говорит о том, что будет один видеопоток; a = 1 говорит о том, что будет один аудиопоток (я знаю, я сказал, что ffmpeg начинает отсчет с 0, но, очевидно, автор этого фильтра решил сделать это вместо этого).

[v] и [a] являются именами для выходных потоков, чтобы позволить оставшейся части строки ffmpeg использовать выходные данные фильтра concat. Я думаю, что они могут иметь произвольные имена; какой из них - видео, а какой - аудио, вероятно, определяется их относительным положением, но я этого не проверял.

Обратите внимание, что одинарные кавычки '' вокруг всего раздела фильтра являются обязательными.

-map '[v]' -map '[a]'

Это говорит ffmpeg использовать результаты фильтра concat, а не потоки непосредственно из входных файлов.

Обратите внимание, что фильтры несовместимы с потоковым копированием; Вы не можете использовать -c копию с этим методом. Я также думаю, что он не может обрабатывать мягкие субтитры, хотя я не проверял это: в документации нет никаких намеков на это, но документация ffmpeg часто является неполной или запутанной, так что в любом случае это не верный признак.

Это может объединять файлы, закодированные в разных форматах (я протестировал с h264/aac MP4 и vpx/vorbis WEBM, работал отлично), хотя они должны иметь одинаковый размер видеокадра и глубину звука (и, возможно, другие вещи).

Смотрите также здесь.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .