Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[Script] Terminal Playlists
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
darkmason
Tux's lil' helper
Tux's lil' helper


Joined: 31 Aug 2003
Posts: 116
Location: London, UK

PostPosted: Sun Nov 26, 2006 2:18 am    Post subject: [Script] Terminal Playlists Reply with quote

UPDATE: Now with track skipping and bug fixes
UPDATE: Now with support for stopping and resuming

I knocked this together this evening as I use terminals to play music, as I wanted support for playlists like I had in Madman, but without the bloat. I thought some people may find it useful.

Code:
#!/bin/bash
PLAYER="mplayer"
PLDIR=~/.playlist

function Usage() {

   echo "$0 [command] [options]"
   echo ""
   echo "Command/Options are as follows:"
   echo "-l             List playlists"
   echo "-c             Resume playlist"
   echo "-s             Stop playlist"
   echo "-p <playlist>          Play playlist"
   echo "-r <playlist>          Remove playlist"
   echo "-a <playlist> <item>      Add item to end of playlist"
   echo "-n <playlist> <item>      Add item to next in playlist"
   echo "-m            Monitor status"

}

function Monitor(){

   watch -n 1 -t "cat $PLDIR/NOW"

}

function Stop(){

   echo "stop" > $PLDIR/STOP
   killall -5 $PLAYER

}

function GoForward(){

   killall -5 $PLAYER

}

function GoBack(){

   CURRENTPLAYLIST=`cat $PLDIR/CURRENT | cut -d ' ' -f 2`
   CURRENTTRACK=`cat $PLDIR/CURRENT | cut -d ' ' -f 1`

   let CURRENTTRACK=CURRENTTRACK-2

   if [ "$CURRENTTRACK" -le "0" ]
   then

      CURRENTTRACK=0

   fi

   echo "$CURRENTTRACK $CURRENTPLAYLIST" > $PLDIR/CURRENT

   killall -5 $PLAYER

}

function UpdateMonitor(){

   MCURRENTLINE=`cat $PLDIR/CURRENT | cut -d ' ' -f 1`
   MPLNAME=`cat $PLDIR/CURRENT | cut -d ' ' -f 2`
   MTOTALLINES=`cat $PLDIR/$MPLNAME | wc -l | cut -d ' ' -f 1`

   echo "Playlist: $MPLNAME" > $PLDIR/NOW
   echo " " >> $PLDIR/NOW
   
   i=1
   while [ "$i" -lt "$MCURRENTLINE" ]
   do

      TRACK=`cat $PLDIR/$MPLNAME | head -n $i | tail -n 1`
   
      j=`echo "$TRACK" | grep -o '/' | wc -l`
      let j=j+1

      echo "$TRACK" | cut -d '/' -f $j >> $PLDIR/NOW

      let i=i+1

   done

   TRACK=`cat $PLDIR/$MPLNAME | head -n $MCURRENTLINE | tail -n 1`
   j=`echo "$TRACK" | grep -o '/' | wc -l`
   let j=j+1
   echo "** `echo $TRACK | cut -d '/' -f $j`" >> $PLDIR/NOW

   let i=MCURRENTLINE+1
   while [ "$i" -le "$MTOTALLINES" ]
   do

      TRACK=`cat $PLDIR/$MPLNAME | head -n $i | tail -n 1`
   
      j=`echo "$TRACK" | grep -o '/' | wc -l`
      let j=j+1

      echo "$TRACK" | cut -d '/' -f $j >> $PLDIR/NOW

      let i=i+1

   done

}

function ListPlaylists() {

   for i in `ls $PLDIR/`;
   do

      if [ "$i" != "CURRENT" ]
      then
         if [ "$i" != "NOW" ]
         then

            echo "$i"

         fi

      fi

   done

}

