Hier eine Lösung für das Aufzeichnen von Realtime Streams. Entworfen für IP-Cams mit rtsp Protokoll, getestet mit Abus TVIP11000, aber Grundstrucktur auch für jede Art von Streams brauchbar. Hintergrund mal wieder, IP-Cams bringen meines erachtens unbrauchbare, zu fette Software mit und dann brauchen sie auch noch ein Desktop. Das Script benötigt absolut keinen Desktop und läuft, wenn korrekt eingestellt, voll automatisch.
Da es noch in der Entwicklung ist, vermute ich noch den einen oder anderen Bug, aber ich arbeite daran. Eine genauere Beschreibung folgt ebenfalls.
Systemabhängigkeiten: vlc >=2.2.0, livemedia-utils (openRTSP) >=2014.01.13-1 [ $ apt-get install vlc livemedia-utils ]
Kein Desktop nötig!
Startparameter: -d für Debug
Das Script sollte mit & im Hintergrund gestartet werden. Z.B. $ ./script.bsh &
Im Debug empfehle ich das nicht zu tun, damit ihr den stdout auf der aktuellen Konsole bekommt. Im Debug Modus wird ebenfalls VLC im Verbose Modus gestartet und ein Logfile unter ./LOG/$DATUM_vlc_debug.log angelegt.
Aktualisiert von 20150927 auf 20151002
#!/bin/bash
# Catch all switches
DEBUG="${@}";
# Set VLC to be quiet
VLC_DEBUG="--quiet"
# Set a fake PID for ${CAM_PID} at startup
CAM_PID="00000";
# Simply the Script-Version for LogHeader
VERSION="v20151002_01";
# Set ${FIRST_START} for LOAD_CFG. It's a switch for "Loading Config-File" and "Reloading Config"
FIRST_START=1;
# A Switch to prevent doubleposts in Logfile "Camera-Action "START" was initiated."
START_RECORD=1;
# A Switch to indicate "this is the first start" and i've to test, that i can record video from cam.
# In runtime the switch will set back to 1 if config has change, to test the new settings.
TEST_RECORD=1;
# Text
NEW_PID_SET=1;
# Main-Function
MAIN() {
# Write Script-Header to Logfile
TEXT="#########################################################";
LOGINFO="INFO";
LOG;
TEXT="# Script ${0} started. Version ${VERSION} #";
LOGINFO="INFO";
LOG;
TEXT="#########################################################";
LOGINFO="INFO";
LOG;
# Looking for a record.pid at startup. Delete them.
if [ -f record.pid ]; then
rm record.pid;
fi
# Manage all switches. If -d is set, the Script and VLC will start in verbose-mode. All other switches will be ignored!
if [ ! -z "${DEBUG}" ]; then
case "${DEBUG}" in
'-d') set -xo;
VLC_DEBUG="--file-logging --verbose 2 --logmode text --logfile LOG/$(date '+%Y-%m-%d')_vlc_debug.log";
TEXT="Script security-cam.bsh started with Debug-Mod. \"set -xo\"";
LOGINFO="INFO";
LOG;
;;
*) TEXT="Unknown Command. \"${DEBUG}\"";
LOGINFO="WARN";
LOG;
;;
esac
fi
# Executing LOAD_CFG
LOAD_CFG;
# Executing ENVIRONMENT
ENVIRONMENT;
# Executing RECORD_DIR
TEXT="Checking Record-Directory.";
LOGINFO="INFO";
LOG;
RECORD_DIR;
# Executing CHECK_DISK_SPACE
TEXT="Calculating available Disk-Space.";
LOGINFO="INFO";
LOG;
CHECK_DISK_SPACE;
# Executing CHECK_RECORD_SPACE
TEXT="Checking Record-Space.";
LOGINFO="INFO";
LOG;
CHECK_RECORD_SPACE;
# Executing CHECK_CAM
TEXT="Checking Camera is available.";
LOGINFO="INFO";
LOG;
CHECK_CAM;
# Executing RECORD
TEXT="Starting into Camera-Action modus.";
LOGINFO="INFO";
LOG;
RECORD;
}
# Function to load the camera.conf
# The function will grep all needed information from camera.conf
# Is ${FIRST_START} equal 1 LOAD_CFG will only grep settings,
# on 0 the function will executing ENVIRONMENT, RECORD_DIR, CHECK_DISK_SPACE and CHECK_RECORD_SPACE
# again to check the reloaded camera.conf
LOAD_CFG() {
if [ "${FIRST_START}" -eq 1 ]; then
TEXT="Loading Config-File.";
LOGINFO="INFO";
LOG;
if [ -f camera.conf ]; then
CONFIG_CHANGE=$(md5sum camera.conf | awk '{ print $1 }');
CAM_IP="$(grep ^CAM_IP camera.conf | awk -F \" '{ print $2 }')";
if [ -n "${CAM_IP}" ]; then
TEXT="Camera IP is ${CAM_IP}.";
LOGINFO="INFO";
LOG;
VALIDATE_CAM_IP;
else
TEXT="No IP-Address set for Camera.";
LOGINFO="CRIT";
LOG;
fi
CAM_PORT="$(grep ^CAM_PORT camera.conf | awk -F \" '{ print $2 }')";
if [ -n "${CAM_PORT}" ]; then
TEXT="Camera Port is ${CAM_PORT}.";
LOGINFO="INFO";
LOG;
VALIDATE_CAM_PORT;
else
TEXT="No Port is set for Camera.";
LOGINFO="CRIT";
LOG;
fi
CAM_USERNAME="$(grep ^CAM_USERNAME camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Username is ${CAM_USERNAME}.";
LOGINFO="INFO";
LOG;
CAM_PASSWORD="$(grep ^CAM_PASSWORD camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Password is ${CAM_PASSWORD}.";
LOGINFO="INFO";
LOG;
CAM_STREAM_PATH="$(grep ^CAM_STREAM_PATH camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Stream-Path is ${CAM_STREAM_PATH}.";
LOGINFO="INFO";
LOG;
RECORD_PATH="$(grep ^RECORD_PATH camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Record-Directory is "${RECORD_PATH}".";
LOGINFO="INFO";
LOG;
RECORD_SAVE_SUFFIX="$(grep ^RECORD_SAVE_SUFFIX camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Record-Suffix is ${RECORD_SAVE_SUFFIX}.";
LOGINFO="INFO";
LOG;
RECORD_MAX_SPACE_USE="$(grep ^RECORD_MAX_SPACE_USE camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Max-Space-Use is ${RECORD_MAX_SPACE_USE}.";
LOGINFO="INFO";
LOG;
RECORD_MAX_SPACE_VALUE="$(grep ^RECORD_MAX_SPACE_VALUE camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Max-Space-Value is ${RECORD_MAX_SPACE_VALUE}.";
LOGINFO="INFO";
LOG;
RECORD_VIDEO_SPLIT_TIME="$(grep ^RECORD_VIDEO_SPLIT_TIME camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Record-Split-Time is ${RECORD_VIDEO_SPLIT_TIME} Seconds.";
LOGINFO="INFO";
LOG;
FIRST_START=0
else
TEXT="No Config-File found.";
LOGINFO="CRIT";
LOG;
fi
else
if [ $(md5sum camera.conf | awk '{ print $1 }') != ${CONFIG_CHANGE} ]; then
CONFIG_CHANGE=$(md5sum camera.conf | awk '{ print $1 }');
TEXT="Reloading Config-File.";
LOGINFO="INFO";
LOG;
if [ "$(echo "${CAM_IP}")" != "$(echo "$(grep ^CAM_IP camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_CAM_IP="$(echo ${CAM_IP})";
CAM_IP="$(grep ^CAM_IP camera.conf | awk -F \" '{ print $2 }')";
if [ -n "${CAM_IP}" ]; then
TEST_RECORD=1;
TEXT="Camera IP has change from ${OLD_CAM_IP} to ${CAM_IP}.";
LOGINFO="INFO";
LOG;
VALIDATE_CAM_IP;
else
TEXT="No IP-Address set for Camera.";
LOGINFO="CRIT";
LOG;
fi
fi
if [ "$(echo "${CAM_PORT}")" != "$(echo "$(grep ^CAM_PORT camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_CAM_PORT="$(echo ${CAM_PORT})";
CAM_PORT="$(grep ^CAM_PORT camera.conf | awk -F \" '{ print $2 }')";
if [ -n "${CAM_PORT}" ]; then
TEST_RECORD=1;
TEXT="Camera Port has change from ${OLD_CAM_PORT} to ${CAM_PORT}.";
LOGINFO="INFO";
LOG;
VALIDATE_CAM_PORT;
else
TEXT="No Port is set for Camera.";
LOGINFO="CRIT";
LOG;
fi
fi
if [ "$(echo "${CAM_USERNAME}")" != "$(echo "$(grep ^CAM_USERNAME camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_CAM_USERNAME="$(echo ${CAM_USERNAME})";
CAM_USERNAME="$(grep ^CAM_USERNAME camera.conf | awk -F \" '{ print $2 }')";
TEST_RECORD=1;
TEXT="Camera Username has change from ${OLD_CAM_USERNAME} to ${CAM_USERNAME}.";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${CAM_PASSWORD}")" != "$(echo "$(grep ^CAM_PASSWORD camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_CAM_PASSWORD="$(echo ${CAM_PASSWORD})";
CAM_PASSWORD="$(grep ^CAM_PASSWORD camera.conf | awk -F \" '{ print $2 }')";
TEST_RECORD=1;
TEXT="Camera Password has change from ${OLD_CAM_PASSWORD} to ${CAM_PASSWORD}.";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${CAM_STREAM_PATH}")" != "$(echo "$(grep ^CAM_STREAM_PATH camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_CAM_STREAM_PATH="$(echo ${CAM_STREAM_PATH})";
CAM_STREAM_PATH="$(grep ^CAM_STREAM_PATH camera.conf | awk -F \" '{ print $2 }')";
TEST_RECORD=1;
TEXT="Camera Stream-Path has change from ${OLD_CAM_STREAM_PATH} to ${CAM_STREAM_PATH}.";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${RECORD_PATH}")" != "$(echo "$(grep ^RECORD_PATH camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_RECORD_PATH="$(echo ${RECORD_PATH})";
RECORD_PATH="$(grep ^RECORD_PATH camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Record-Directory has change from "${OLD_RECORD_PATH}" to "${RECORD_PATH}".";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${RECORD_SAVE_SUFFIX}")" != "$(echo "$(grep ^RECORD_SAVE_SUFFIX camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_RECORD_SAVE_SUFFIX="$(echo ${RECORD_SAVE_SUFFIX})";
RECORD_SAVE_SUFFIX="$(grep ^RECORD_SAVE_SUFFIX camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Record-Suffix has change from ${OLD_RECORD_SAVE_SUFFIX} to ${RECORD_SAVE_SUFFIX}.";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${RECORD_MAX_SPACE_USE}")" != "$(echo "$(grep ^RECORD_MAX_SPACE_USE camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_RECORD_MAX_SPACE_USE="$(echo ${RECORD_MAX_SPACE_USE})";
RECORD_MAX_SPACE_USE="$(grep ^RECORD_MAX_SPACE_USE camera.conf | awk -F \" '{ print $2 }')";
OLD_VALUE="$(echo ${RECORD_MAX_SPACE_VALUE})";
NEW_VALUE="$(grep ^RECORD_MAX_SPACE_VALUE camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Max-Space-Use has change from ${OLD_RECORD_MAX_SPACE_USE}${OLD_VALUE} to ${RECORD_MAX_SPACE_USE}${NEW_VALUE}.";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${RECORD_MAX_SPACE_VALUE}")" != "$(echo "$(grep ^RECORD_MAX_SPACE_VALUE camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_RECORD_MAX_SPACE_VALUE="$(echo ${RECORD_MAX_SPACE_VALUE})";
RECORD_MAX_SPACE_VALUE="$(grep ^RECORD_MAX_SPACE_VALUE camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Max-Space-Value has change from ${OLD_RECORD_MAX_SPACE_VALUE} to ${RECORD_MAX_SPACE_VALUE}.";
LOGINFO="INFO";
LOG;
fi
if [ "$(echo "${RECORD_VIDEO_SPLIT_TIME}")" != "$(echo "$(grep ^RECORD_VIDEO_SPLIT_TIME camera.conf | awk -F \" '{ print $2 }')")" ]; then
OLD_RECORD_VIDEO_SPLIT_TIME="$(echo ${RECORD_VIDEO_SPLIT_TIME})";
RECORD_VIDEO_SPLIT_TIME="$(grep ^RECORD_VIDEO_SPLIT_TIME camera.conf | awk -F \" '{ print $2 }')";
TEXT="Camera Record-Split-Time has change from ${OLD_RECORD_VIDEO_SPLIT_TIME} to ${RECORD_VIDEO_SPLIT_TIME} Seconds.";
LOGINFO="INFO";
LOG;
fi
ENVIRONMENT;
RECORD_DIR;
CHECK_DISK_SPACE;
CHECK_RECORD_SPACE;
fi
fi
}
# Function ENVIRONMENT check the general "variables are filled and "paths are reachable and writeable"
# When all variables are valid, it combine the settings to ${CAM_FULL_PATH}
# The function will also check, how is executing the script. Root is not allowd to execute the script.
ENVIRONMENT() {
TEXT="Checking Environment.";
LOGINFO="INFO";
LOG;
if [ ${UID} -eq 0 ]; then
TEXT="This Programm should be never run as root.";
LOGINFO="CRIT";
LOG;
fi
for CHECK_VAR in "${CAM_USERNAME}" "${CAM_PASSWORD}" "${CAM_STREAM_PATH}" "${RECORD_PATH}" "${RECORD_MAX_SPACE_USE}" "${RECORD_MAX_SPACE_VALUE}" "${RECORD_VIDEO_SPLIT_TIME}"
do
if [ -z "${CHECK_VAR}" ]; then
TEXT="This Programm can't be run without all variables are set.";
LOGINFO="CRIT";
LOG;
fi
done
if [ ! -d "${RECORD_PATH}" ]; then
TEXT="Record-Directory does'nt exist or is not reachable.";
LOGINFO="CRIT";
LOG;
else
if [ $(echo "Recordtestfile" > ${RECORD_PATH}testfile.txt 2>&1; echo ${?}) -gt 0 ]; then
TEXT="Can't write in Record-Directory.";
LOGINFO="CRIT";
LOG;
else
rm ${RECORD_PATH}testfile.txt;
fi
fi
# do not edit this line on your own!
CAM_FULL_PATH="${CAM_USERNAME}:${CAM_PASSWORD}@${CAM_IP}:${CAM_PORT}${CAM_STREAM_PATH}";
}
RECORD_DIR() {
OLD_RECORD_DIRECTORY="$(echo "${RECORD_DIRECTORY}")";
RECORD_DIRECTORY=$(date +"%Y-%m-%d");
if [ ! -z "${OLD_RECORD_DIRECTORY}" ]; then
if [ "$(echo "${OLD_RECORD_DIRECTORY}")" != "$(echo "${RECORD_DIRECTORY}")" ]; then
TEXT="Record-Directory has change from "${OLD_RECORD_DIRECTORY}" to "${RECORD_DIRECTORY}"";
LOGINFO="INFO";
LOG;
fi
fi
if [ ! -d ${RECORD_PATH}${RECORD_DIRECTORY} ]; then
mkdir ${RECORD_PATH}${RECORD_DIRECTORY}/;
fi
}
CALC_SPACE() {
case ${RECORD_MAX_SPACE_VALUE} in
mb|MB) let SPACE=${RECORD_MAX_SPACE_USE}*1024**2;
;;
gb|GB) let SPACE=${RECORD_MAX_SPACE_USE}*1024**3;
;;
tb|TB) let SPACE=${RECORD_MAX_SPACE_USE}*1024**4;
;;
*) TEXT="Invalid value for RECORD_MAX_SPACE_VALUE";
LOGINFO="CRIT";
LOG;
;;
esac
}
CHECK_DISK_SPACE() {
SPACE_OK=0;
CALC_SPACE;
until [ ${SPACE_OK} -eq 1 ];
do
let DISK_SPACE_LEFT=$(df ${RECORD_PATH} | awk '{ print $4 }' | grep [0-9].*)*1024;
if [ ${DISK_SPACE_LEFT} -lt ${SPACE} ]; then
if [ "${TEXT}" = "Available Disk-Space is lower than your value to use Record-Space on this Disk." ]; then
sleep 5;
LOAD_CFG;
CALC_SPACE;
else
TEXT="Available Disk-Space is lower than your value to use Record-Space on this Disk.";
LOGINFO="WARN";
kill ${CAM_PID} > /dev/null 2>&1;
LOG;
fi
else
SPACE_OK=1;
fi
done
}
CHECK_RECORD_SPACE() {
I_NEED_SPACE=1;
until [ ${I_NEED_SPACE} -eq 0 ];
do
if [ $(du -bs ${RECORD_PATH} | awk '{ print $1 }') -gt ${SPACE} ]; then
OLDEST_DIR=$(ls -l ${RECORD_PATH} | egrep -o "[0-9]{4}-[0-9]{2}-[0-9]{2}" | tac | tail -n1);
if [ -d ${RECORD_PATH}${OLDEST_DIR} ]; then
OLDEST_FILE=$(ls -l ${RECORD_PATH}${OLDEST_DIR} | egrep -o "[0-9]{2}-[0-9]{2}-[0-9]{2}.*" | tac | tail -n1);
CHECK_VLC_REC=$(ps fax | egrep -o ${RECORD_PATH}[0-9]{4}-[0-9]{2}-[0-9]{2}/.*_${RECORD_SAVE_SUFFIX}.ts);
if [ -n "${CHECK_VLC_REC}" ]; then
if [ $(ls -l ${CHECK_VLC_REC} | awk '{ print $5 }') -gt ${SPACE} ]; then
TEXT="The acutal recording Videofile becomes greader then the Space for recording.";
LOGINFO="CRIT";
LOG;
fi
fi
rm -R ${RECORD_PATH}${OLDEST_DIR}/${OLDEST_FILE};
fi
else
I_NEED_SPACE=0;
fi
done
}
CHECK_CAM() {
CAM_READY=0;
CAM_NOW_READY=0;
until [ ${CAM_READY} -eq 1 ];
do
if [ $(ping -c1 ${CAM_IP} > /dev/null 2>&1; echo ${?}) -eq 0 ]; then
CAM_READY=1;
if [ ${CAM_NOW_READY} -eq 1 ]; then
TEXT="Camera is now available.";
LOGINFO="INFO";
LOG;
fi
else
if [ "${TEXT}" = "Camera is not available." ]; then
sleep 5;
LOAD_CFG;
else
TEXT="Camera is not available.";
LOGINFO="WARN";
CAM_NOW_READY=1;
LOG;
if [ -f record.pid ]; then
kill $(cat record.pid);
rm record.pid;
fi
sleep 5;
LOAD_CFG;
fi
fi
done
}
CHECK_STREAM() {
CAM_URL_ERROR=$(openRTSP -B 10000000 -b 10000000 -d 10 -P 10 -v -u ${CAM_USERNAME} ${CAM_PASSWORD} rtsp://${CAM_IP}:${CAM_PORT}${CAM_STREAM_PATH} 2>&1 | grep ^Failed | grep -o [0-9a-zA-Z\ ]*$);
case ${CAM_URL_ERROR} in
" Connection reset by peer") TEXT="Connection reset by peer: [IP:PORT] are incorrect. Peer don't understand \"rtsp://\".";
LOGINFO="CRIT";
LOG;
;;
" Connection refused") TEXT="Connection refused: [PORT] is closed/filtered.";
LOGINFO="CRIT";
LOG;
;;
" 401 Unauthorized") TEXT="401 Unauthorized: [USERNAME and/or PASSWORD] are incorrect.";
LOGINFO="CRIT";
LOG;
;;
" 503 Service Unavailable") TEXT="503 Service Unavailable: [STREAM_PATH] are incorrect.";
LOGINFO="CRIT";
LOG;
;;
*) TEST_RECORD=0;
TEXT="Test-record are successful.";
LOGINFO="INFO";
LOG;
rm video-* > /dev/null 2>&1;
sleep 1;
;;
esac
}
CHANGE_ACTION_TO_STOP() {
ACTION=STOP;
if [ -f record.pid ]; then
rm record.pid
fi
sed -i s/START/STOP/g camera.conf;
TEXT="Camera-Action is now \"STOP\", because the configuration is invalid.";
LOGINFO="WARN";
LOG;
}
RECORD() {
while true
do
sleep 2;
LOAD_CFG;
ACTION=$(grep ACTION camera.conf | awk -F = '{ print $2 }');
if [ -z ${ACTION} ]; then
ACTION=OTHER;
fi
case ${ACTION} in
START) if [ ${START_RECORD} -eq 1 ]; then
TEXT="Camera-Action \"START\" was initiated.";
LOGINFO="INFO";
START_RECORD=0;
LOG;
fi
if [ ! -f record.pid ]; then
VLC_PARAM="${VLC_DEBUG} --pidfile vlc.pid --rtsp-tcp -I dummy --one-instance --daemon --reset-config --no-sout-display --no-audio --play-and-exit --stop-time=${RECORD_VIDEO_SPLIT_TIME}";
# deaktivierte Start-Parameter
if [ ${TEST_RECORD} -eq 1 ]; then
CHECK_STREAM;
fi
CHECK_DISK_SPACE;
CHECK_RECORD_SPACE;
RECORD_DIR;
CHECK_CAM;
/usr/bin/vlc rtsp://${CAM_FULL_PATH} ${VLC_PARAM} --sout "#standard{mux="ts",access="file",dst="${RECORD_PATH}${RECORD_DIRECTORY}/$(date +'%H-%M-%S')_${RECORD_SAVE_SUFFIX}.ts"}" > /dev/null 2>&1
CHECK_PID=0;
VLC_PID;
else
if [ -f record.pid ]; then
if [ $(ps fax | awk '{ print $1 }' | grep "$(cat record.pid)" > /dev/null 2>&1; echo ${?}) -eq 1 ]; then
rm record.pid;
fi
fi
RECORD_DIR;
CHECK_DISK_SPACE;
CHECK_RECORD_SPACE;
# CHECK_CAM;
fi
;;
STOP) START_RECORD=1;
NEW_PID_SET=1;
if [ -f record.pid ]; then
TEXT="Send SIGTERM (15) to VLC Process ID $(cat record.pid)";
LOGINFO="INFO";
LOG;
kill $(cat record.pid);
rm record.pid;
else
CHECK_DISK_SPACE;
RECORD_DIR;
CHECK_CAM;
fi
if [ "${TEXT}" != "Camera-Action \"STOP\" was initiated." ]; then
TEXT="Camera-Action \"STOP\" was initiated.";
LOGINFO="INFO";
LOG;
fi
;;
KILL) if [ -f record.pid ]; then
kill $(cat record.pid);
rm record.pid;
fi
TEXT="Camera-Action \"KILL\" was initiated. All running records killed.";
LOGINFO="CRIT";
LOG;
;;
*) if [ "${TEXT}" != "Camera-Action \"${ACTION}\" unknown. Please check Config-File." ]; then
TEXT="Camera-Action \"${ACTION}\" unknown. Please check Config-File.";
LOGINFO="WARN";
LOG;
fi
;;
esac
done
}
VLC_PID() {
until [ ${CHECK_PID} -eq 10 ];
do
if [ ${NEW_PID_SET} -eq 1 ]; then
if [ $(ps fax | grep "[r]tsp://${CAM_FULL_PATH}" > /dev/null 2>&1; echo ${?}) -eq 0 ]; then
CAM_PID=$(ps fax | grep "[r]tsp://${CAM_FULL_PATH}" | awk '{ print $1 }'); echo ${CAM_PID} > record.pid;
VALIDATE_VLC_PID;
if [ "${INVALID_PID}" -eq 0 ]; then
TEXT="VLC Process ID = "$(echo ${CAM_PID})"";
LOGINFO="INFO";
LOG;
NEW_PID_SET=0;
else
INVALID_PID=0;
fi
CHECK_PID=10;
else
let CHECK_PID=${CHECK_PID}+1;
if [ ${CHECK_PID} -eq 10 ]; then
TEXT="Can't find any running VLC Processes!";
LOGINFO="CRIT";
LOG;
fi
sleep 2;
fi
else
if [ $(ps fax | grep "[r]tsp://${CAM_FULL_PATH}" > /dev/null 2>&1; echo ${?}) -eq 0 ]; then
CAM_PID=$(ps fax | grep "[r]tsp://${CAM_FULL_PATH}" | awk '{ print $1 }'); echo ${CAM_PID} > record.pid;
VALIDATE_VLC_PID;
if [ "${INVALID_PID}" -eq 0 ]; then
TEXT="New VLC Process ID = "$(echo ${CAM_PID})"";
LOGINFO="INFO";
LOG;
else
INVALID_PID=0;
fi
CHECK_PID=10;
else
let CHECK_PID=${CHECK_PID}+1;
if [ ${CHECK_PID} -eq 10 ]; then
TEXT="Can't find any running VLC Processes!";
LOGINFO="CRIT";
LOG;
fi
sleep 2;
fi
fi
done
}
VALIDATE_VLC_PID() {
INVALID_PID=0;
if [ ! -z $(cat record.pid | awk '{ print $2 }') ]; then
kill -9 $(cat record.pid);
TEXT="Invalid VLC Process ID found ($(cat record.pid))";
LOGINFO="WARN";
LOG;
CHANGE_ACTION_TO_STOP;
INVALID_PID=1;
fi
}
VALIDATE_CAM_IP() {
VALID_IP() {
TEXT="IP-Address is valid.";
LOGINFO="INFO";
LOG;
}
INVALID_IP() {
TEXT="The IP-Address is invalid.";
LOGINFO="CRIT";
LOG;
}
if [ "$(echo "${CAM_IP}" | egrep -o '^?([0-9]{2}|[0-9]{3})\.?([0-9]{1}|[0-9]{2}|[0-9]{3})\.?([0-9]{1}|[0-9]{2}|[0-9]{3})\.?([0-9]{1}|[0-9]{2}|[0-9]{3})$' > /dev/null 2>&1; echo ${?})" -eq 1 ]; then
INVALID_IP;
fi
A=$(echo ${CAM_IP} | awk -F \. '{ print $1 }');
B=$(echo ${CAM_IP} | awk -F \. '{ print $2 }');
C=$(echo ${CAM_IP} | awk -F \. '{ print $3 }');
D=$(echo ${CAM_IP} | awk -F \. '{ print $4 }');
case ${A} in
"192") if [ "${B}" -eq 168 ]; then
if [ ${C} -lt 0 ]; then
INVALID_IP;
elif [ ${C} -gt 255 ]; then
INVALID_IP;
else
if [ ${D} -lt 0 ]; then
INVALID_IP;
elif [ ${D} -gt 255 ]; then
INVALID_IP;
else
VALID_IP;
fi
fi
else
INVALID_IP;
fi
;;
"172") if [ ${B} -lt 16 ]; then
INVALID_IP;
elif [ ${B} -gt 31 ]; then
INVALID_IP;
else
if [ ${C} -lt 0 ]; then
INVALID_IP;
elif [ ${C} -gt 255 ]; then
INVALID_IP;
else
if [ ${D} -lt 0 ]; then
INVALID_IP;
elif [ ${D} -gt 255 ]; then
INVALID_IP;
else
VALID_IP;
fi
fi
fi
;;
"10") if [ ${B} -lt 0 ]; then
INVALID_IP;
elif [ ${B} -gt 255 ]; then
INVALID_IP;
else
if [ ${C} -lt 0 ]; then
INVALID_IP;
elif [ ${C} -gt 255 ]; then
INVALID_IP;
else
if [ ${D} -lt 0 ]; then
INVALID_IP;
elif [ ${D} -gt 255 ]; then
INVALID_IP;
else
VALID_IP;
fi
fi
fi
;;
*) INVALID_IP;
;;
esac
}
VALIDATE_CAM_PORT() {
if [ ${CAM_PORT} -lt 0 ]; then
TEXT="Port is invalid.";
LOGINFO="CRIT";
LOG;
elif [ ${CAM_PORT} -gt 65535 ]; then
TEXT="Port is invalid.";
LOGINFO="CRIT";
LOG;
else
PORT_COLLISION=$(cat /etc/services | awk '{ print $2 }' | egrep "^${CAM_PORT}{1,5}/?(udp|tcp)$");
if [ -z "${PORT_COLLISION}" ]; then
TEXT="Port is valid.";
LOGINFO="INFO";
LOG;
else
if [ $(cat /etc/services | awk '{ print $2 }' | egrep -m1 "^${CAM_PORT}{1,5}/?(udp|tcp)$") = "554/tcp" ]; then
TEXT="Port is valid.";
LOGINFO="INFO";
LOG;
else
TEXT="Port is valid, but a service collision can be happen.";
LOGINFO="WARN";
LOG;
fi
fi
fi
}
LOG() {
if [ ! -d LOG ]; then
mkdir LOG;
fi
if [ ${LOGINFO} = "CRIT" ]; then
echo -e "${LOGINFO}\t`date '+%H:%M:%S'` ${TEXT} Script killed!" >> LOG/`date '+%Y-%m-%d'`.log;
echo -e "${LOGINFO}\t`date '+%H:%M:%S'` Send SIGKILL (9) to kill all other instances of VLC Processes!" >> LOG/`date '+%Y-%m-%d'`.log;
killall -9 vlc > /dev/null 2>&1;
exit 1;
else
echo -e "${LOGINFO}\t`date '+%H:%M:%S'` ${TEXT}" >> LOG/`date '+%Y-%m-%d'`.log;
fi
}
MAIN;
#_EoF_
Alles anzeigen
Im Pfad des Scriptes wird ebenfalls eine camera.conf erwartet.
###########################
## CAMCONTROL ##
## START | STOP | KILL ##
ACTION=START
###########################
# !!!ALL VALUES MUST BE IN DOUBLEQUOTAS!!!
# set ip or alternative the dns of the rtsp-stream-host
# value must be set
CAM_IP="192.168.0.1"
# set the port of rtsp-stream-host listening on
# value must be set
CAM_PORT="554"
# set username that allowed to watch the stream
# value is optional
CAM_USERNAME="benutzer"
# set password for the username
# value is optional
CAM_PASSWORD="123456"
# set the streampath to the rtsp-stream
# value must be set
CAM_STREAM_PATH="/video.h264"
# set the path to recordfile !WITH TAILING SLASH!
# value must be set
RECORD_PATH="/pfad/zu/den/videoaufzeichnungen/"
# set the file-suffix for the recorded files.
# value is optional
RECORD_SAVE_SUFFIX="cam-01"
# set the maximum space to use in ${MAX_SPACE_VALUE}
# value is optional but use careful because of drivespace
RECORD_MAX_SPACE_USE="5"
# set the value 'mb|MB = Megabyte', 'gb|GB = Gigabyte' or 'tb|TB = Terabyte' for ${RECORD_MAX_SPACE_USE}
# value must be set, when ${RECORD_MAX_SPACE_USE} is set
RECORD_MAX_SPACE_VALUE="GB"
# set a timevalue in seconds to split the outputvideo in ${RECORD_VIDEO_SPLIT_TIME} parts
# value ist optional
RECORD_VIDEO_SPLIT_TIME="1800"
Alles anzeigen
So sieht ein standard Logfile des Scriptes aus. Mit diversen Fehl-Konfigurationen und Kamera-Aktionen.
INFO 22:18:30 #########################################################
INFO 22:18:30 # Script security-cam.bsh started. Version v20150927_05 #
INFO 22:18:30 #########################################################
INFO 22:18:30 Loading Config-File.
INFO 22:18:30 Camera IP is 192.168.0.6.
INFO 22:18:30 IP-Address is valid.
INFO 22:18:30 Camera Port is 1558.
INFO 22:18:30 Port is valid.
INFO 22:18:30 Camera Username is benutzer.
INFO 22:18:30 Camera Password is 123456.
INFO 22:18:30 Camera Stream-Path is /video.h264.
INFO 22:18:30 Camera Record-Directory is /pfad/zu/den/videoaufzeichnungen/.
INFO 22:18:30 Camera Record-Suffix is cam-01.
INFO 22:18:30 Camera Max-Space-Use is 5.
INFO 22:18:30 Camera Max-Space-Value is GB.
INFO 22:18:30 Camera Record-Split-Time is 1800 Seconds.
INFO 22:18:30 Checking Environment.
INFO 22:18:30 Checking Record-Directory.
INFO 22:18:30 Calculating available Disk-Space.
INFO 22:18:30 Checking Record-Space
INFO 22:18:30 Checking Camera is available.
INFO 22:18:30 Starting into Camera-Action modus.
INFO 22:18:32 Camera-Action "START" was initiated.
INFO 22:18:42 Test-record are successful.
INFO 22:18:44 VLC Process ID = 21844
INFO 22:48:48 New VLC Process ID = 12497
INFO 23:18:51 New VLC Process ID = 3133
INFO 23:35:04 Reloading Config-File.
INFO 23:35:04 Checking Environment.
INFO 23:35:04 Send SIGTERM (15) to VLC Process ID 3133
INFO 23:35:04 Camera-Action "STOP" was initiated.
INFO 23:35:22 Reloading Config-File.
INFO 23:35:22 Camera IP has change from 192.168.0.6 to 192.168.0.7.
INFO 23:35:22 IP-Address is valid.
INFO 23:35:22 Checking Environment.
WARN 23:35:25 Camera is not available.
INFO 23:35:46 Reloading Config-File.
INFO 23:35:46 Camera IP has change from 192.168.0.7 to 192.168.0.6.
INFO 23:35:46 IP-Address is valid.
INFO 23:35:46 Checking Environment.
INFO 23:35:46 Camera is now available.
INFO 23:35:46 Camera-Action "STOP" was initiated.
INFO 23:36:15 Reloading Config-File.
INFO 23:36:15 Camera Port has change from 1558 to 554.
WARN 23:36:15 Port is valid, but a service collision can be happen.
INFO 23:36:15 Checking Environment.
INFO 23:36:15 Camera-Action "STOP" was initiated.
INFO 23:36:49 Reloading Config-File.
INFO 23:36:49 Camera Max-Space-Use has change from 5GB to 10GB.
INFO 23:36:49 Camera Record-Split-Time has change from 1800 to 300 Seconds.
INFO 23:36:49 Checking Environment.
INFO 23:36:49 Camera-Action "STOP" was initiated.
INFO 23:37:10 Reloading Config-File.
INFO 23:37:10 Camera Max-Space-Value has change from GB to TB.
INFO 23:37:10 Checking Environment.
WARN 23:37:10 Available Disk-Space is lower than your value to use Record-Space on this Disk.
INFO 23:37:35 Reloading Config-File.
INFO 23:37:35 Camera Max-Space-Value has change from TB to GB.
INFO 23:37:35 Camera Record-Split-Time has change from 300 to 1800 Seconds.
INFO 23:37:35 Checking Environment.
INFO 23:37:35 Camera-Action "STOP" was initiated.
INFO 23:38:01 Reloading Config-File.
INFO 23:38:01 Checking Environment.
INFO 23:38:01 Camera-Action "START" was initiated.
CRIT 23:38:01 Connection refused: [PORT] is closed/filtered. Script killed!
CRIT 23:38:01 Send SIGKILL (9) to kill all remaining VLC Processes!
INFO 23:38:35 #########################################################
INFO 23:38:35 # Script security-cam.bsh started. Version v20150927_05 #
INFO 23:38:35 #########################################################
INFO 23:38:35 Loading Config-File.
INFO 23:38:35 Camera IP is 192.168.0.6.
INFO 23:38:35 IP-Address is valid.
INFO 23:38:35 Camera Port is 1558.
INFO 23:38:35 Port is valid.
INFO 23:38:35 Camera Username is benutzer.
INFO 23:38:35 Camera Password is 123456.
INFO 23:38:35 Camera Stream-Path is /video.h264.
INFO 23:38:35 Camera Record-Directory is /pfad/zu/des/videoaufzeichnungen/.
INFO 23:38:35 Camera Record-Suffix is cam-01.
INFO 23:38:35 Camera Max-Space-Use is 10.
INFO 23:38:35 Camera Max-Space-Value is GB.
INFO 23:38:35 Camera Record-Split-Time is 1800 Seconds.
INFO 23:38:35 Checking Environment.
INFO 23:38:35 Checking Record-Directory.
INFO 23:38:35 Calculating available Disk-Space.
INFO 23:38:35 Checking Record-Space
INFO 23:38:35 Checking Camera is available.
INFO 23:38:35 Starting into Camera-Action modus.
INFO 23:38:37 Camera-Action "STOP" was initiated.
INFO 23:38:49 Reloading Config-File.
INFO 23:38:50 Checking Environment.
CRIT 23:38:50 Camera-Action "KILL" was initiated. All running records killed. Script killed!
CRIT 23:38:50 Send SIGKILL (9) to kill all other instances of VLC Processes!
INFO 23:39:16 #########################################################
INFO 23:39:16 # Script security-cam.bsh started. Version v20150927_05 #
INFO 23:39:16 #########################################################
INFO 23:39:16 Loading Config-File.
INFO 23:39:16 Camera IP is 192.168.0.66666.
CRIT 23:39:16 The IP-Address is invalid. Script killed!
CRIT 23:39:16 Send SIGKILL (9) to kill all other instances of VLC Processes!
INFO 23:39:32 #########################################################
INFO 23:39:32 # Script security-cam.bsh started. Version v20150927_05 #
INFO 23:39:32 #########################################################
INFO 23:39:32 Loading Config-File.
INFO 23:39:32 Camera IP is 192.168.0.6.
INFO 23:39:32 IP-Address is valid.
INFO 23:39:32 Camera Port is 1558.
INFO 23:39:32 Port is valid.
INFO 23:39:32 Camera Username is benutzer.
INFO 23:39:32 Camera Password is 123456.
INFO 23:39:32 Camera Stream-Path is /video.h264.
INFO 23:39:32 Camera Record-Directory is /pfad/zu/den/videoaufzeichnungen/.
INFO 23:39:32 Camera Record-Suffix is cam-01.
INFO 23:39:32 Camera Max-Space-Use is 10.
INFO 23:39:32 Camera Max-Space-Value is GB.
INFO 23:39:32 Camera Record-Split-Time is 1800 Seconds.
INFO 23:39:32 Checking Environment.
INFO 23:39:32 Checking Record-Directory.
INFO 23:39:32 Calculating available Disk-Space.
INFO 23:39:32 Checking Record-Space
INFO 23:39:32 Checking Camera is available.
INFO 23:39:32 Starting into Camera-Action modus.
INFO 23:39:34 Camera-Action "STOP" was initiated.
INFO 23:39:50 Reloading Config-File.
INFO 23:39:50 Checking Environment.
INFO 23:39:50 Camera-Action "START" was initiated.
INFO 23:40:01 Test-record are successful.
INFO 23:40:02 VLC Process ID = 18042
Alles anzeigen
Viel Spaß damit.