streamdumper - my utility to dump streams to my server

So I decide to rewrite my very simple bunch of dumping scripts to something more complex. The main problem was in disconnects from live stream because some packet loss or maybe another network related issues.

To solve this I wrote script which uses one second long cycles to check if there is mplayer instance which is dumping the current mp3 stream. If there isn't mplayer instance it will start a new one.

How it works

MPlayer instance is spawned in background and script is monitoring if PID is present in processlist. Script will try to dump a stream for two hours and ten minutes after its launch. This time can be set in variable $seconds_to_run. There will be same number of dumps on disk as instances spawned cause of errors which led to mplayer termination within specified time interval (in this case 7800 secs, or 2h10min).

So I hope there will be no more losses. In the future I plan to build another device for dumps as backup. Maybe I will get enough money from advertising (LOL).

streamdumper

 
 #! /bin/bash
 
 umask 027
 
 # datetime options
 seconds_to_run="7800" # 7800 = 2h 10min
 timestamp_start="$(date +%s)"
 timestamp_stop="$(($timestamp_start + $seconds_to_run))"
 
 # www root as part of data path
 wwwroot="/var/www" # general web root path, the real one differs from this
 domain="niekde.sk" # my domain - it's real
 
 # stream source URL
 surl="http://live.slovakradio.sk:8000/FM_128.mp3"
 
 # define other variables by case switch
 case "$1" in
 	"experimentalfm" | "headbangerfm" | "leporelofm" | "nuspiritfm" | "signallfm")
 		stream_name="$1"
 		sdir="$wwwroot/$stream_name.$domain/streams"
 		log="$HOME/var/log/streamdumper/$stream_name.log"
 		;;
 	*)
 		echo "Error: Bad input parameter" >&2
 		exit 1
 		;;
 esac
 
 if ! touch  "$log"; then
 	echo "Error: couldn't touch $log"	
 fi
 
 function log {
 	echo "$(date '+%Y-%m-%d %H:%M:%S') [II] $1" | tee -a "$log" > "/dev/null"
 }
 
 function err {
 	echo "$(date '+%Y-%m-%d %H:%M:%S') [EE] $1" | tee -a "$log"
 }
 
 # conditional variables - don't change unless you know what are you doing
 first_run=0
 mplayer_running=0
 mplayer_pid=0
 runcycle=0
 
 # dump stream and count seconds to end
 # afterwards kill dump with SIGINT
 
 log "Dumping stream: $stream_name"
 
 while [ $runcycle -eq 0 ]; do
 	timestamp_now="$(date +%s)"
 	fname="$(date -d @$timestamp_now '+%Y%m%d-%H%M%S')_$stream_name.mp3"
 
 	# is this first cycle? if yes, set m'running to 0
 	if [ $first_run -eq 0  ]; then
 		first_run=$(($first_run + 1))
 		mplayer_running=0
 	fi
 
 	# if is m'running equal to 1, check if is it in processlist (did ps return non-error status?)
 	if [ $mplayer_running -eq 1 ]; then
 		if ! ps --no-headers "$mplayer_pid" > "/dev/null"; then
 			err "PID '$mplayer' isn't in processlist"
 			mplayer_running=0
 		fi
 	fi
 
 	# if is m'running equal to 0, launch it in background, get PID and set m'running to 1
 	if [ $mplayer_running -eq 0 ]; then
 		log "Launching mplayer in backround..."
 		exec "/usr/bin/mplayer" "-novideo" "-really-quiet" "-dumpfile" "$sdir/$fname" "-dumpstream" "$surl" >> "$log" 2>&1 &
 		mplayer_pid="$!"
 		log "PID: $mplayer_pid"
 		mplayer_running=1
 	fi
 
 	# if is actual timestamp greater than scheduled to stop timeout, kill the dump and end cycle by setting runcycle to 1
 	if [ "$timestamp_now" -gt "$timestamp_stop" ]; then
 		if ! kill -s SIGINT "$mplayer_pid"; then
 			err "Couldn't kill $mplayer_pid with SIGINT"
 			log "Trying SIGKILL"
 			if kill -s SIGKILL "$mplayer_pid"; then
 				log "Killed"
 			else
 				err "Couldn't kill $mplayer_pid with SIGKILL"
 				exit 2
 			fi
 		else
 			log "Interrupted"
 		fi
 
 		# this will terminate this cycle
 		runcycle=1
 	fi
 
 	# sleep one sec every cycle
 	sleep 1
 done
 
 log "End of cycle, changing permissions of '$sdir'"
 if ! /bin/chown ":www-data" "-R" "$sdir" >> "$log" 2>&1; then
 	err "Couldn't change permissions for '$sidr'"
 fi
 
 log "Done"
 exit 0
 

author: niekto@niekde.sk (Jaroslav Petráš)

date: Mon, 02 Dec 2013 16:12:00 +0000

link: CyberAsylum.eu/streamdumper