Reputation: 1006
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
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
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