Skip to content

Instantly share code, notes, and snippets.

@iddo
Created March 10, 2021 10:50
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save iddo/a4c03c63c055064a0657d0d36a9f667d to your computer and use it in GitHub Desktop.
Save iddo/a4c03c63c055064a0657d0d36a9f667d to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -e
DEVICE_NUMBER="9"
DEVICE_FILE="/dev/video${DEVICE_NUMBER}"
RTSP_URL="rtsp://username:password@WIFIFCAM:554"
# GitHub: iddo
# https://github.com/umlaeute/v4l2loopback/issues/109#issuecomment-617638198
# This script creates a video loopback device with an
# on-demand RTSP stream connected to it, which allows saving resources when not in use.
# This work is licensed under the Creative Commons Attribution 3.0 Unported License.
# To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/
# or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
function finish {
# Your cleanup code here
if [ -n "${PID}" ]; then # streamer is already running
echo "--- Stopping RTSP streamer"
kill "${PID}" && sleep 2 || true
fi
echo "--- Removing loaded v4l2loopback dkms"
sudo modprobe -r v4l2loopback
}
trap finish EXIT
if [ ! -e "${DEVICE_FILE}" ]; then
echo "--- Loading v4l2loopback with device ${DEVICE_FILE}"
sudo modprobe v4l2loopback exclusive_caps=1 video_nr=${DEVICE_NUMBER} card_label="RTSP Stream"
echo "--- Locking output format"
sudo v4l2-ctl --device "${DEVICE_FILE}" --set-ctrl keep_format=1
ffmpeg -rtsp_transport tcp -i "${RTSP_URL}" -f v4l2 "${DEVICE_FILE}" &
PID="${!}"
echo "--- PID of ffmpeg is '${PID}'"
sleep 5
echo "--- Setting device timeout (blank video if connection is lost)"
sudo v4l2-ctl --device "${DEVICE_FILE}" --set-ctrl timeout=1500
fi
# Trigger usage check in 1 second so that if the camera is not used the streamer will stop
(sleep 1; touch "${DEVICE_FILE}")&
echo "--- Waiting for video device usage"
sudo inotifywait -e OPEN,CLOSE -m "${DEVICE_FILE}" |
while read dir op file; do
if [ -n "${PID}" ]; then # streamer is already running
if [ "$(lsof -t "${DEVICE_FILE}" | grep -v "${PID}" | wc -l)" -eq "0" ]; then # no more clients
echo "--- No more clients, stopping RTSP streamer"
kill "${PID}"
unset PID
fi
elif [ "$(lsof -t "${DEVICE_FILE}" | wc -l)" -gt "0" ]; then # new clients
echo "--- Detected usage of camera, spinning up RTSP streamer"
ffmpeg -rtsp_transport tcp -i "${RTSP_URL}" -vf format=pix_fmts=yuv420p -f v4l2 "${DEVICE_FILE}" &
# TODO add disconnection detection and restart streamer
PID="${!}"
echo "--- PID of ffmpeg is '${PID}'"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment