FFMPEG Точное наложение

478
SuperUser_Novice

Давайте перейдем прямо к делу, у меня проблема с функцией наложения ffmpeg. У меня есть два видео. Один 2865 кадров, второй 2865 кадров. Оба в 30000/1001 кадров в секунду. Я проверил обе их метки времени перед наложением и записал их в файл, который я наложил бы на свой пост, поскольку изображение имело бы мою репутацию, так что сейчас вам просто нужно поверить, что я говорю правду, когда я говорят, что их метки времени точно такие же.

Теперь, несмотря на совпадение частоты кадров видео, результат этой команды:

"ffmpeg", "-i", fmt.Sprintf("%s%s", CCME.PathsToUse[0], CCME.UnderlayVideo), "-i", fmt.Sprintf("%s%s", CCME.PathsToUse[1], CCME.VideoName),  "-filter_complex", "overlay=0:0", "-vsync", "0", "-crf", "18", "-y", "-shortest", "-strict", "-2", fmt.Sprintf("%s%s.%s", CCME.PathsToUse[2], CCME.FinalVideoName, CCME.VidFormat 

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

Frame 770: Repeated  Frame 1500: Repeated  Frame 2276: Repeated  Missing Or Mangled Frame(s) After Frame 2591  QR DATA: 2593  3 frames repeated and or added. 

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

Кто-нибудь имеет представление о том, почему это происходит и чего не хватает в приведенной выше команде или что можно добавить, чтобы эти видео выстроились в линию и / или предотвратили повторы и пропадание кадров? Насколько я знаю, этого не должно происходить, но, похоже, все, что я сделал до сих пор, не удалось исправить.

1
Запустите команду с добавленным -report и поделитесь отчетом. Gyan 6 лет назад 0
Рад снова тебя видеть, Гьян. Вам нужен весь журнал? Это довольно долго. Или их конкретную часть я могу извлечь и поделиться? SuperUser_Novice 6 лет назад 0
Полный лог, пожалуйста. Разместите это в другом месте при необходимости. Gyan 6 лет назад 0
Хорошо, отправил это, чтобы вести. Вот ссылка: https://drive.google.com/open?id=1YU1sqKidpT_Lfi04b-oCxhTmhL3Gal25 SuperUser_Novice 6 лет назад 0
Частота кадров и длительности не идентичны. Запустите `ffmpeg -i file -an -f mkvtimestamp_v2 filepts.txt` для обоих файлов и сравните. Gyan 6 лет назад 0
Гьян, похоже, ffprobe не возвращает точный результат для частоты кадров или отметки времени. Я могу закончить анализ выходных данных оболочки файла ffmpeg -i, чтобы получить точную частоту кадров, которая в случае двух видео была 29,99 против 29,97. Я думаю, что ваш файл ffmpeg -i -f mkvtimestamp_v2 быстро помог мне определить проблему и определить, что происходит не так. Если вы хотите, чтобы это было вашим ответом, я был бы рад принять его. SuperUser_Novice 6 лет назад 0

2 ответа на вопрос

0
Gyan

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

ffmpeg -i main.mp4 -i overlay -filter_complex "[0]setpts=1001*N/30000/TB[m]; [1]setpts=1001*N/30000/TB[o]; [m][o]overlay=shortest=1" -crf 18 out.mp4 
0
SuperUser_Novice

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

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

Идеальное наложение кадра может быть достигнуто путем деконструкции целевого видео на отдельные кадры:

exec.Command("ffmpeg", "-i", fmt.Sprintf("%s%s", CCME.PathsToUse[0], CCME.UnderlayVideo), "-start_number", "0", "-qscale:v", "2", fmt.Sprintf("%s%s%%d.jpg", TempDirPath[0], VideoName)) 

Наложение кадров по отдельности:

for x:=0; x<len(files)-2; x++ { overlayFile := exec.Command("ffmpeg", "-i", fmt.Sprintf("%s%s%d.jpg", TempDirPath[0], VideoName, x), "-i", fmt.Sprintf("%s%s%d.png", CCME.PathsToUse[1], CCME.VideoName, x), "-filter_complex", "overlay", "-y", fmt.Sprintf("%s%s%d.jpg", TempDirPath[1], VideoName, x)) 

(Примечание: в большинстве случаев не нужно было бы указывать -2. TempDir, в котором это делается, содержит подкаталог и аудиофайл, который необходимо учитывать.)

Затем Реконструкция видео на основе частоты кадров и видеотипа, полученная путем анализа выходных данных файла ffmpeg -i:

cmdConstruct := exec.Command("ffmpeg", "-framerate", AudioFS[1], "-i", fmt.Sprintf("%s%s%%d.jpg", TempDirPath[1], VideoName), "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p", "-y", "-vsync", "0", "-strict", "-2", fmt.Sprintf("%s%s.%s", CCME.PathsToUse[2], CCME.FinalVideoName, VideoFormat)) 

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

Похожие вопросы