1

У меня есть видеофайл, и мне нравится извлекать одно изображение из (около 1500) определенных временных точек (expl. -Ss 00:50, ss 00:67, ss: 01:70 ...)

Есть ли способ сделать это? Я попытался использовать эту команду:

ffmpeg.exe -ss 00:50 -i all.avi -t 00:00:01 -vframes 1 images-filename_%03d.png

Это прекрасно работает для одной картинки, но есть ли способ сделать это для такого количества конкретных временных точек?

У кого-нибудь есть совет?

2 ответа2

1

Этот ответ улучшает @slhck «s ответ, который может не работать в некоторых ситуациях.

Одна тонкость в выборе кадров по (приблизительной) временной метке заключается в том, что фактическая временная метка кадра может не быть точно равна требуемой временной метке. Например, в видео с частотой кадров 23,98 (24000/1001) нет кадра с отметкой времени 1,0 - ближайший кадр имеет значение отметки времени 1,001.

Выражение eq(t, specific_timepoint) оценивается как true, только если t точно равно specific_timepoint . Поэтому он не сможет выбрать кадр в ситуации, описанной выше. В качестве обходного пути мы можем выбрать первый кадр, следующий сразу за желаемой временной меткой, т.е. кадр, значение временной метки которого больше или равно указанному моменту времени, в то время как метка времени его предыдущего кадра была меньше указанного момента времени. Выражение выбора для одного момента времени будет

lt(prev_pts * TB, timepoint ) * gte(pts * TB, timepoint )

Обратите внимание, что я намеренно не использовал более короткий вариант

between( timepoint , prev_pts*TB, pts*TB)

что эквивалентно

lte(prev_pts * TB, timepoint ) * gte(pts * TB, timepoint )

поскольку он выберет два последовательных кадра, когда значение метки времени (первого) одного из них точно соответствует указанному значению момента времени.

Пример выбора фреймов, соответствующих или сразу после временных точек 1.5, 10 и 20:

ffmpeg -i input.mp4 -filter:v \
    "select='lt(prev_pts*TB\,1.5)*gte(pts*TB\,1.5) \
            +lt(prev_pts*TB\,10)*gte(pts*TB\,10)   \
            +lt(prev_pts*TB\,20)*gte(pts*TB\,20)'" \
    -vsync drop images-filename_%03d.png
1

Добавьте несколько временных меток в качестве параметров для фильтра select .

ffmpeg -i input.mp4 -filter:v \
"select='eq(t\,1.5)+eq(t\,10)+eq(t\,20)'" \
-vsync drop images-filename_%03d.png

Если фильтр оценивается как true, он выведет кадр, поэтому добавление проверок, сравнивающих временную метку кадра t с определенной временной меткой в секундах (например, 1.5), даст вам все кадры с этими временными метками.

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