#!/bin/bash # bash-music v1.0 # # Bash script to generate a playlist and play music! # It's not great, but it's a great basic player, # and can take advantage of Pulseaudio's networked playing. # Fairly small memory usage too. # Requires: # bash v3+ # gzip, zcat (provided by gzip) # play (provided by sox) # tree, cut, sed, tail, head, sort, kill, that sort of stuff... # Shortcomings: # Playlist will contain non-audio items # Max 32767 songs due to bash's $RANDOM limit # Does not daemonize and does not catch any input, only signals, #+i.e. it's fairly simple # Syntax: # ./bash-music # ./bash-music skip # Config -- make sure you edit this PIDFILE="/tmp/bash-music.pid" PLFILE="/tmp/bash-music-pl.gz" MUSDIR="/path/to/your/Music" TREECMD="tree -qQinflL 10 --noreport" # Bash's maximum random number through $RANDOM MAXRND=32767 MAXERR=50 # Begin # Did we receive a command? if [ -e "$PIDFILE" ] ; then if [ -r "$PIDFILE" ] ; then if [ "$1" == "" ] ; then echo "$0 is already running." exit 0 elif [ "$1" == "skip" ] ; then kill -USR1 `cat "$PIDFILE"` exit 0 fi fi fi # Init echo $$ > "$PIDFILE" ERRS=0 umask 0077 # X is not necessary here and can cause spurious output, esp. with X-forwarding unset DISPLAY # Set traps trap 'rm -f "$PLFILE" "$PIDFILE"; exit 0' INT TERM EXIT trap 'kill $PLAYPID' USR1 # Generate playlist, # prepend a random number to each entry # sort it by the random numbers # trim out the random numbers # compress and save list echo "Generating playlist, please wait..." $TREECMD "$MUSDIR" | \ sort -R | \ head -n $MAXRND | \ cut -f2- | \ gzip -9 > "$PLFILE" # How long is our playlist? CEIL=`zcat "$PLFILE" | wc -l` # Now play! # .. lack of a better syntax makes me sad :< # (syntaxes such as `for i in {1..5}` do not allow for variables) i=0 while [ $i -lt $CEIL ] do SONG=. while [ ! -f "$SONG" -o ! -r "$SONG" ] ; do RND=$RANDOM if [ "$RND" -gt "$CEIL" ] ; then let "RND %= $CEIL" ; fi SONG=`zcat "$PLFILE" | sed -n "$RND"p | head -c -2 | tail -c +2` done play -q "$SONG" -t pulseaudio & let PLAYPID=$! echo "#$i: $PLAYPID: Now playing $SONG" wait $PLAYPID if [ $? -ne 0 ] ; then let "ERRS=$ERRS+1" ; fi if [ $ERRS -gt $MAXERR ] ; then echo "Too many errors; aborting!" exit 1 fi let i=i+1; done