I couldn't get it to work with pure ffmpeg
in a reasonable amount of time but the nginx-rtmp module worked out of the box.
It's basically apt install libnginx-mod-rtmp nginx
, add ..
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
# Only localhost is allowed to publish
allow publish 127.0.0.1;
deny publish all;
}
}
}
.. to nginx.conf, systemctl restart nginx
and nginx
acts as a local loop-back device on rtmp://localhost/live
.
If you now have n streams to multiplex, you can create n systemd services camera_i.service
[Unit]
Description=Send stream i to local nginx loopback device
# List all other
Conflicts=camera_1.service, camera_2.service, [...]
[Service]
ExecStart=/usr/bin/ffmpeg -i rtsp://mystreamurl_i -c copy -f flv rtmp://localhost/live
Type=simple
Restart=on-failure
KillSignal=SIGINT
SuccessExitStatus=255
[Install]
WantedBy=xsession.target
and switch to stream i by starting camera_i.service
:
systemctl --user start camera_i.service
All other services listed on the Conflicts=
option are automatically being terminated by systemd, effectively multiplexing the camera streams.
The resulting stream can then be recorder used using something like the following:
/usr/bin/ffmpeg \
[...]
-use_wallclock_as_timestamps 1 \
-fflags +genpts \
-i "rtmp://localhost/live" \
[...]
-itsoffset $AUDIOVIDEOOFFSET \
-f pulse \
-i default \
[...]
-vcodec copy \
-map 0:v -map 1:a \
[...]
OUTPUT
The result is a rather smooth flip with continuous audio.
-use_wallclock_as_timestamps 1 -fflags +genpts
might be unnecessary if you don't use -vsync 0
. But I haven't tested that yet.
Appendix
As has been proposed on the ffmpeg mailing-list, there is the zmq
filter that supposedly can change filters settings on-the-fly.
The idea is to overlay two streams and toggle the opacity of the top stream, effectively switching stream.
I couldn't get it to work but for anyone to try:
# compiled with --enable-libzmq
ffmpeg -i INPUT -filter_complex 'null[main];movie=INPUT2,zmq,lumakey@toggle=tolerance=1,[main]overlay,realtime' OUTPUT
echo lumakey@toggle tolerance 0 | zmqsend
where zmqsend
results from:
git clone https://github.com/FFmpeg/FFmpeg
cd FFmpeg/
./configure
cd tools/
gcc zmqsend.c -o zmqsend -I.. `pkg-config --libs --cflags libzmq libavutil`