Repeat/loop Input Video with ffmpeg?

  • I just want to loop a mp4 video with ffmpeg and keep the current settings and codec.

    For example if input.mp4 is 0:10 long, and I would want to loop it 4 times so output.mp4 is 0:40 long, how could I change the following command line to do that?

    ffmpeg -i input.mp4 -c copy output.mp4
    

    I tried...

    ffmpeg -loop 4 -i input.mp4 -c copy output.mp4
    

    ...but I get the error "Option loop not found."

    Use quicktime 7 pro and mov container. So you won't get a bigger file size, than with opensource one.

  • llogan

    llogan Correct answer

    6 years ago

    Concat demuxer

    This allows you to loop an input without needing to re-encode.

    1. Make a text file. Contents of an example text file to repeat 4 times.

      file 'input.mp4'
      file 'input.mp4'
      file 'input.mp4'
      file 'input.mp4'
      
    2. Then run ffmpeg:

      ffmpeg -f concat -i list.txt -c copy output.mp4
      

    For Linux users

    This example is the same as above but you don't have to manually make list.txt:

    for i in {1..4}; do printf "file '%s'\n" input.mp4 >> list.txt; done
    ffmpeg -f concat -i list.txt -c copy output.mp4
    

    With most commonly-used modern shells, you can even avoid the creation of the list.txt file entirely. For example, with bash:

    ffmpeg -f concat -i <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -c copy output.mp4
    

    Also see:


    loop filter

    Example using the loop filter to loop 4 times, each loop is 75 frames, each loop skips the first 25 frames of the input:

    ffmpeg -i input -filter_complex loop=loop=3:size=75:start=25 output
    
    • Or use the shorthand: loop=3:75:25
    • Filtering requires re-encoding.
    • This filter places all frames into memory.
    • Using loop=3 will loop 4 times.
    • To loop infinitely use -1.
    • You must list the number of frames to loop (shown as 75 in the example above). Max value is 32767.
    • Also see ffmpeg -h filter=loop.

    movie filter

    The movie filter has a loop option. See answer below by Monah Tuk. Filtering requires re-encoding. For audio use the amovie filter.


    -stream_loop option

    See answer below by Thingy and answer by Gyan.

    Note that this option was buggy (see bug reports #5719, #6121, and #7043) so may not work for old builds (anything older than 2018 06-27 including the FFmpeg 4.0.x release branch). For users of old builds, as mentioned by mulvya in ticket #6121, one workaround is to first re-mux to MKV or TS then use -stream_loop in the next command.


    -loop option

    The -loop option is specific to the image file demuxer and gif muxer, so it can't be used for typical video files, but it can be used to infinitely loop a series of input images. This example will loop over and over but the -t 30 will limit the output duration to 30 seconds:

    ffmpeg -loop 1 -i %03d.png -t 30 output.mkv
    

    Or to loop a GIF output:

    ffmpeg -i input -loop 3 output.gif
    

    Does this work fine with mp4 files?

    I get this error `> <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -bash: /dev/fd/63: Permission denied`

    @jamesfzhang - I think that's because you need an absolute path to the file (as explained here: https://trac.ffmpeg.org/wiki/Concatenate). To fulfill that, you could write: ffmpeg -safe 0 -f concat -i <(for i in {1..4}; do printf "file '$PWD'/'%s'\n" input.mp4; done) -c copy output.mp4

    As for me this works to repeat **full time** video without skipping fames for 4 times `ffmpeg -i video.mp4 -filter_complex "loop=4:32767" output.mp4`

    This issue is 4 years old and noone noticed that the link to the second issue in the `-stream_loop` section is pointing to the same ticket as the first one...

    When working on images, is there any difference between `-i %03d.png -t 30` and `-t 30 -i %03d.png`? I know that when working on video, you usually want `-t` (and `-ss`) before the input to save on decode time, but does this matter for images? I've recently run some commands with `-t` before the input and it worked fine.

    @DigiVisionMedia Shouldn't make a difference.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM