こげな感じ*1。
#!/bin/sh ####################### # # Simple MP3 Jukebox # KAWAMATA, Yoshihiro # kaw@on.rim.or.jp # ####################### #===== # utility functions / routines #===== # terminate process # terminate () { [ $# -ne 0 ] && echo "$@" rm -rf ctrl/playing [ -r ctrl/finish ] && . ctrl/finish } # trap for ^C # trap 'terminate "Aborted by user" ; exit' 2 # check flags, # fetch a file, # play it # # Usage: play_one_action { local_file | URL } # play_one_action () { [ $# -eq 0 ] && return # halt, reboot or exit # if [ -f ctrl/halt ]; then terminate "Halting..." rm -f ctrl/halt /sbin/shutdown -hp now elif [ -f ctrl/reboot ]; then terminate "Rebooting..." rm -f ctrl/reboot /sbin/shutdown -r now elif [ -f ctrl/restart ]; then terminate "Restarting scipt..." rm -f ctrl/restart exec $progfile elif [ -f ctrl/exit ]; then terminate "Exiting..." rm -f ctrl/exit exit fi # clean non-MP3 file and empty directories under spool # if [ -f ctrl/clean ]; then echo "Clearning dirs..." rm -f ctrl/clean find $src $dest oneshot oneshot_finished -type f \! \( -iname '*.mp3' -o -iname '*.url' \) -print0 | xargs -0 rm -f for d in $src $dest oneshot oneshot_finished; do (cd $d && find . -type d -print | sort -r | xargs rmdir >/dev/null 2>&1) done fi # pause playing # if [ -f ctrl/pause ]; then echo "Pausing..." while [ -f ctrl/pause ]; do sleep 15 done fi # play MP3 file # # ... invoke MP3 player with high priority # case "$1" in http://*.mp3|ftp://*.mp3) # # Cats are buffers against network stall. # Please adjust its numbers, if necessary. # ftp -o - "$1" |cat|cat|cat| nice -n -15 /usr/local/bin/mpg123 $opts - ;; *.[Mm][Pp]3) if [ -f "$1" ]; then nice -n -15 /usr/local/bin/mpg123 $opts "$1" else echo "Cannot find $1" fi ;; esac } # move played file to another directory. # directory hierarchy preserved. # # Usage: movefile srcpath desttop # movefile () { [ $# -lt 2 ] && return destdir=$2/${1#*/} destdir=${destdir%[^/]*} if [ -d $destdir ]; then mv $1 $destdir else su mp3play -c "mkdir -p $destdir" && mv $1 $destdir fi } #===== # Running code from here #===== # Base and current directory is where script placed. # progfile=$0 cd `dirname $progfile` || exit 1 # check if another player running # if mkdir ctrl/playing; then date > ctrl/playing/started chmod 0000 ctrl/playing else echo "Another player running" exit 1 fi # remove stale files # rm -f ctrl/exit ctrl/reboot ctrl/halt # user initialization # [ -r ctrl/init ] && . ctrl/init #===== # main loop ... play MP3 and its control #===== while :; do # parameters to MP3 player # unset opts [ -f ctrl/mpg123opts ] && opts=`cat ctrl/mpg123opts` # We have two spool directories for infinite loop # ... spool0 and spool1. # # set direction of file movement # between two spools # when every MP3 file played # if [ -f ctrl/reverse ]; then src=spool1 dest=spool0 else src=spool0 dest=spool1 fi # playlist is symlink to spool for playing. # rm -f playlist ln -s $src playlist # for every MP3 files # control and/or playing # for playfile in `find $src -type f \( -iname '*.mp3' -o -iname '*.url' \) | sort`; do # retrieve resource location # case "$playfile" in *.[Uu][Rr][Ll]) mp3reslist=`cat $playfile` ;; *.[Mm][Pp]3) mp3reslist=$playfile ;; esac # for every MP3 resource ... # for mp3res in $mp3reslist; do # perform one shot playlist # for oneshot in `find oneshot -type f \( -iname '*.mp3' -o -iname '*.url' \) | sort`; do # retrieve resource location # case "$oneshot" in *.[Uu][Rr][Ll]) oneshot_mp3res=`cat $oneshot` ;; *.[Mm][Pp]3) oneshot_mp3res=$oneshot ;; esac for os_mp3 in $oneshot_mp3res; do play_one_action $os_mp3 # restart at current spool # if [ -f ctrl/rescan ]; then break 2 fi done movefile $oneshot oneshot_finished done play_one_action $mp3res # restart at current spool # if [ -f ctrl/rescan ]; then echo "Recanning playlist..." break 2 fi done # move played file to the other spool # movefile $playfile $dest done # pause when no MP3 files in spools # if [ X"$playfile" = X ]; then noplay=Z$noplay echo "No file to play : $noplay" if [ $noplay = ZZ ]; then echo "Now sleeping for 60 secs..." sleep 60 noplay="" fi else noplay="" fi # role change of spools # (not changing when rescan) # if [ -f ctrl/rescan ]; then rm -f ctrl/rescan else if [ -f ctrl/reverse ]; then rm -f ctrl/reverse else touch ctrl/reverse fi fi done