#!/bin/bash 
##
# Script to check and resteram IP camera and IP video server 
# Tested for Planet IVS-H120 and restreaming for IPTV STB XL-ITB103EZ
#
# Hope usefull for most IP cameras, if not exactly at least for inspiration
#
# Write comments to hemzal@asm.cz
#
# Before used you must to have functional aplications VLC and cURL
# apt-get install vlc
# apt-get install curl
#
# Script is dounig endless check of stream if is operational by getting few seconds of stream into file and then checking if his size grows enough. If so going next check after defined period.
# If stream is not running correctly, produced temporary file is zero os small and then will firstly restart restreaming application. If several times trying to restart restreaming application without effect
# then will go to restart remote device. 
#
# !! If you will kill this process you must to kill also stream which is running using this process. Script do not now about previously run streams. So if you running this script in bunch of others stream 
# recommend to put then command like 'killall vlc'  before running such copies of script.
#
#
#
# You have to tune variables bellow to your case.
## 1.]
# Format command for restreaming. here exactly it reencapsulates RTSP stream from videoserver into RTP stream and will send them over multicast adress
# backslash necessary before & in command formating, it is bash convention...
RUNSTREAM='cvlc --rtsp-caching=7000 'rtsp://10.99.99.252/media/media.amp?resolution=704x576\&videocodec=h264\&audio=0' --sout '#duplicate{dst=rtp{proto=udp,mux=ts,dst=239.148.0.100,port=9001}}''
# Time which is necessary to give to restream to be fully operational, in seconds
RESTREAMSTARTTIME=15

# 2.]
# Format command to check that device is online, here used check for exit code of cUrl
# Note - error codes of curl used, their others will be ignored. If using other app for online test change to his error codes
# Put there right connection timeout according your case, here used 3 seconds
ONLINE="curl --silent --max-time 3 10.99.99.252 -o /dev/null"


# 3.]
# Format command for checking that stream is running 
# Time allowed for vlc runtime check in seconds, after this time will be killed by system, if system too slow make it bigger
DELAY=15
# Minimal size define how big stream file must be to valiadate streaming as functional (10kB defined running of VLC)
MINIMALSIZE=10000
# temporary file used fo check - if more scripts running each need own file
FILE="/tmp/camcheck1.ts"
# Source of stream to check. Can be used source or restreamed stream. Here used alreday restreamed one
SOURCE="rtp://239.148.0.100:9001"
# Format command for test of stream functionality.
RUNCMD="/usr/bin/timeout $DELAY cvlc $SOURCE --sout="#std{access=file,mux=ts,dst=$FILE}""
# Time between each check in seconds
NEXTCHECKDELAY=15

# 4.]
# Format command to reboot videoserver 
DEVICEREBOOT="curl --silent --max-time 3 --user admin:admin http://10.99.99.252/reboot.cgi?redirect=maintenance.asp -o /dev/null"
# How many tries before reboot
TRIESBEFOREREBOOT=3
# Delay after reboot - to give device chance to boot up
DELAYAFTERREBOOT=60



##################################################
PIDRUNSTREAM=0
TRYCOUNT=0

while true; do

echo Checking if video server is online...
$ONLINE; ECODE=$?;


# Error codes of curl used, their others will be ignored. If using other app for online test change to his error codes
case $ECODE in 
    7|28)
    echo Server is offline, cannot repair from here...
    # Pust some email message here
    ;;
    0)
    echo OK, server online.
    ;;
    * )
    echo Unexpected error code. Check handling of online test.
esac


if [ $ECODE -eq 0 ]; then 
    if [ $PIDRUNSTREAM -eq 0 ]; then
	echo Spoustim stream...
        echo $RUNSTREAM
        $RUNSTREAM &
        PIDRUNSTREAM=$!
        echo Stream spusten s PID $PIDRUNSTREAM
        # Some delay before going to check sequence to give stream chance to be started before checked for first time
        sleep $RESTREAMSTARTTIME
        TRYCOUNT=$[$TRYCOUNT+1]
    fi

    echo Checking stream...
    # Checking routine here
    # If exist check-file then delete them
    if [ -e $FILE ]; then 
        rm  $FILE 
    fi

    # Run checking routine to generate temporary file
    #echo $RUNCMD
    $RUNCMD
    sleep 1
    
    # Check the filesize, if stream is working it will be bigger then defined size 
    echo Checking size...
    SIZE=0
    if [ -e $FILE ]; then 
        SIZE=`/bin/ls -als $FILE | /usr/bin/cut -d " " -f 6`
    fi
    echo Filesize is $SIZE

    if [ $MINIMALSIZE -gt $SIZE ]
    then
	if [ $TRYCOUNT -gt $TRIESBEFOREREBOOT ]; then 
		echo Number of stream restarts exceeded, restarting remote device  first.
		TRYCOUNT=0
		$DEVICEREBOOT 
		sleep $DELAYAFTERREBOOT
	fi
	
      echo Stream is DOWN. Restart streaming... 
    # Put your restarting commands here
      kill -KILL $PIDRUNSTREAM
      sleep 1
      PIDRUNSTREAM=0
    else
      echo Stream is operational. Doing nothing...
      TRYCOUNT=0
    # Some delay before next check
    sleep $NEXTCHECKDELAY
    fi
else
    sleep $NEXTCHECKDELAY
fi

done

