VideoHelp Forum




+ Reply to Thread
Results 1 to 14 of 14
  1. I'm trying to change the frame rate (and thus duration) of a video with no audio stream. My video is 23 seconds long @ constant 30 fps but I want to make it play at 25 fps, i.e. the new video should be about 28 seconds long.

    Instructions on how to do with with the setpts filter are all over the internet and it looks very simple. I use the following command:

    Code:
    ffmpeg -i vidsilent.mkv -vf setpts=N/25/TB out25.mkv
    The file out25.mkv plays for 28 seconds as expected, but if I examine metadata using Mediainfo, it says the frame rate is Variable. If I instead save to mp4 container:

    Code:
    ffmpeg -i vidsilent.mkv -vf setpts=N/25/TB out25.mp4
    then it also plays for 28 seconds but Mediainfo says the frame rate is still 30 fps, even though the action appears to be slowed down by the right amount. Examining the playback in avidemux I see that some frames have been duplicated to pad out the file to 30 fps. Based on the ffmpeg setpts documentation and examples on many forums, I can't understand why this is the default behaviour. I've tried it with two different videos from completely different sources and the problem is the same.

    How can I simply get all the frames in my original video to be played at constant 25 fps?
    Quote Quote  
  2. Try:
    Code:
    ffmpeg -r 25 -i vidsilent.mkv out25.mkv
    Quote Quote  
  3. Thanks! That does give the result I wanted.

    For my own education (and curiosity), why does the other method not work? I am very new to ffmpeg and I actually came across that syntax while searching online for how to use the mpdecimate filter to strip duplicate frames. In various places, it is suggested to use

    Code:
    ffmpeg -i vidsilent.mkv -vf mpdecimate,setpts=N/25/TB out25.mkv
    but since this did not do what I wanted, I started exploring the behaviour of the filters when applied separately, and then found that setpts behaviour was not as I expected.

    Can the -r 25 method be used in conjunction with mpdecimate? It seems I can achieve the final result I want by doing this:

    Code:
    ffmpeg -i vidsilent.mkv -vf mpdecimate out.mkv
    ffmpeg -r 25 -i out.mkv out25.mkv
    But it would be nice to only have to re-encode once, if possible.
    Quote Quote  
  4. ffmpeg -i vidsilent.mkv -vf mpdecimate - r 25 out25.mkv
    You should also specify the encoder and the encoding quality, g.e. -c:v libx264 -crf 20
    Quote Quote  
  5. Originally Posted by ProWo View Post
    ffmpeg -i vidsilent.mkv -vf mpdecimate - r 25 out25.mkv

    I tried this, but for some reason it generates a video that is exactly the same duration as the input. My test video has enough duplicate frames that the mpdecimated video should end up a few seconds shorter than the original even after slowing the frame rate to 25 fps, but the output from the above command contains some duplicated frames in order to pad it out to the original duration... which kinda puts me back to square 1! (except that it's now 25 fps with a small number of duplicate frames instead of 30 fps with a large number of duplicate frames). I want 25 fps with no duplicate frames.
    Last edited by tfolder; 26th Dec 2020 at 03:25.
    Quote Quote  
  6. This isnt possible i think, because the 30fps source is probably tekecined. So you can decimate to have a 23.976 result. If youwant 25fps then frames are added/duplicated.
    Quote Quote  
  7. That doesn't make sense to me. Suppose I created a 10 second video @ 23.976 fps which contains 240 frames, then I want to speed up the video to 25 fps so that the 240 frames would play in 9.6 seconds. I can't imagine any reason why I should not be able to do this by just instructing the encoder to timestamp my set of 240 frames at 25 per second. Why should the history of the video source make a difference?

    (Remember I am not trying to maintain a constant duration of the video, because there is no audio sync to maintain.)
    Last edited by tfolder; 26th Dec 2020 at 04:55.
    Quote Quote  
  8. Then try ffmpeg - r 25 -i vidsilent.mkv -vf mpdecimate out25.mkv
    Quote Quote  
  9. As far as I can tell, that applies the two steps in the wrong order - first slows the file to 25 fps and THEN mpdecimates, so I end up with an even longer file padded with duplicate frames.
    Quote Quote  
  10. I'd still be interested in a solution to my original question: why setpts isn't behaving as documented, and/or what is the correct command syntax to make it do what I want.
    Quote Quote  
  11. I confirmed what you saw in your first post.

    With "-vf setpts=N/25/TB" and outputting to MKV ffmpeg is keeping 1/30 per frame for most frames but increasing the duration of every 5th frame by a factor of 2 increasing the running time by a factor of 30/25. Hence the variable frame rate.

    When outputting to mp4 it keeps 1/30 second per frame but increases the number of frames by a factor of 30/25, thereby increasing the running time by that amount.

    I don't know why it behaves differently between the two cases. Though the final effect is the same.
    Last edited by jagabo; 27th Dec 2020 at 09:38.
    Quote Quote  
  12. Using setpts=PTS*30.0/25.0 results in the same behavior. VFR with some 2x duration frames in MKV, CFR with additional frames in MP4.
    Quote Quote  
  13. Aha! Combining the advice from the last few posts, I think I've found the answer:

    Code:
    ffmpeg -r 25 -i vidsilent.mkv -vf mpdecimate,setpts=N/25/TB out25.mkv
    So it needs to specify both methods of frame rate change in order to work. I still don't fully understand why, but thanks to both of you for helping me piece together a solution.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!