user6693: 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."

user12104: At least on FFmpeg 2.8.x (but oldie should works too) you can use lavfi as input format and complex filter graph using movie and setpts filters as a argument for -i option.
Next command doing this work for you:
ffmpeg -re -f lavfi -i "movie=filename=input.mp4:loop=0, setpts=N/(FRAME_RATE*TB)" output.mp4

Zero loop= arguments means infinity loop. Values greater zero sets repeat counts. setpts filters required for PTS adjusting for second and later repeats, otherwise most output muxers will fails with non-monotonic PTS increasing: loop does not recalc PTS.
Note, that using filters assuming that bypass frames without decoding/encoding is impossible: by design filters deals with decoded frames only.
At the FFmpeg 2.8.2 new input option -stream_loop inroduced. I first look it works more simple and allows copy content without transcoding:
ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -y output.mp4

But it does not recalculate PTS and output file is wrong. If you add filter to fix PTS (see setpts) you must remove -c copy too. Only bitstream filters can deals with encoded packets, but there is no any bitstream filters to fix PTS (see: https://ffmpeg.org/ffmpeg-bitstream-filters.html)
In any case ffmpeg on second pass fails with error:
input.mp4: Resource temporarily unavailable

Known work around for me: use container for input file without PTS limits (streaming container). One of them, known me, is MPEG-TS. So, you can simple convert your MP4 file to the MPEG-TS:
ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input.ts

And use next command to compose infinity file:
ffmpeg -re -stream_loop -1 -i input.ts -c copy -strict -2 -bsf:a aac_adtstoasc -y output.mp4

(bitstream filters should be used only if needed, on my samples it is required)
FFmpeg >= 2.8.2 is required in this case.

user12531: With ffmpeg 2.8.4, the following command creates output.mp4 that is a repeating copy of input.mp4 until the ffmpeg process is stopped:
ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4

This command won't terminate on its own, and the output file will grow infinitely.

user1760: -stream_loop option
ffmpeg -stream_loop 3 -i input.mp4 -c copy output.mp4


This can avoid re-encoding because it can use stream copy.
0 means no loop, -1 means infinite loop.
This may not work with anything older than FFmpeg 4.0.


concat demuxer
The concat demuxer allows you to loop an input without needing to re-encode because it can use stream copy.

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'


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



If you want to add additional inputs make sure they all have the same attributes.
Automatically make list.txt in Linux/macOS
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:

FFmpeg concat demuxer documentation
FFmpeg Wiki: Concatenate


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.mp4 -filter_complex "loop=loop=3:size=75:start=25" output.mp4


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 and amovie filters have a loop option:
ffmpeg -f lavfi -i "movie=filename=input.mp4:loop=4,setpts=N/FRAME_RATE/TB" -f lavfi -i "amovie=filename=input.mp4:loop=4,asetpts=N/SR/TB" output.mp4


Filtering requires re-encoding.
1 means no loop, 0 means infinite loop.


-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 single image or a series of images.
single image
This example will loop a single image over and over but the -t 30 will limit the output duration to 30 seconds:
ffmpeg -loop 1 -i input.png -t 30 -vf format=yuv420p output.mp4

-vf format=yuv420p is for compatibility reasons.
series of images
ffmpeg -loop 1 -i %03d.jpg -t 30 -vf format=yuv420p output.mp4

GIF output
Or to loop a GIF:
ffmpeg -i input -loop 3 output.gif

For GIF output also see How do I convert a video to GIF using ffmpeg, with reasonable quality?

6693: <p>I just want to loop a mp4 video with ffmpeg and keep the current settings and codec.</p>

<p>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?</p>

<pre><code>ffmpeg -i input.mp4 -c copy output.mp4
</code></pre>

<p>I tried...</p>

<pre><code>ffmpeg -loop 4 -i input.mp4 -c copy output.mp4
</code></pre>

<p>...but I get the error "Option loop not found."</p>
 12104: <p>At least on FFmpeg 2.8.x (but oldie should works too) you can use <code>lavfi</code> as input format and complex filter graph using <code>movie</code> and <code>setpts</code> filters as a argument for <code>-i</code> option.</p>

<p>Next command doing this work for you:</p>

<pre><code>ffmpeg -re -f lavfi -i "movie=filename=input.mp4:loop=0, setpts=N/(FRAME_RATE*TB)" output.mp4
</code></pre>

<p>Zero <code>loop=</code> arguments means infinity loop. Values greater zero sets repeat counts. <code>setpts</code> filters required for PTS adjusting for second and later repeats, otherwise most output muxers will fails with non-monotonic PTS increasing: loop does not recalc PTS.</p>

<p><strong>Note, that using filters assuming that bypass frames without decoding/encoding is impossible: by design filters deals with decoded frames only.</strong></p>

<p>At the FFmpeg 2.8.2 new input option <code>-stream_loop</code> inroduced. I first look it works more simple and allows copy content without transcoding:</p>

<pre><code>ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -y output.mp4
</code></pre>

<p>But it does not recalculate PTS and output file is wrong. If you add filter to fix PTS (see <code>setpts</code>) you must remove <code>-c copy</code> too. Only bitstream filters can deals with encoded packets, but there is no any bitstream filters to fix PTS (see: <a href="https://ffmpeg.org/ffmpeg-bitstream-filters.html">https://ffmpeg.org/ffmpeg-bitstream-filters.html</a>)</p>

<p>In any case ffmpeg on second pass fails with error:</p>

<pre><code>input.mp4: Resource temporarily unavailable
</code></pre>

<p><strong>Known work around for me</strong>: use container for input file without PTS limits (streaming container). One of them, known me, is MPEG-TS. So, you can simple convert your MP4 file to the MPEG-TS:</p>

<pre><code>ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input.ts
</code></pre>

<p>And use next command to compose infinity file:</p>

<pre><code>ffmpeg -re -stream_loop -1 -i input.ts -c copy -strict -2 -bsf:a aac_adtstoasc -y output.mp4
</code></pre>

<p>(bitstream filters should be used only if needed, on my samples it is required)</p>

<p>FFmpeg >= 2.8.2 is required in this case.</p>
 12531: <p>With ffmpeg 2.8.4, the following command creates output.mp4 that is a repeating copy of input.mp4 until the ffmpeg process is stopped:</p>

<pre><code>ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4
</code></pre>

<p>This command won't terminate on its own, and the output file will grow infinitely.</p>
 1760: <h1><code>-stream_loop</code> option</h1>
<pre><code>ffmpeg -stream_loop 3 -i input.mp4 -c copy output.mp4
</code></pre>
<ul>
<li>This can avoid re-encoding because it can use <a href="https://ffmpeg.org/ffmpeg.html#Stream-copy" rel="noreferrer">stream copy</a>.</li>
<li><code>0</code> means no loop, <code>-1</code> means infinite loop.</li>
<li>This may not work with anything older than FFmpeg 4.0.</li>
</ul>
<hr />
<h1>concat demuxer</h1>
<p>The <a href="https://ffmpeg.org/ffmpeg-formats.html#concat" rel="noreferrer">concat demuxer</a> allows you to loop an input without needing to re-encode because it can use <a href="https://ffmpeg.org/ffmpeg.html#Stream-copy" rel="noreferrer">stream copy</a>.</p>
<ol>
<li><p>Make a text file. Contents of an example text file to repeat 4 times.</p>
<pre><code> file 'input.mp4'
 file 'input.mp4'
 file 'input.mp4'
 file 'input.mp4'
</code></pre>
</li>
<li><p>Then run <code>ffmpeg</code>:</p>
<pre><code> ffmpeg -f concat -i list.txt -c copy output.mp4
</code></pre>
</li>
</ol>
<p>If you want to add additional inputs make sure they all have the same attributes.</p>
<h3>Automatically make <code>list.txt</code> in Linux/macOS</h3>
<p>This example is the same as above but you don't have to manually make <code>list.txt</code>:</p>
<pre><code>for i in {1..4}; do printf &quot;file '%s'\n&quot; input.mp4 &gt;&gt; list.txt; done
ffmpeg -f concat -i list.txt -c copy output.mp4
</code></pre>
<p>With most commonly-used modern shells, you can even avoid the creation of the <code>list.txt</code> file entirely. For example, with bash:</p>
<pre><code>ffmpeg -f concat -i &lt;(for i in {1..4}; do printf &quot;file '%s'\n&quot; input.mp4; done) -c copy output.mp4
</code></pre>
<h3>Also see:</h3>
<ul>
<li><a href="https://ffmpeg.org/ffmpeg-formats.html#concat" rel="noreferrer">FFmpeg concat demuxer documentation</a></li>
<li><a href="https://trac.ffmpeg.org/wiki/Concatenate" rel="noreferrer">FFmpeg Wiki: Concatenate</a></li>
</ul>
<hr />
<h1>loop filter</h1>
<p>Example using the <a href="https://ffmpeg.org/ffmpeg-filters.html#loop" rel="noreferrer">loop filter</a> to loop 4 times, each loop is 75 frames, each loop skips the first 25 frames of the input:</p>
<pre><code>ffmpeg -i input.mp4 -filter_complex &quot;loop=loop=3:size=75:start=25&quot; output.mp4
</code></pre>
<ul>
<li>Or use the shorthand: <code>loop=3:75:25</code></li>
<li>Filtering requires re-encoding.</li>
<li>This filter <a href="https://ffmpeg.org/ffmpeg-filters.html#movie" rel="noreferrer">places all frames into memory</a>.</li>
<li>Using <code>loop=3</code> will loop 4 times.</li>
<li>To loop infinitely use <code>-1</code>.</li>
<li>You must list the number of frames to loop (shown as 75 in the example above). Max value is 32767.</li>
<li>Also see <code>ffmpeg -h filter=loop</code>.</li>
</ul>
<hr />
<h1>movie filter</h1>
<p>The <a href="https://ffmpeg.org/ffmpeg-filters.html#movie" rel="noreferrer">movie</a> and amovie filters have a loop option:</p>
<pre><code>ffmpeg -f lavfi -i &quot;movie=filename=input.mp4:loop=4,setpts=N/FRAME_RATE/TB&quot; -f lavfi -i &quot;amovie=filename=input.mp4:loop=4,asetpts=N/SR/TB&quot; output.mp4
</code></pre>
<ul>
<li>Filtering requires re-encoding.</li>
<li><code>1</code> means no loop, <code>0</code> means infinite loop.</li>
</ul>
<hr />
<h1><code>-loop</code> option</h1>
<p>The <code>-loop</code> option is specific to the <a href="https://ffmpeg.org/ffmpeg-formats.html#image2-1" rel="noreferrer">image file demuxer</a> and <a href="https://ffmpeg.org/ffmpeg-formats.html#gif-2" rel="noreferrer">gif muxer</a>, so it can't be used for typical video files. But it can be used to infinitely loop a single image or a series of images.</p>
<h3>single image</h3>
<p>This example will loop a single image over and over but the <code>-t 30</code> will limit the output duration to 30 seconds:</p>
<pre><code>ffmpeg -loop 1 -i input.png -t 30 -vf format=yuv420p output.mp4
</code></pre>
<p><code>-vf format=yuv420p</code> is for compatibility reasons.</p>
<h3>series of images</h3>
<pre><code>ffmpeg -loop 1 -i %03d.jpg -t 30 -vf format=yuv420p output.mp4
</code></pre>
<h3>GIF output</h3>
<p>Or to loop a GIF:</p>
<pre><code>ffmpeg -i input -loop 3 output.gif
</code></pre>
<p>For GIF output also see <a href="https://superuser.com/a/556031/">How do I convert a video to GIF using ffmpeg, with reasonable quality?</a></p>
