Я использую ffmpeg.exe чтобы объединить два видео вместе. Первое видео, по сути, представляет собой пятисекундное вступление, отображаемое в формате 1080p со скоростью 25 кадров в секунду, и оно всегда будет оставаться в том же формате. Второе - это случайное видео, которое может быть любой длины и формата, но будет файлом MP4 (h264). Этот конкретный тестовый случай - это видео с разрешением 400x240 со скоростью 30 кадров в секунду.

Исходя из этого, у меня есть 5-секундное вступительное видео в формате 1080p25, соединенное с видео в формате 240p30. Поскольку они оба являются файлами MP4, я сначала транскодирую каждый в файл mpegts используя следующее:

ffmpeg -y -i intro.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intro.mp4.ts
ffmpeg -y -i video.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts video.mp4.ts

Теперь, когда два файла конвертированы в форматы для объединения, я запускаю следующую команду для кодирования двух видео, которые объединяются:

ffmpeg -y -i "concat:intro.mp4.ts|video.mp4.ts" -c:v libx264 -preset ultrafast -crf 20 -vf fps=60 -b:v 8M -minrate 8M -maxrate 12M -bufsize -8M -c:a aac -b:a 256k output.mp4

Это работает почти так же, как и ожидалось, но одна вещь продолжает происходить: когда кодирование достигает 5-секундной отметки (либо конец вступления, либо начало самого видео), оно отображает это предупреждение: DTS 126000 < 619200 out of order

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

Поскольку остальная часть файла воспроизводится очень хорошо, я экспериментировал с настройками и был удивлен, обнаружив, что когда я изменяю предустановку x264 со ultrafast на medium или slow , это усугубляет проблему: пропуск произойдет раньше во вступлении, но оставьте фактическое видео без изменений. В тех случаях, когда ultrafast пропускает пропуск последней полсекунды видео / аудио, medium - от секунды до секунды с половиной, а slow в течение двух секунд.

Что является причиной этого, и как я могу исправить эту проблему? Я прочитал предложения о перекодировании обоих видео перед объединением, но я хотел бы избежать этого, если это возможно, поскольку вступление будет оставаться неизменным каждый раз. Если это единственное решение, есть ли способ выполнить все это с помощью одного вызова FFmpeg? Инструмент вызывается программой на C #, которую я пишу.

1 ответ1

1

Вы можете использовать предложения из этого ответа для масштабирования видео при необходимости:

ffmpeg -y -i intro.mp4 -i video.mp4 -filter_complex "\
[0:v:0]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v0]; \
[1:v:0]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2[v1]; \
[v0][0:a:0][v1][1:a:0]concat=n=2:v=1:a=1[v][a] \
" -map "[v]" -map "[a]" output.mp4

Обратите внимание, что я применил это ко всем входным данным, но вы, конечно, можете выборочно сделать это для тех, которые, как вы знаете, будут отличаться от выходного размера. В случае различных SAR вы можете использовать фильтр setsar после pad , но я не думаю, что это строго необходимо:

[0:v:0]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=sar=1[v0]

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