0

When converting the framerate of a video, ffmpeg offers multiple options

one options is -r:

ffmpeg -i myvideo.mp4 -r 10 my10fpsvideo.mp4

another option is using filters:

ffmpeg -i myvideo.mp4 -filter_complex [0]fps=fps=10[s0] -map [s0] my10fpsvideo.mp4

Using the second option I can apply further filters on the changed fps stream, like selecting a start frame number for exemple select=gte(n,42)

Both these solutions don't return the same frames from the original video:

-r 10 return the frame indexes  0,1,2,4,7,9,12...
-filter_complex returns indexes     1,3,6,8,11...

As you can see -r somehow shift the output video by 2 frames and doesn't return the same frames as -complex_filter

My problem is I need to apply that start frame number filters, but I also need to extract the exact frames from the original video as -r would do

For exemple: If I convert to 10 fps and want to start at frame index 3 I should receive frames 4,7,9,12..., the frame I would have gotten if had changed framerate using -r and skipped the result's first 2 frame

I am constrained to the exact frames returned by -r by legacy data that relies on these specific frames to be returned. I am also constrained by the fact that input can be VFR and I can't precompute what frames I need to extract for a given framerate.

Right now the only solution I've found is to read the entire video and discard all frame up to that frame number, which is long and cost a lot of resources.

Is there any way to do what I'm trying to do ?

3
  • Did you just delete an earlier instance of this Q that I answered?
    – Gyan
    Commented Nov 2, 2023 at 17:28
  • @gyan Yes, another user pointed out that this was out of topic on stack overflow and needed to be deleted and reposted on video.stackexchange, which is what I did
    – BlueMagma
    Commented Nov 4, 2023 at 8:39
  • 1
    a) you aren't obliged to follow that, b) see your deleted questions and refer to my answer for a solution
    – Gyan
    Commented Nov 4, 2023 at 15:15

1 Answer 1

0

You cannot use -r and -filter_complex together. They are different ways of changing the frame rate. -r is an input or output option. -filter_complex is a filtergraph option. They have different logic and behavior. You may try this command:

ffmpeg -i myvideo.mp4 -vf “select=‘gte(n,3)’,setpts=N/10/TB” my10fpsvideo.mp4

This will skip the first three frames and then change the frame rate to 10 using the setpts filter. It should give you the same result as -r 10 and then skipping two frames. However, I do not know if it works for variable frame rate input. You have to test it yourself.

I hope this helps.

1
  • thank you for your answer, unfortunately, it doesn work even in CFR, if I understood correctly, to get X fps and start at frame F, I should enter the command: ffmpeg -i myvideo.mp4 -vf “select=‘gte(n,<F+1>)’,setpts=N/<X>/TB” my10fpsvideo.mp4 When I try your exact example for frame 2 at 10 fps, I get the frames: [3,3,4,4,5,5,5,6,6,7]
    – BlueMagma
    Commented Nov 2, 2023 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.