mwlon
mwlon

Reputation: 1006

Using FFMPEG select video filter with -ss on input

I'm currently using an ffmpeg command like this, where I want to select very particular video frames from between (say) 6 and 8 seconds into the video:

ffmpeg
  -t 10
  -i test/timer.mp4
  -ss 6
  -vf "select=eq(ceil(n * 1 / 29.97) + 1\, ceil((n+1) * 1 / 29.97)) * lt(n\, 8 * 29.97)"
  tmp/%07d.png

However, this makes ffmpeg decode the entire video up to 6s because the -ss comes after the -i. How can I change this command to still do the video filter based on absolute timestamp into the video? For instance,

ffmpeg
  -ss 6
  -t 4
  -i test/timer.mp4
  -vf "select=eq(ceil(n * 1 / 29.97) + 1\, ceil((n+1) * 1 / 29.97)) * lt(n\, 8 * 29.97)"
  tmp/%07d.png

Is not equivalent because n now refers to the frame number starting after 6s into the video. This ends up selecting different frames.

Any way to reference the input video's absolute timestamp or frame number when using -ss on it?

Upvotes: 3

Views: 2316

Answers (2)

Gyan
Gyan

Reputation: 93068

You can add -copyts to convey source timestamps, but you won't be able to use n which references index of frames fed to the filter.

Assuming a constant rate 29.97 video stream, use

ffmpeg
  -ss 6 -to 10
  -copyts
  -i test/timer.mp4
  -vf "select='trunc(t+1001/30000+TB)-trunc(t)'" -vsync 0
  tmp/%07d.png

I've used the exact rational value for 29.97.

Upvotes: 3

Mattias Wadman
Mattias Wadman

Reputation: 11425

Maybe you can use some other variable like t (PTS time) instead. You might need to subtract with start_t etc to get time starting from zero. See https://www.ffmpeg.org/ffmpeg-all.html#select_002c-aselect for all variables available with the select filter.

If your selecting a continuous range of frames then maybe the trim filter is easier to use.

Upvotes: 0

Related Questions