5

am trying to cut a part of Video

Here is the code i have tried Let's say i have 6 seconds video and i want to slow down 2:5 seconds video that 3 second video

First approach after searching is, Cut the video, then apply slow filter then concat it with original video. But this is a mid part not entire video. How can i modify below code

ffmpeg -i Soon.mp4 -filter_complex [0:v]trim=2:5,setpts=PTS-STARTPTS[v1];[v1]setpts=0.5PTS[v1];[0:a]atempo=2[a] concat=n=1:v=1:a=1 -map "[v]" -map "[a] -preset superfast -profile:v baseline output.mp4

3 Answers 3

12

This slows down one part of a video and keeps the rest as is.

ffmpeg -i Soon.mp4
  -filter_complex
     "[0:v]trim=0:2,setpts=PTS-STARTPTS[v1];
      [0:v]trim=2:5,setpts=2*(PTS-STARTPTS)[v2];
      [0:v]trim=5,setpts=PTS-STARTPTS[v3];
      [0:a]atrim=0:2,asetpts=PTS-STARTPTS[a1];
      [0:a]atrim=2:5,asetpts=PTS-STARTPTS,atempo=0.5[a2];
      [0:a]atrim=5,asetpts=PTS-STARTPTS[a3];
      [v1][a1][v2][a2][v3][a3]concat=n=3:v=1:a=1"
  -preset superfast -profile:v baseline output.mp4

How does it work?

  • The trim and atrim filters cut the video into different parts, from 0–2 seconds, from 2–5, and from 5 to the end.
  • In each part a setpts/asetpts filter is applied, which, when using the option PTS-STARTPTS, "resets" the presentation timestamps of each frame in each part, so that they can later be concatenated easily.
  • Each part is given an output label (e.g. [v1] through [v3]).
  • For the video parts that need to be slowed down, every presentation timestamp is doubled (2*(…)), which effectively halves the speed of the video. If you wanted to speed up the video, use a multiplier lower than 1.
  • For audio parts to be sped up / slowed down, use the atempo filter, whose parameter is the speedup (e.g., 0.5 = half speed).
  • These parts are finally concatenated using the concat filter.
4
  • Hi Thanks for this code :) can u please explain this part [0:a]atrim=2:5,asetpts=2*(PTS-STARTPTS),atempo=0.5[a2]; what is 2 and 0.5? Jun 27, 2017 at 20:19
  • If you're slowing down part of a video, you'll want to slow down corresponding audio as well. But not the other parts of the audio. That 2 is not needed. Removed. 0.05 is to slow down the audio by 2.
    – Gyan
    Jun 28, 2017 at 4:57
  • 1
    Note: -preset superfast -profile:v baseline will usually result in very bad quality and/or high file sizes. Unless you know that you need these options, it's better to not use them and let ffmpeg use the default settings.
    – slhck
    Aug 18, 2019 at 15:46
  • Worked perfectly! Thanks so much. Jul 11, 2020 at 16:11
0

Thanks to Gyan's answer! Taking that plus a bit research, I have applied it to speed up a video with audio by 6 times. Be aware that atempo argument has a value ranging between 0.5 and 2. So three atempo were used to make up 6 (2 x 2 x 1.5). So the idea is to make the video from 00:00:00 to 00:17:30, a total of 1050 seconds, to play 6 times faster and the rest stays unchanged. Code example as follows:

ffmpeg -i in_file.mp4 -filter_complex \
   "[0:v]trim=0:1050,setpts=1/6*(PTS-STARTPTS)[v1];\
   [0:v]trim=1050,setpts=PTS-STARTPTS[v2];\
   [0:a]atrim=0:1050,asetpts=PTS-STARTPTS,atempo=2,atempo=2,atempo=1.5[a1];\
   [0:a]atrim=1050,asetpts=PTS-STARTPTS[a2];\
   [v1][a1][v2][a2]concat=n=2:v=1:a=1" \
   output_file.mp4
1
0

@ slhck

This slows down one part of a video and keeps the rest as is.

I've never seen PTS-STARTPTS before. I have always used just PTS for this purpose. I have a recent script that hangs with just PTS but it works with PTS-STARTPTS. Can you explain why?

With PTS

ffmpeg -i "input.mkv" \
-filter_complex \
" \
[0:v]trim='00\:08\:23.961':'00\:08\:24.379',setpts=4*PTS,curves=psfile=curves40.acv,unsharp=13:13:1.5:13:13:1.5[v0]; \
[0:a]atrim='00\:08\:23.961':'00\:08\:24.379',asetpts=PTS,atempo=0.5,atempo=0.5[a0]; \
[0:v]trim='00\:08\:23.961':'00\:08\:24.379',reverse,setpts=4*PTS,curves=psfile=curves40.acv,unsharp=13:13:1.5:13:13:1.5[v1]; \
[0:a]atrim='00\:08\:23.961':'00\:08\:24.379',areverse,asetpts=PTS,atempo=0.5,atempo=0.5[a1]; \
[v0][a0][v1][a1]concat=n=2:v=1:a=1[out] \
" \
-map "[out]" \
-r $fps -c:v libx264 -preset slow -crf 10 -map_chapters -1 -bf 2 -flags +cgop -pix_fmt yuv420p -codec:a aac -strict -2 -b:a 384k -r:a 48000 \
-movflags faststart "otput.mp4"

With PTS-STARTPTS

ffmpeg -i "input.mkv" \
-filter_complex \
" \
[0:v]trim='00\:08\:23.961':'00\:08\:24.379',setpts=4*(PTS-STARTPTS),curves=psfile=curves40.acv,unsharp=13:13:1.5:13:13:1.5[v0]; \
[0:a]atrim='00\:08\:23.961':'00\:08\:24.379',asetpts=PTS-STARTPTS,atempo=0.5,atempo=0.5[a0]; \
[0:v]trim='00\:08\:23.961':'00\:08\:24.379',reverse,setpts=4*(PTS-STARTPTS),curves=psfile=curves40.acv,unsharp=13:13:1.5:13:13:1.5[v1]; \
[0:a]atrim='00\:08\:23.961':'00\:08\:24.379',areverse,asetpts=PTS-STARTPTS,atempo=0.5,atempo=0.5[a1]; \
[v0][a0][v1][a1]concat=n=2:v=1:a=1[out] \
" \
-map "[out]" \
-r $fps -c:v libx264 -preset slow -crf 10 -map_chapters -1 -bf 2 -flags +cgop -pix_fmt yuv420p -codec:a aac -strict -2 -b:a 384k -r:a 48000 \
-movflags faststart "otput.mp4"

In both cases I get frame= 0 fps=0.0 q=0.0 size= 0kB time=00:00:00.00 bitrate=N/A speed= 0x but it works in this case.

Your Answer

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

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