Есть ли способ обнаружить дубликаты кадров в видео с помощью ffmpeg
.
Я попробовал флаг -vf
с select=gt(scene\,0.xxx)
для смены сцены. Но это не помогло мне.
Есть ли способ обнаружить дубликаты кадров в видео с помощью ffmpeg
.
Я попробовал флаг -vf
с select=gt(scene\,0.xxx)
для смены сцены. Но это не помогло мне.
Используйте фильтр mpdecimate, целью которого является "Отбросить кадры, которые не сильно отличаются от предыдущего кадра, чтобы уменьшить частоту кадров".
Это создаст консольное показание, показывающее, какие кадры, которые, по мнению фильтра, являются дублирующими.
ffmpeg -i input.mp4 -vf mpdecimate -loglevel debug -f null -
Чтобы создать видео с удалением дубликатов
ffmpeg -i input.mp4 -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mp4
Выражение фильтра th set генерирует ровные метки времени для видео в FRAME_RATE fps. См. Объяснение временных меток в разделе Что такое временные рамки видео, временная база или временная метка в ffmpeg?
У меня также была эта проблема, и превосходный ответ Gyan выше меня начал, но результатом было десинхронизированное аудио, поэтому мне пришлось изучить дополнительные возможности:
mpdecimate
- это стандартная рекомендация, которую я нашел во всем SO и в Интернете, но я не думаю, что это должен быть первый выбор frac
, но эту дополнительную работу вы можете избежать, если сможетеmp4
(source), но я использовал mkv
поэтому это ограничение не применимо к моему делу, но хорошо знать об этомdecimate
удаляет кадры точно, но это полезно только для периодически встречающихся дубликатов ffprobe in.mkv
выведет обнаруженный FPS; это может выглядеть так
Stream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 1920x1080, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
фактическая частота кадров может быть обнаружена, если вы открываете медиа- in.mkv
в медиаплеере, который позволяет вам шагнуть на один кадр в то время; затем подсчитайте шаги, необходимые для увеличения времени воспроизведения в течение 1 секунды, в моем случае это было 30 кадров в секунду
N/FRAME_RATE/TB
кроме использования переменной FRAME_RATE
N/FRAME_RATE/TB
равен приведенному ниже примеру документации ffmpeg (source)
Установите фиксированную скорость 25 кадров в секунду:
setpts=N/(25*TB)
математика за ним прекрасно объясняется в том, что такое временная шкала видео, временная база или временная метка в ffmpeg?
TB
для повышения точностиFRAME_RATE
vs буквальное значение FPS (например, 25)FRAME_RATE
в N/FRAME_RATE/TB
FRAME_RATE
самостоятельно N/25/TB
FRAME_RATE
(и я на самом деле пробовал это), он бы принял неверные обнаруженные fps из 25 кадров, то есть FRAME_RATE=25
, запустил его через фильтр mpdecimate
который удалит каждый шестой кадр, и он будет обновляться до FRAME_RATE=20.833
так что N/FRAME_RATE/TB
самом деле будет N/20.833/TB
что совершенно неверновот что я использовал с хорошими результатами
ffmpeg -i in.mkv -vf mpdecimate out.mkv
ffmpeg -i in.mkv -vf decimate =cycle=6, setpts =N/25/TB out.mkv
но следующее дало мне десинхронизированное аудио
ffmpeg -i in.mkv -vf mpdecimate, setpts =N/FRAME_RATE/TB out.mkv
ffmpeg -i in.mkv -vf mpdecimate, setpts =N/25/TB out.mkv
как вы видите
FRAME_RATE
и использовать N/25/TB
вместо этого, потому что фактический FPS не был обнаружен должным образом-af asetpts =N/SAMPLE_RATE/TB
SAMPLE_RATE
соответствии с соотношением дублированных кадров, но мне кажется, что это лишняя ненужная работа, особенно когда у моего видео было синхронизированное аудио в начале, поэтому лучше использовать команды, которые будут содержать его таким образом, вместо того, чтобы фиксировать его позже Если обычно рекомендуемая команда ffmpeg -i in.mkv -vf mpdecimate, setpts =N/FRAME_RATE/TB out.mkv
не работает, попробуйте это:
ffmpeg -i in.mkv -vf mpdecimate out.mkv
или же
ffmpeg -i in.mkv -vf decimate =cycle=6, setpts =N/25/TB out.mkv
(cycle=6
потому что каждый 6-й кадр дублируется и N/25/TB
потому что после удаления дубликатов видео будет иметь 25 кадров в секунду (FRAME_RATE
переменную FRAME_RATE
), настройте для использования)