I've got an interesting setup. I have four videos which are all identical in duration, identical frame rate, and have identical PTS timestamps. I wish to stream these four videos to an RTMP server but keep them synchronized so that someone switching between the streams will not jump forward or back in time, but instead pick up right where they left off.
Here's the command I'm currently using:
ffmpeg \
-re -stream_loop -1 -fflags +genpts -i 01.mp4 \
-re -stream_loop -1 -fflags +genpts -i 02.mp4 \
-re -stream_loop -1 -fflags +genpts -i 03.mp4 \
-re -stream_loop -1 -fflags +genpts -i 04.mp4 \
-map 0:v -map 0:a \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/01 \
-map 1:v -map 1:a \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/02 \
-map 2:v -map 2:a \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/03 \
-map 3:v -map 3:a \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/04
This command properly synchronizes the streams and broadcasts all four, however the moment the video ends so does the stream. Due to the -stream_loop -1
I would expect the video to keep looping indefinitely. This is the output to stdout
when the stream dies:
[flv @ 0x2392d40] Failed to update header with correct duration.
[flv @ 0x2392d40] Failed to update header with correct filesize.
[flv @ 0x229b980] Failed to update header with correct duration.
[flv @ 0x229b980] Failed to update header with correct filesize.
[flv @ 0x22f3bc0] Failed to update header with correct duration.
[flv @ 0x22f3bc0] Failed to update header with correct filesize.
[flv @ 0x23a4240] Failed to update header with correct duration.
[flv @ 0x23a4240] Failed to update header with correct filesize.
[libx264 @ 0x25ebd00] frame I:236 Avg QP:29.17 size: 20892
[libx264 @ 0x25ebd00] frame P:5412 Avg QP:32.33 size: 1892
[libx264 @ 0x25ebd00] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x25ebd00] mb P I16..4: 0.2% 0.0% 0.0% P16..4: 18.5% 0.0% 0.0% 0.0% 0.0% skip:81.3%
[libx264 @ 0x25ebd00] final ratefactor: 31.62
[libx264 @ 0x25ebd00] coded y,uvDC,uvAC intra: 68.8% 62.8% 34.6% inter: 8.8% 1.8% 0.0%
[libx264 @ 0x25ebd00] i16 v,h,dc,p: 38% 25% 19% 18%
[libx264 @ 0x25ebd00] i8c dc,h,v,p: 40% 22% 27% 11%
[libx264 @ 0x25ebd00] kb/s:515.11
[libspeex @ 0x2537580] 1 frames left in the queue on closing
[libx264 @ 0x2531d00] frame I:236 Avg QP:31.85 size: 15843
[libx264 @ 0x2531d00] frame P:5412 Avg QP:34.95 size: 2086
[libx264 @ 0x2531d00] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x2531d00] mb P I16..4: 2.8% 0.0% 0.0% P16..4: 37.8% 0.0% 0.0% 0.0% 0.0% skip:59.4%
[libx264 @ 0x2531d00] final ratefactor: 32.38
[libx264 @ 0x2531d00] coded y,uvDC,uvAC intra: 48.4% 40.8% 13.5% inter: 12.1% 4.0% 0.0%
[libx264 @ 0x2531d00] i16 v,h,dc,p: 41% 21% 26% 13%
[libx264 @ 0x2531d00] i8c dc,h,v,p: 48% 20% 24% 8%
[libx264 @ 0x2531d00] kb/s:510.33
[libspeex @ 0x2533080] 1 frames left in the queue on closing
[libx264 @ 0x22da600] frame I:236 Avg QP:26.11 size: 13705
[libx264 @ 0x22da600] frame P:5412 Avg QP:29.17 size: 2185
[libx264 @ 0x22da600] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x22da600] mb P I16..4: 4.5% 0.0% 0.0% P16..4: 35.2% 0.0% 0.0% 0.0% 0.0% skip:60.3%
[libx264 @ 0x22da600] final ratefactor: 28.44
[libx264 @ 0x22da600] coded y,uvDC,uvAC intra: 37.1% 40.1% 10.4% inter: 12.3% 6.2% 0.1%
[libx264 @ 0x22da600] i16 v,h,dc,p: 40% 21% 22% 17%
[libx264 @ 0x22da600] i8c dc,h,v,p: 43% 18% 28% 11%
[libx264 @ 0x22da600] kb/s:511.43
[libspeex @ 0x22db080] 1 frames left in the queue on closing
[libx264 @ 0x22d7a00] frame I:236 Avg QP:30.31 size: 13811
[libx264 @ 0x22d7a00] frame P:5412 Avg QP:33.28 size: 2209
[libx264 @ 0x22d7a00] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x22d7a00] mb P I16..4: 5.4% 0.0% 0.0% P16..4: 37.4% 0.0% 0.0% 0.0% 0.0% skip:57.2%
[libx264 @ 0x22d7a00] final ratefactor: 31.52
[libx264 @ 0x22d7a00] coded y,uvDC,uvAC intra: 37.9% 36.7% 9.5% inter: 11.4% 5.0% 0.1%
[libx264 @ 0x22d7a00] i16 v,h,dc,p: 41% 23% 21% 16%
[libx264 @ 0x22d7a00] i8c dc,h,v,p: 45% 19% 27% 9%
[libx264 @ 0x22d7a00] kb/s:516.78
[libspeex @ 0x22d8d80] 1 frames left in the queue on closing
My FFMPEG version:
$ ffmpeg -version
ffmpeg version N-90065-g8a8d0b3 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.5) 20160609
configuration: --prefix=/home/sbarnett/ffmpeg_build --pkg-config-flags=--static --extra-cflags=-I/home/sbarnett/ffmpeg_build/include --extra-ldflags=-L/home/sbarnett/ffmpeg_build/lib --extra-libs='-lpthread -lm' --bindir=/home/sbarnett/bin --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libspeex --enable-nonfree
libavutil 56. 7.101 / 56. 7.101
libavcodec 58. 11.101 / 58. 11.101
libavformat 58. 9.100 / 58. 9.100
libavdevice 58. 1.100 / 58. 1.100
libavfilter 7. 12.100 / 7. 12.100
libswscale 5. 0.101 / 5. 0.101
libswresample 3. 0.101 / 3. 0.101
libpostproc 55. 0.100 / 55. 0.100
How do I get the video to loop indefinitely? Why is -stream_loop -1
not working?
Following @Gyan's advice, I attempted to use filter_complex
with the movie filter, however I may be doing it incorrectly:
ffmpeg \
-stream_loop -1 \
-re -i 01.mp4 \
-re -i 02.mp4 \
-re -i 03.mp4 \
-re -i 04.mp4 \
-filter_complex \
"movie=01.mp4:loop=0[v1];[v1]setpts=N/FRAME_RATE/TB[v1];
amovie=01.mp4:loop=0[a1];[a1]asetpts=N/SR/TB[a1];
movie=02.mp4:loop=0[v2];[v2]setpts=N/FRAME_RATE/TB[v2];
amovie=02.mp4:loop=0[a2];[a2]asetpts=N/SR/TB[a2];
movie=03.mp4:loop=0[v3];[v3]setpts=N/FRAME_RATE/TB[v3];
amovie=03.mp4:loop=0[a3];[a3]asetpts=N/SR/TB[a3];
movie=04.mp4:loop=0[v4];[v4]setpts=N/FRAME_RATE/TB[v4];
amovie=04.mp4:loop=0[a4];[a4]asetpts=N/SR/TB[a4]" \
-map "[v1]" -map "[a1]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/01 \
-map "[v2]" -map "[a2]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/02 \
-map "[v3]" -map "[a3]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/03 \
-map "[v4]" -map "[a4]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/04
This threw the following error:
[libspeex @ 0x23f4d80] nb_samples (325) != frame_size (320) (avcodec_encode_audio2)
stream_loop isn't yet implemented for multiple inputs; you'll have to use the movie filter.
ffmpeg \
-filter_complex \
"movie=01.mp4:loop=0,setpts=N/FRAME_RATE/TB,realtime[v1];
amovie=01.mp4:loop=0,asetpts=N/SR/TB,arealtime[a1];
movie=02.mp4:loop=0,setpts=N/FRAME_RATE/TB,realtime[v2];
amovie=02.mp4:loop=0,asetpts=N/SR/TB,arealtime[a2];
movie=03.mp4:loop=0,setpts=N/FRAME_RATE/TB,realtime[v3];
amovie=03.mp4:loop=0,asetpts=N/SR/TB,arealtime[a3];
movie=04.mp4:loop=0,setpts=N/FRAME_RATE/TB,realtime[v4];
amovie=04.mp4:loop=0,asetpts=N/SR/TB,arealtime[a4]" \
-map "[v1]" -map "[a1]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/01 \
-map "[v2]" -map "[a2]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/02 \
-map "[v3]" -map "[a3]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/03 \
-map "[v4]" -map "[a4]" \
-c:a speex -ar 16000 -ac 1 \
-c:v libx264 -preset ultrafast \
-b:v 500k -b:a 32k \
-f flv rtmp://output/04