Camera Power Off Detection

Using ffmpeg to convert a cameras RTMP stream to an HLS stream has one major disadvantage. If the camera is powered off, ffmpeg will patiently wait forever for more data. If the camera is powered back on, ffmpeg will contain to wait for data on the TCP connection it had previously, and which is now unknown to the camera.

It would be much better if ffmpeg exited when the camera was powered off, and then some surrounding script could work out what to do next, such as restart a new copy of ffmpeg when the camera next appears to be on. This behaviour can be achieved with Linux by setting TCP keep-alives on. This enables idle TCP connections and dead TCP connections to be distinguished, after a few tens of seconds.

One could recompile ffmpeg to use TCP keep-alives on its connections. That sounds tedious. But one can also use LD_PRELOAD to wrap the connect call without bothering to recompile. There is a separate page on wrapping to enable TCP keep-alives. With this done, a script such as

#!/bin/bash

[ ! -d /dev/shm/streaming/ptz ] && mkdir -p /dev/shm/streaming/ptz
cd /dev/shm/streaming/ptz

while :
do
    if ping -c 1 192.168.1.80 >/dev/null
    then
        :>status.html
        LD_PRELOAD=/path/to/keep_alive.so ffmpeg [...]
    fi
    echo "Camera not detected" > status.html
    sleep 15
done

should be able to run continuously, and automatically connect to the camera when the camera is on, and disconnect when it is off. It also maintains a brief status file, which, assuming one's webserver supports server side includes, can be included with a statement like

<p style="text-align:center;"><!--#include virtual="./path/status.html" --></p>

It may be neccessary to add to the ffmpeg options, before the first -i,

-rtsp_transport tcp

if using RTSP, or

-rw_timeout 5000000

if using RTMP.