Этот ответ улучшает @slhck «s ответ, который может не работать в некоторых ситуациях.
Одна тонкость в выборе кадров по (приблизительной) временной метке заключается в том, что фактическая временная метка кадра может не быть точно равна требуемой временной метке. Например, в видео с частотой кадров 23,98 (24000/1001) нет кадра с отметкой времени 1,0 - ближайший кадр имеет значение отметки времени 1,001.
Выражение eq(t, specific_timepoint)
оценивается как истинное, только если 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