function PlayPlaylist() {

   if [ -z "$CURRENT" ]
   then

      CURRENTLINE=1

   else

      CURRENTLINE=`cat $PLDIR/CURRENT | cut -d ' ' -f 1`

   fi

   if [ -e "$PLDIR/STOP" ]
   then

      rm $PLDIR/STOP

   fi

   echo "$CURRENTLINE $PLNAME" > $PLDIR/CURRENT

   TOTALLINES=`cat $PLDIR/$PLNAME | wc -l | cut -d ' ' -f 1`

   echo "Loading..." > $PLDIR/NOW

   while [ "$CURRENTLINE" -le "$TOTALLINES" ]
   do

      let LINESLEFT=TOTALLINES-CURRENTLINE+1
      CURRENTTRACK=`cat $PLDIR/$PLNAME | tail -n $LINESLEFT | head -n 1`

      UpdateMonitor

      $PLAYER "$CURRENTTRACK"

      if [ -e "$PLDIR/STOP" ]
      then

         rm $PLDIR/STOP
         exit 0

      fi

      TOTALLINES=`cat $PLDIR/$PLNAME | wc -l | cut -d ' ' -f 1`
      CURRENTLINE=`cat $PLDIR/CURRENT | cut -d ' ' -f 1`
      
      let CURRENTLINE=CURRENTLINE+1
      echo "$CURRENTLINE $PLNAME" > $PLDIR/CURRENT

   done

}

function RemovePlaylist(){

   rm $PLDIR/$PLNAME

}

function AddToPlaylist(){

   CURRENTDIR=`pwd`
   echo "$CURRENTDIR/$NEWITEM" >> $PLDIR/$PLNAME
   UpdateMonitor

}

function AddToPlaylistNext(){

   CURRENTDIR=`pwd`
   CURRENTLINE=`cat $PLDIR/CURRENT | cut -d ' ' -f 1`
   TOTALLINES=`cat $PLDIR/$PLNAME | wc -l | cut -d ' ' -f 1`

   cat $PLDIR/$PLNAME | head -n $CURRENTLINE > $PLDIR/tmp
   echo "$CURRENTDIR/$NEWITEM" >> $PLDIR/tmp

   let LINESLEFT=TOTALLINES-CURRENTLINE

   if [ "$LINESLEFT" -ge "1" ]
   then

      cat $PLDIR/$PLNAME | tail -n $LINESLEFT >> $PLDIR/tmp

   fi   

   mv $PLDIR/tmp $PLDIR/$PLNAME   
   UpdateMonitor

}

if [ "$1" == "-p" ]
then
   
   PLNAME=$2
   if [ ! -e $PLDIR/$PLNAME ]
   then

      echo "Invalid Playlist"
      exit 0

   fi

   PlayPlaylist
   exit 0

fi

if [ "$1" == "-c" ]
then
   
   PLNAME=`cat $PLDIR/CURRENT | cut -d ' ' -f 2`
   CURRENT=1
   if [ ! -e $PLDIR/$PLNAME ]
   then

      echo "Invalid Playlist"
      exit 0

   fi

   PlayPlaylist
   exit 0

fi

if [ "$1" == "-a" ]
then

   PLNAME=$2

   NEWITEM=$3
   if [ ! -e "$NEWITEM" ]
   then

      echo "Invalid item"
      exit 0

   fi

   AddToPlaylist
   exit 0

fi
   
if [ "$1" == "-n" ]
then

   PLNAME=$2
   if [ ! -e $PLDIR/$PLNAME ]
   then

      echo "Invalid Playlist"
      exit 0

   fi

   NEWITEM=$3
   if [ ! -e "$NEWITEM" ]
   then

      echo "Invalid item"
      exit 0

   fi

   AddToPlaylistNext
   exit 0

fi
   
if [ "$1" == "-r" ]
then

   PLNAME=$2
   if [ ! -e $PLDIR/$PLNAME ]
   then

      echo "Invalid Playlist"
      exit 0

   fi

   RemovePlaylist
   exit 0

fi

