ffmpeg pause video every 10 seconds for 3 seconds

5,105

Solution 1

Edit: Different method added, which accounts for audio and also the overwritten frames due to the initial method,which is shown at the bottom.

ffmpeg -i input.mp4 -filter_complex \
       "[0:v]split=4[v0][v1][v2][v3]; \
        [v0]trim=start_frame=0:end_frame=1,loop=90:1:0,setpts=N/FRAME_RATE/TB[0v]; \
        [v1]trim=start_frame=1:end_frame=301,loop=90:1:299,setpts=N/FRAME_RATE/TB[1v]; \
        [v2]trim=start_frame=301:end_frame=601,loop=90:1:299,setpts=N/FRAME_RATE/TB[2v]; \
        [v3]trim=start_frame=601:end_frame=900,loop=90:1:298,setpts=N/FRAME_RATE/TB[3v]; \
        aevalsrc=0:d=3[0a]; \
        [0:a]asplit=3[a1][a2][a3]; \
        [a1]atrim=0:10,asetpts=N/SR/TB[1a]; \
        [a2]atrim=10:20,asetpts=N/SR/TB[2a]; \
        [a3]atrim=20:30,asetpts=N/SR/TB[3a]; \
        [0v][0a][1v][1a][2v][2a][3v][3a]concat=n=4:v=1:a=1[v][a]" \
       -map "[v]" -map "[a]" outva.mp4

This can be done, using a daisychained loop filter.

ffmpeg -i input.mp4 \
      -vf loop=90:1:0,setpts=N/FRAME_RATE/TB, \
          loop=90:1:390,setpts=N/FRAME_RATE/TB, \
          loop=90:1:780,setpts=N/FRAME_RATE/TB, \
          loop=90:1:1169,setpts=N/FRAME_RATE/TB
stuttered.mp4

The command above is for a 30 fps video. Each loop filter sets loop to 90 frames i.e. 3 seconds at 30 fps with a 1-frame segment to be looped. The third argument is the frame index that has to be looped. The index for all loop filters after the first, have to be offset since their input feed contains earlier loops inserted e.g. the 2nd loop at 10 seconds would normally be 300 for a 30 fps video, but since the very first has been looped for 3 seconds, it is 3x30 + 10x30 = 390.

The setpts generates a monotonic set of new timestamps after each loop, since otherwise the command doesn't work correctly.

Audio has been completely ignored.

Solution 2

I created a Python script that does that: https://github.com/slhck/bufferer — you can install it with

pip install bufferer

Then:

bufferer -i input.mp4 -b "[10,3],[20,3],[30,3]" -o output.avi

This will add a "rebuffering" indicator to the command – like a spinner that indicates the pause. It will insert the pauses you specified, i.e., for three seconds at 10, 20 and 30 seconds of the original clip. It will output lossless video with FFV1 encoding and PCM audio, but this can be changed. See the README for more info.

I am planning to add a feature to disable that rebuffering indicator, as you may just want a simple pause. In the meantime you can use the --dry-run switch to just print the command and use that as a starting point for some manual changes.

Share:
5,105

Related videos on Youtube

Franky
Author by

Franky

Updated on September 18, 2022

Comments

  • Franky
    Franky over 1 year

    Is there a way to use ffmpeg to halt a video for 3 seconds every 10 seconds?

    For example, I use a 30 seconds video, the video should stop at 0:00, 0:10, 0:20 and 0:30 for 3 seconds. The length of the output video is 0:42 seconds.

    Thank you!

  • Franky
    Franky about 8 years
    Woow!! Thank you, genius!! :))) And what about the audio, is it possible to loop the audio too or to split the whole original-stream in parts and put them at the right positions again?
  • Franky
    Franky about 8 years
    One other point: is it possible to do a exact pause? For the moment, the video is pausing three seconds, thats correct. But the "loop" is overlapping the next three seconds of the video, so we loose the three seconds while the picture is freezing.
  • Gyan
    Gyan about 8 years
    I'll provide a new command tomorrow, taking care of the audio and the overlapping.
  • Franky
    Franky almost 8 years
    Thanks a lot @Mulvya!! In node I've developed a small app to create these videofilter-file (link). But one last question: for long videos > 30min the first pause-loop is 1 - 1,5min long. Is it possible to reduce this first loop? I can't find the error in the filter..
  • Lea... FFmpeg
    Lea... FFmpeg over 2 years
    Gyan what about long videos?. What about long videos? Is there a way we can use a command that repeats the above operations cyclically until the video ends?