<p>ffmpeg concat demuxer supports nested scripts 
 with the header "<em>ffconcat version 1.0</em>".</p>

<p>Example of endless recursive playlist script "<em>test.txt</em>":</p>

<pre><code>ffconcat version 1.0
file 'video1.mp4'
file 'video2.mp4'
file 'video3.mp4'
file 'test.txt'
</code></pre>

<p>ffmpeg command: </p>

<pre><code>ffmpeg -re -f concat -i ./test.txt  -c copy -f flv rtmp://....
</code></pre>

<p>Note: all file paths must be "safe", 
  because the header "concat version 1.0" also resets the <em>safe</em> option to 1.</p>

CC BY-SA 4.0
2020-04-08T18:28:23.570Z
Beware that probably it's leaking file descriptors.
Nakilon
CC BY-SA 4.0
2019-01-25T21:17:35.080Z
Can you explain what is going on here?
chovy
CC BY-SA 4.0
2019-01-24T20:05:09.590Z
2019-01-26T18:29:03.337Z
2019-01-26T18:29:03.337Z
q_h
<p>Basically I have 4 movies I would like to stream in a continuous loop (ie: like a 24/7 tv channel).</p>

<p>Here is the ./test.txt list of videos:</p>

<pre><code>file 'video1.mp4'
file 'video2.mp4'
file 'videoN.mp4'
</code></pre>

<p>Here is the ffmpeg command:</p>

<pre><code>ffmpeg -re -stream_loop -1 -f concat -safe 0 -i ./test.txt -bsf:v h264_mp4toannexb -c copy ./test.m3u8
</code></pre>

<p>It starts to play the stream and I think it even loops, as the video files are 10 second clips...but then I get an error "Illegal Seek".</p>

<p>Here is the output:</p>

<pre><code>$ ffmpeg -re -stream_loop -1 -f concat -safe 0 -i ./test.txt -bsf:v h264_mp4toannexb -c copy ./test.m3u8
ffmpeg version 3.1.1 Copyright (c) 2000-2016 the FFmpeg developers
  built with Apple LLVM version 7.3.0 (clang-703.0.31)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.1.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --disable-lzma --enable-vda
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 48.101 / 57. 48.101
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 47.100 /  6. 47.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
[matroska,webm @ 0x7f9791809c00] Auto-inserting h264_mp4toannexb bitstream filter
Input #0, concat, from './test.txt':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc
    Metadata:
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:00:10.046000000
    Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      DURATION        : 00:00:10.001000000
[hls @ 0x7f979105a600] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
    Last message repeated 1 times
Output #0, hls, to './test.m3u8':
  Metadata:
    encoder         : Lavf57.41.100
    Stream #0:0: Video: h264, yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc
    Metadata:
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:00:10.046000000
    Stream #0:1(eng): Audio: opus, 48000 Hz, stereo
    Metadata:
      DURATION        : 00:00:10.001000000
Stream mapping:
  Stream #0:0 -&gt; #0:0 (copy)
  Stream #0:1 -&gt; #0:1 (copy)
Press [q] to stop, [?] for help
Error while filtering: Illegal seek time=00:00:09.60 bitrate=N/A speed=   1x
frame=  220 fps= 22 q=-1.0 Lsize=N/A time=00:00:09.98 bitrate=N/A speed=0.998x
video:4821kB audio:152kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
</code></pre>

<p>I'm unclear what I'm doing wrong. I tried with just one <code>file</code> entry in <code>test.txt</code> list of movies and it still chokes.</p>