if [ "$1" == "-l" ]
then

   ListPlaylists
   exit 0

fi

if [ "$1" == "-s" ]
then

   Stop
   exit 0

fi

if [ "$1" == "-f" ]
then

   GoForward
   exit 0

fi

if [ "$1" == "-b" ]
then

   GoBack
   exit 0

fi

if [ "$1" == "-m" ]
then

   Monitor
   exit 0

fi

Usage




First of all, change PLAYER to your player of choice, in my case mplayer and create the directory '.playlist' in your home directory. I'll assume you called this script 'music', but you can call it whatever you like.

You can then create your playlists by adding tracks e.g.

Code:
music -a somerandomplaylist music/Artist/Album/01_Somesong.mp3


NOTE: You can only enter relative paths, not full ones. i.e. music/track.mp3 will work, but /home/user/music/track.mp3 won't.

Play your playlist with:
Code:
music -p somerandomplaylist


Stop with:
Code:
music -s


...And resume with:
Code:
music -c


You can then add tracks while it's playing with the '-n' and '-a' arguments in another window.

The '-l' and '-r' arguments should be quite self-explanatory.

UPDATE: You can now skip tracks with the '-b' and '-f' arguments in another window.

Whats the point? Well I control this script with Pekwm i.e.
Code:
   Chain = "Ctrl Mod4 M" {
      Keypress = "P" { Actions = "Exec music -p dark >&/dev/null &" }
      Keypress = "S" { Actions = "Exec music -s" }
      Keypress = "F" { Actions = "Exec music -f" }
      Keypress = "C" { Actions = "Exec music -c" }
      Keypress = "B" { Actions = "Exec music -b" }
      Keypress = "M" { Actions = "Exec aterm -e  music -m " }
   }


but I'm sure you could assign keys in any WM.

Using another terminal you can use...
Code:
music -m

to monitor your current playlist.

it may contain bugs! :P
_________________
emerge sex cowsay
sex | cowsay -f sodomized :o
sex | festival --tts :o :o :o
Back to top
View user's profile Send private message
wudmx
Guru
Guru


Joined: 07 Aug 2002
Posts: 527

PostPosted: Sun Apr 08, 2007 11:13 pm    Post subject: Reply with quote

Hi,
thanks for your script. Don't know why but somehow the script didn't work on my laptop... so I hacked together my own one based on your solution. It's almost the same without monitor support but with a function creating a play list! Hope this is okay for you, here is the code:

Code:
#!/bin/sh

#########################
#####               #####
# configuration section #
#####               #####
#########################


# your console player, I prefer mplayer
PLAYER="/usr/bin/mplayer"

# playlist directory (use $HOME and not ~ for your home directory)
PLDIR="$HOME/.playlist"

# some absolute paths for bash built-in commands
PROG_RM="/bin/rm"
PROG_MKDIR="/bin/mkdir"
PROG_CAT="/bin/cat"
PROG_AWK="/bin/awk"
PROG_LS="/bin/ls"
PROG_KILL="/bin/kill"
PROG_KILLALL="/bin/killall"
PROG_TOUCH="/bin/touch"


#########################################################
#####                                               #####
# do *NOT* edit lines below until you know what you do! #
#####                                               #####
#########################################################

# files internally used by the script
FILE_STOP=".stop"
FILE_CURRENT_TRACK=".current_track"

PL=""
NUM_TRACKS=0
CURRENT_DIR=""
CURRENT_TRACK=""
CURRENT_TRACK_NO=0
CURRENT_PL=""
LINES_LEFT=0
OLD_TRACK_NO=0
OLD_PL=""
RANDOM_TRACK=0


function Usage {

   echo "$0 [command]"
   echo ""
   echo "commands:"
   echo "-l                list playlists"
   echo "-s                stop playlist"
   echo "-p <PL>           play playlist <PL>"
   echo "-r <PL>           remove playlist <PL>"
   echo "-a <PL> <FILE>    add <FILE> to playlist <PL>"
   echo "-c <PL> <DIR>     add all files below <DIR> to <PL>"
   echo "-n                go to next song"
   echo "-N                go to randomly next song"
   echo "-b                go to previous song"
   echo "-B                go to randomly previous song"
   echo "-h                print (this) help screen"
}


