Как вырезать в точные кадры, используя ffmpeg?

22

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

ffmpeg -i input.mpg -acodec copy -vcodec copy -timecode_frame_start 200 -vframes 210 -n ouput.mpg

Я переместил параметр timecode_frame_start до и после других параметров без изменений в результатах. Есть ли дополнительная опция, которую мне нужно указать? Я пробовал различные форматы файлов, mkv, avi, mp4, и, похоже, проблема не связана с кодеками. Вот один файл, который я пробовал:

http://www.seaotter.com/marine/movies/hermit-long-01.mpg

Я что-то пропустил?

curmil
источник
Похоже, что в списке рассылки об этом ответили (и учтите, что с копией -vcodec вы не сможете «реально» получить вырезку по кадрам, поскольку она может ресинхронизироваться только на i-кадрах
rogerdpack
@ user39364 Я спросил в списке рассылки, и оказалось, что эта опция не делает то, что хочет ОП. Я также узнал кое-что новое :)
slhck
Просто хотел заметить, что я нашел метод для обрезки в точных кадрах, используя melt, см. Точно вырезать видеофайлы из командной строки - Super User
sdaau

Ответы:

46

Я только что узнал, что timecode_frame_startтак не работает. Единственный способ начать с определенных кадров - преобразовать количество кадров в ss.msсинтаксис или hh:mm:ss.ms. Итак, если ваше видео на скорости 25 кадров в секунду и вы хотите начать с 133 кадров, вам понадобится

133/25 = 5,32

Итак, беги

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac out.mp4

Обратите внимание, что обрезка точных кадров с помощью битового потока copy ( -c:v copy) невозможна, поскольку не все кадры являются внутренне кодированными и могут стоять самостоятельно.

-ss всегда будет с точностью до кадра.

Если вы хотите кодировать определенное количество кадров, используйте -frames:v, например:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac -frames:v 60 out.mp4

У вас также есть выбор использования видеофильтров , но поддержка аудио может быть не точной. И, видимо, поиск по кадрам все еще не является особенностью. Вы можете следовать этой ветке списка рассылки FFmpeg-users для получения дополнительной информации:

Вы можете использовать -vf selectдля точного выбора кадра (что-то вроде -vf 'select=gte(n\,100)'пропустить 100 первых кадров)

slhck
источник
3
для видео с пропускаемыми кадрами (например, 29,97 кадр / с), продолжительность которых превышает 10 минут; Как бы вы точно рассчитали время для определенного кадра?
GFoley83
select=gte(n\,100)метод работает , но искание съедает производительность. Если вы тестируете, кодируя только 30 кадров за раз. Чем дальше в видео, которое я запускаю, тем больше ffmpeg требуется для завершения из-за поиска.
Адам Грант
6

Опция

-vf select = «между (n \, start_frame_num \, end_frame_num ), setpts = PTS-STARTPTS"
например,

-vf select=“between(n\,200\,300),setpts=PTS-STARTPTS"

вырезает видео из (включает) 200-й (включает) 300-й кадр, отсчет последовательности начинается с 0.

Нуо Чен
источник