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
date: Mon, 02 Dec 2013 16:12:00 +0000
link: CyberAsylum.eu/streamdumper