function CheckConfiguration {

   ###
   # verify the PLAYER configuration variable
   if [ ! -e "$PLAYER" ]
   then
         
      echo "$PLAYER does not exist ! Please double-check your configuration."
      exit -1
   fi


   ###
   # verify that there is a playlist directory - we need it!

   if [ ! -e "$PLDIR" ]
   then

      echo -n "Playlist directory $PLDIR does not exist. Should I create it now ? (y/n) "
      read input
      case "$input" in
         "y" | "Y" )
            $PROG_MKDIR $PLDIR
            ;;
      esac
   fi
}


function CleanUp {
   
   ###
   # remove $FILE_CURRENT_TRACK file if existent in playlist directory

   if [ -e "$PLDIR/$FILE_CURRENT_TRACK" ]
   then

      $PROG_RM -f "$PLDIR/$FILE_CURRENT_TRACK"
   fi

   ###
   # remove $FILE_STOP file if existent in playlist directory
   if [ -e "$PLDIR/$FILE_STOP" ]
   then

      $PROG_RM -f "$PLDIR/$FILE_STOP"
   fi
}


function CleanUpExit {
   
   ###
   # remove $FILE_CURRENT_TRACK if existent in playlist directory

   if [ -e "$PLDIR/$FILE_CURRENT_TRACK" ]
   then

      $PROG_RM -f "$PLDIR/$FILE_CURRENT_TRACK"
   fi

   ###
   # remove $FILE_STOP file if existent in playlist directory
   if [ -e "$PLDIR/$FILE_STOP" ]
   then

      $PROG_RM -f "$PLDIR/$FILE_STOP"
   fi

   ###
   # clean termination of program

   exit 0
}


