4

У меня есть видео с камеры безопасности, которое было изначально записано с низкой частотой кадров, возможно, 15 кадров в секунду, возможно, 10 кадров в секунду, может быть, даже меньше. С тех пор он был преобразован кем-то еще в 25 кадров в секунду (без изменения длительности). Я предполагаю, что были добавлены дополнительные дублирующие кадры, и, возможно, это также немного исказило точное время, в которое отображаются исходные кадры.

Я хочу перекодировать видео с помощью ffmpeg в исходную частоту кадров, не отбрасывая ни одного полезного кадра реального движения. Если я просто использую фильтр fps он не будет избирательно выбирать, какие кадры он хранит, и я предполагаю, что из-за ошибок округления это может привести к тому, что некоторые дублирующиеся кадры могут остаться и навсегда потерять полезные кадры, что ухудшит ситуацию. В любом случае, я не знаю, какое число сказать фильтру, потому что я не знаю точно, какова была первоначальная частота кадров!

Как я могу приступить к восстановлению этого видео с помощью ffmpeg?

ffmpeg -i "orig.mp4" -an -vcodec h264 -vf "fps=???" "fixed.mp4"

2 ответа2

5

Мне удалось исправить мой файл. Я нашел фильтр mpdecimate , который удаляет повторяющиеся или почти повторяющиеся кадры из видеопотока. Сначала я попробовал:

ffmpeg -loglevel debug -i orig.mp4 -an -vf "mpdecimate" test.mp4

Я добавил -loglevel debug чтобы получить больше информации во время транскодирования. Информация показала, что mpdecimate делает с фреймами, что было много-много такого шаблона:

lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:44032 pts_time:3.44 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:44544 pts_time:3.48 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:45056 pts_time:3.52 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:45568 pts_time:3.56 drop_count:4
781>=hi keep pts:46080 pts_time:3.6 drop_count:-1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:46592 pts_time:3.64 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:47104 pts_time:3.68 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:47616 pts_time:3.72 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:48128 pts_time:3.76 drop_count:4
821>=hi keep pts:48640 pts_time:3.8 drop_count:-1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:49152 pts_time:3.84 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:49664 pts_time:3.88 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:50176 pts_time:3.92 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:50688 pts_time:3.96 drop_count:4
793>=hi keep pts:51200 pts_time:4 drop_count:-1

То есть он последовательно отбрасывал 4 кадра подряд как дубликаты и сохранял каждый 5-й. Это показало, что исходная частота кадров была 1/5 от того, что было сейчас. Мне повезло! Поскольку текущие 25 кадров в секунду для видео были кратны исходной частоте кадров, не должно быть проблем с временным смещением сохраненных и пропущенных кадров. Поэтому я ретранслировал исходное видео с ничего более сложного, чем -vf "fps=5" , и результат, похоже, был в порядке. Просто чтобы быть уверенным, я передал вывод через фильтр mpdecimate , и он обнаружил все оставшиеся кадры как "keep". Таким образом, исходный файл был не так запутан, как я думал.

2

Если дополнительные кадры являются дубликатами, а не интерполяциями, то может работать следующее:

ffmpeg -i orig.mp4 -an -vf "select='gt(scene\,0.001)',setpts=N/(10*TB)" -r 10 fixed.mp4

Идея состоит в том, чтобы выбрать все кадры, а не дубликаты предыдущего кадра. Затем ПТС восстанавливаются в соответствии с заданной скоростью. Возможно, вам придется настроить значение сцены вверх или вниз, чтобы правильно настроить фильтр обнаружения. Если видео появляется быстрее или медленнее, чем в режиме реального времени, то уменьшите или увеличьте скорость (и установите значение знаменателя) соответственно.

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