CC BY-SA 3.0
2016-07-24T07:58:57.537Z
It appears not.
Gyan
CC BY-SA 3.0
2016-07-24T08:36:39.127Z
any ideas how to play multiple movies into one live stream and have it repeat? I suppose I can just copy the entries in the concat file
chovy
CC BY-SA 3.0
2016-07-24T08:44:52.763Z
There's a bug in the execution of stream_loop, so without re-encoding, this doesn't look currently possible. Enlarging the concat text still gives only a finite loop.
Gyan
CC BY-SA 3.0
2016-07-24T10:52:14.323Z
Even large numbers, such as TREE(3) (see https://en.wikipedia.org/wiki/Kruskal%27s_tree_theorem) and SSCG(3) (see https://en.wikipedia.org/wiki/Friedman%E2%80%99s_SSCG_function), are finite.
Michael Tiemann
CC BY-SA 3.0
2016-07-25T04:08:24.943Z
@Mulvya how should I re-encode so `stream_loop` works?
chovy
CC BY-SA 3.0
2016-07-25T04:58:22.450Z
Actually, you can concat once without the stream_loop to a MKV file and then copy that MKV using stream_loop to HLS. This produces a working loop. However, there's a bug with timestamps generation, so there's a timestamp gap at each loop joint. ffplay plays the output correctly without gaps but Potplayer output freezes in that interval before resuming. No idea how HLS clients will behave.
Gyan
CC BY-SA 3.0
2016-07-26T05:29:55.030Z
I think this will fix the time gaps: `-fflags +genpts`
chovy
CC BY-SA 3.0
2018-03-31T23:49:53.110Z
Did you ever figure out how to get this working @chovy ? I am thinking of moving this to a pythonic solution.
Fight Fire With Fire
CC BY-SA 3.0
2018-04-02T00:13:37.250Z
@FightFireWithFire I did not get it working. If you figure it out please come back here and update us!
chovy
<ffmpeg>
Is it possible to create an endless loop using concat?
chovy
# Is it possible to create an endless loop using concat?

(Asked by: username_0 on 2016-07-24)

Basically I have 4 movies I would like to stream in a continuous loop (ie: like a 24/7 tv channel).
Here is the ./test.txt list of videos:
file 'video1.mp4'
file 'video2.mp4'
file 'videoN.mp4'

Here is the ffmpeg command:
ffmpeg -re -stream_loop -1 -f concat -safe 0 -i ./test.txt -bsf:v h264_mp4toannexb -c copy ./test.m3u8

It starts to play the stream and I think it even loops, as the video files are 10 second clips...but then I get an error "Illegal Seek".
Here is the output:
$ ffmpeg -re -stream_loop -1 -f concat -safe 0 -i ./test.txt -bsf:v h264_mp4toannexb -c copy ./test.m3u8
ffmpeg version 3.1.1 Copyright (c) 2000-2016 the FFmpeg developers
  built with Apple LLVM version 7.3.0 (clang-703.0.31)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.1.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --disable-lzma --enable-vda
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 48.101 / 57. 48.101
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 47.100 /  6. 47.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
[matroska,webm @ 0x7f9791809c00] Auto-inserting h264_mp4toannexb bitstream filter
Input #0, concat, from './test.txt':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc
    Metadata:
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:00:10.046000000
    Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      DURATION        : 00:00:10.001000000
[hls @ 0x7f979105a600] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
    Last message repeated 1 times
Output #0, hls, to './test.m3u8':
  Metadata:
    encoder         : Lavf57.41.100
    Stream #0:0: Video: h264, yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc
    Metadata:
      HANDLER_NAME    : VideoHandler
      DURATION        : 00:00:10.046000000
    Stream #0:1(eng): Audio: opus, 48000 Hz, stereo
    Metadata:
      DURATION        : 00:00:10.001000000
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
Error while filtering: Illegal seek time=00:00:09.60 bitrate=N/A speed=   1x
frame=  220 fps= 22 q=-1.0 Lsize=N/A time=00:00:09.98 bitrate=N/A speed=0.998x
video:4821kB audio:152kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

I'm unclear what I'm doing wrong. I tried with just one file entry in test.txt list of movies and it still chokes.

**Tags:** ffmpeg

> **Comments:**
> **username_1**: It appears not.  
> **username_0**: any ideas how to play multiple movies into one live stream and have it repeat? I suppose I can just copy the entries in the concat file  
> **username_1**: There's a bug in the execution of stream_loop, so without re-encoding, this doesn't look currently possible. Enlarging the concat text still gives only a finite loop.  
> **username_2**: Even large numbers, such as TREE(3) (see https://en.wikipedia.org/wiki/Kruskal%27s_tree_theorem) and SSCG(3) (see https://en.wikipedia.org/wiki/Friedman%E2%80%99s_SSCG_function), are finite.  
> **username_0**: @Mulvya how should I re-encode so `stream_loop` works?  
> **username_1**: Actually, you can concat once without the stream_loop to a MKV file and then copy that MKV using stream_loop to HLS. This produces a working loop. However, there's a bug with timestamps generation, so there's a timestamp gap at each loop joint. ffplay plays the output correctly without gaps but Potplayer output freezes in that interval before resuming. No idea how HLS clients will behave.  
> **username_0**: I think this will fix the time gaps: `-fflags +genpts`  
> **username_3**: Did you ever figure out how to get this working @username_0 ? I am thinking of moving this to a pythonic solution.  
> **username_0**: @FightFireWithFire I did not get it working. If you figure it out please come back here and update us!  

---

## 1 answers

### Answer by username_4 on 2019-01-24. Score: 5

ffmpeg concat demuxer supports nested scripts 
 with the header "ffconcat version 1.0".
Example of endless recursive playlist script "test.txt":
ffconcat version 1.0
file 'video1.mp4'
file 'video2.mp4'
file 'video3.mp4'
file 'test.txt'

ffmpeg command: 
ffmpeg -re -f concat -i ./test.txt  -c copy -f flv rtmp://....

Note: all file paths must be "safe", 
  because the header "concat version 1.0" also resets the safe option to 1.

> **Comments:**
> **username_0**: Can you explain what is going on here?  
> **username_5**: Beware that probably it's leaking file descriptors.  

---