function DirWalk() {

   ###
   # take the first parameter as an entry to the directory with the files
   
    for i in "$2"/*; do
        if [ -f "$i" ]
        then
            echo "`pwd`/$i" >> "$PLDIR/$1"
        fi
    done
}


function PlayPlaylist {

   ###
   # some words about this code:
   # it plays the tracks one by one and is finished if either
   #   1) the playlist is finished or
   #   2) someone has triggered a $0 -s ("stop signal") from outside (indicated by the $FILE_STOP file)

   ###
   # count number of tracks of current playlist
   
   NUM_TRACKS=`$PROG_CAT $PLDIR/$PL | wc -l | cut -d ' ' -f 1`

   ###
   # go through all tracks one by one
   # keep in mind that order of tracks played can be re-arranged using "signals" from outside
   # (e.g. -s, -b, -n, -B, -N)
   
   CURRENT_TRACK_NO=0
   while [ "$CURRENT_TRACK_NO" -le "$NUM_TRACKS" ]
      do

      ###
      # get current track number and current playlist from current_track-file

      CURRENT_TRACK_NO=`$PROG_CAT $PLDIR/$FILE_CURRENT_TRACK | head -n 1 | cut -d ' ' -f 1`
      CURRENT_PL=`$PROG_CAT $PLDIR/$FILE_CURRENT_TRACK | head -n 1 | cut -d ' ' -f 2`

      ###
      # if stop file exists, exit at once

      if [ -e "$PLDIR/$FILE_STOP" ]
      then
         CleanUpExit
      fi

      ###
      # get filename belonging to current track number

      let LINES_LEFT=NUM_TRACKS-CURRENT_TRACK_NO+1
         CURRENT_TRACK=`$PROG_CAT $PLDIR/$CURRENT_PL | tail -n $LINES_LEFT | head -n 1`

      ###
      # for the next track, we have to increase track number (it's quite a hack, I know)

      let CURRENT_TRACK_NO=CURRENT_TRACK_NO+1
      echo "$CURRENT_TRACK_NO $CURRENT_PL" > "$PLDIR/$FILE_CURRENT_TRACK"

      ###
      # play the current track using player given from configuration

         $PLAYER "$CURRENT_TRACK"

      ###
      # read in new value of current_track
      # we need this line because if we're played the last song and a -b appeared
      # the prev track wouldn't be played w/o the line following

      CURRENT_TRACK_NO=`$PROG_CAT $PLDIR/$FILE_CURRENT_TRACK | head -n 1 | cut -d ' ' -f 1`

      done

   CleanUpExit
}


function PlayRandom {

   ###
   # get current playlist and number of tracks

   PL=`$PROG_CAT $PLDIR/$FILE_CURRENT_TRACK | head -n 1 | cut -d ' ' -f 2`
   NUM_TRACKS=`$PROG_CAT $PLDIR/$PL | wc -l | cut -d ' ' -f 1`

   ###
   # compute random number

   let RANDOM_TRACK=$RANDOM%NUM_TRACKS

   ###
   # write random track information to current_track-file
   echo "$RANDOM_TRACK $PL" > "$PLDIR/$FILE_CURRENT_TRACK"
}


#####
###
# script starts here parsing the command-line
###
#####


###
# before we go on the configuration lines are checked

CheckConfiguration

###
# -l = list the playlists

if [ "$1" == "-l" ]
then

   echo "Your Playlists in $PLDIR:"

   $PROG_LS -lh "$PLDIR" | $PROG_AWK '{ print $9 }'

   exit 0
fi


###
# -r = remove a playlist

if [ "$1" == "-r" ]
then
   
   if [ ! -e "$PLDIR/$2" ]
   then
      echo "Playlist \"$2\" not found in $PLDIR !"
      echo "Could *NOT* delete Playlist !"
      exit -1
   fi

   echo -n "Do you really want to delete the Playlist $2 ? (y/n) "
   read input

   case "$input" in
      "y" | "Y" )
         $PROG_RM -f "$PLDIR/$2"
         ;;
   esac

   exit 0
fi


###
# -a = add a track to a playlist

if [ "$1" == "-a" ]
then

   ###
   # this makes only sense when the playlist is existent
   
   if [ ! -e  "$PLDIR/$2" ]
   then
      echo "Playlist \"$2\" not found in $PLDIR !"
      #fix me shall i create an empty list?
      exit -1
   fi

   CURRENT_DIR=`pwd`
   if [ ! -e "$CURRENT_DIR/$3" ]
   then
      echo "File \"$CURRENT_DIR/$3\" not found !"
      exit -1
   fi

   ###
   # note that these are all absolute pathnames, not relative ones
   
   echo "$CURRENT_DIR/$3" >> "$PLDIR/$2"

   exit 0
fi


###
# -c = create a new playlist with files from directory

if [ "$1" == "-c" ]
then

   ###
   # be sure that we have a directory
   
   if [ ! -d "$3" ]
   then
      echo "$3 is no directory!"
      exit -1
   fi

   ###
   # furthermore, check whether there is a playlist with this name already
   
   if [ -e "$PLDIR/$2" ]
   then
      echo -n "$2 already exists. Do you want to overwrite it ? (y/n) "
      read input

      case "$input" in
         "y" | "Y")
            $PROG_RM -f "$PLDIR/$2"
            ;;
         *)
            echo "$2 has not been deleted. Please try another name or overwrite it!"
            exit 0
      esac
   fi

   ###
   # then let us traverse the directory given from command line
   
   for dir in "$3"*; do
      if [ -d "$dir" ]
      then
         DirWalk "$2" "$dir"
      fi
   done

   exit 0
fi


###
# -p = play a playlist

if [ "$1" == "-p" ]
then

   ###
   # store given parameter (hopefully a playlist name) in $PL
   PL=$2

   ###
   # if there was no second parameter at all
   
   if [ "$PL" == "" ]
   then
      CleanUpExit
   fi

   ###
   # verify whether the playlist is existent in the playlist directory
   
   if [ ! -e "$PLDIR/$PL" ]
   then
      echo "Playlist \"$2\" not found in $PLDIR !"
      echo "Use $0 -l to get a list of all available playlists !"
      CleanUpExit
   fi

   ###
   # before we play we check that there is no other instance running
   # fix me: we need some code detecting another instance of $0
   
   CleanUp

   ###
   # start with the first track of playlist $PL
   
   echo "1 $PL" > "$PLDIR/$FILE_CURRENT_TRACK"
   PlayPlaylist

fi


###
# -s = stop playlist

if [ "$1" == "-s" ]
then
   
   $PROG_TOUCH "$PLDIR/$FILE_STOP"
   $PROG_KILLALL -9 $PLAYER
   
   exit 0
fi


###
# -n = play next track

if [ "$1" == "-n" ]
then
   
   ###
   # this makes only sense when an active player is existent
   
   if [ ! -e "$PLDIR/$FILE_CURRENT_TRACK" ]
   then
      echo "It seems that no player is running atm !"
      exit -1
   fi

   ###
   # to play the next song (if there is one) we have to kill the active one
   # fix me: what if we're on the last track? until now, program terminates
   
   $PROG_KILLALL -9 $PLAYER

   exit 0
fi


###
# -N = play next random track

if [ "$1" == "-N" ]
then
   
   ###
   # this makes only sense when there is an active player existent

   if [ ! -e "$PLDIR/$FILE_CURRENT_TRACK" ]
   then
      echo "It seems that no player is running atm !"
      exit -1
   fi
   
   ###
   # play a random file
   
   PlayRandom
   $PROG_KILLALL -9 $PLAYER

   exit 0
fi


###
# -b = play previous track

if [ "$1" == "-b" ]
then
   
   ###
   # this makes only sense when a player is active
   
   if [ ! -e "$PLDIR/$FILE_CURRENT_TRACK" ]
   then
      echo "It seems that no player is running atm !"
      exit -1
   fi

   ###
   # get track and playlist information of current running track
   
   OLD_TRACK_NO=`$PROG_CAT "$PLDIR/$FILE_CURRENT_TRACK" | head -n 1 | cut -d ' ' -f 1`
   OLD_PL=`$PROG_CAT "$PLDIR/$FILE_CURRENT_TRACK" | head -n 1 | cut -d ' ' -f 2`

   ###
   # compute number of previous track
   
   TRACK_NO=1
   if [ "$OLD_TRACK_NO" -gt 1 ]
   then
      let TRACK_NO=OLD_TRACK_NO-2
   fi

   ###
   # start prev track by writing information to current_track-file and killing active player
   
   echo "$TRACK_NO $OLD_PL" > "$PLDIR/$FILE_CURRENT_TRACK"
   $PROG_KILLALL -9 $PLAYER

   exit 0
fi


###
# -B = play next random track

if [ "$1" == "-B" ]
then
   
   ###
   # makes only sense when there is an active player existent
   
   if [ ! -e "$PLDIR/$FILE_CURRENT_TRACK" ]
   then
      echo "It seems that no player is running atm !"
      exit -1
   fi

   ###
   # play next track randomly
   
   PlayRandom
   $PROG_KILLALL -9 $PLAYER

   exit 0
fi


###
# -h = help screen

if [ "$1" == "-h" ]
then

   Usage
   
   exit 0
fi


exit 0


Here and there, things could be of course better. Just ignore the fix-me lines :D

If you want to make a play list use music -c PL DIR or just use this one:
Code:

touch ~/.playlist/PLAYLISTNAME
for i in *.mp3; do music_terminal -a PLAYLISTNAME $i; done


Hope this will help someone :D

Thanks again darkmason
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum