Find video duration after applying slow motion

Posted on

Problem :

I’m trying to have apply slow motion effect to a series of videos. And further those videos will be scaled, padded and cross-faded. Following is the command I’m using to apply slow motion.

ffmpeg -i 1.mp4 -filter_complex "
[0:v]trim=0:5,setpts=PTS-STARTPTS[tv1];
[0:v]trim=5:7,setpts=PTS-STARTPTS[tv2];
[0:v]trim=start=7,setpts=PTS-STARTPTS[tv3];
[tv2]setpts=PTS*2[slow];
[tv1][slow][tv3]concat=n=3:v=1:a=0[out]" -map [out] -c:v libx264 test.mp4

I have two questions.

  1. Referring to [tv2] though it is trimmed and applied the slow motion effect starting from 5th second actually it apply the effect from 4th second. What is the reason for this?

Following is the command I’m using for other processing right after concatenate in the above command.

[concat0]scale=iw*min(1280/iw,720/ih):ih*min(1280/iw,720/ih),pad=1280:720:(1280-iw*min(1280/iw,720/ih))/2:(720-ih*min(1280/iw,720/ih))/2,format=pix_fmts=yuva420p,fade=t=out:st=16:d=2:alpha=1,setpts=expr=PTS-STARTPTS+10/TB[va0];

There I need to specify the setpts and I’m using the cumulative duration of the videos before the current video. Here is the complete command I’m using for it.

  1. How can I calculate the duration of the video after applying the slow motion effect? For instance what would be the increment of the duration of video result from the 1st command I mentioned here in seconds or even microseconds?

Solution :

Question 1 – The command is incomplete because you don’t take into account the audio track, you changed the PTS only in the video track. To see the difference just try this:

# no-good, starts from 4th second audio with a frozen video frame
ffmpeg -i in.mp4 -vf trim=5:7 out.mp4
#
# works as expected, both audio and video start at 5th second
ffmpeg -i in.mp4 -vf trim=5:7 -af atrim=5:7 out.mp4

Question 2 – This too won’t work as expected for the same reason, but once you fix the previous issue here’s a not-very-elegant yet effective trick to correlate the “before” and “after” times:

# overlay the input video with a timer, pulled to the right 200 pixels
ffmpeg -i in.mp4 -f lavfi -i testsrc=n=3 -vf overlay=x=200 in-with-time.mp4
#
# do all your manipulation, and finaly overlay with another timer at x=0
ffmpeg -i in-with-time.mp4 -f lavfi -i testsrc=n=3 -filter_complex "..stuff...,overlay[out]" out.mp4

This provides you per frame the original and resulting time at 1 millisecond accuracy.

Leave a Reply

Your email address will not be published. Required fields are marked *