I haven’t posted in about 5 billion years. Well, it seems like that anyway. As I sit here partying with my laptop on a Friday night, I’ve been wondering how to display the track length of the current track that xmms2 is playing, without having to use the “xmms2 status” command. Yes, I listen to and control all my music via a full-featured music player/manager from the command line (xmms2). The problem with using the “status” command, is that it just prints out a continuous status of what’s playing and it just keeps going, which is exactly what it’s supposed to do. It’s just like “tail -f”, So you have to ctrl-c to get out of it. Yes. That is my sole motivation for doing this, to avoid ctrl-c. Well, and maybe to learn a thing or two, but mostly out of defiance of having to use ctrl-c.
So I figured, hey I know enough bash to at least get something rolling in order to do this. Of course I had to keep looking stuff up in reference guides and on websites, because there’s no way I can remember it all. Basically, it came down to 4 key tools for going the bash route.
1. sed – to strip brackets, slashes, colons, spaces, and other undesired characters in order to make the strings easier to deal with
2. awk – to find the location of decimal points or other characters
3. cut – to get characters to the left or right of decimal points
4. bc – to calculate and convert the milliseconds to human readable form
I finally got it to work reliably tonight.
It was a horrid process that took forever. What a waste of time. But hey, that’s all part of the RTC experience!
So here it is, please excuse the bad variable names and sloppiness. I was too pissed to give a ****.
Note: I renamed this to xmms2tracklensafe and cut out all the curse words and tried to put some sense into the comments.
#!/bin/bash
tmpfileinfo=xtemp14251.tmp
tmpfile=xtemp91839.tmp
#use xmms2 info here
xmms2 info > $tmpfileinfo
vargrep=$(grep "duration" $tmpfileinfo)
echo $vargrep > $tmpfileinfo
#chopping the brackets, slashes, and spaces out of the string
sed -i 's/\[//g' $tmpfileinfo
sed -i 's/\]//g' $tmpfileinfo
sed -i 's/\///g' $tmpfileinfo
sed -i 's/'\ '//g' $tmpfileinfo
#convert the = to an X, easy to find
sed -i 's/\=/X/g' $tmpfileinfo
#for an mp3 - pluginmaddurationX
sed -i 's/\pluginmaddurationX//g' $tmpfileinfo
#for a flac - pluginflacdurationX
sed -i 's/\pluginflacdurationX//g' $tmpfileinfo
#God knows what other codecs there might be
#prints the time in milliseconds
echo "$(cat $tmpfileinfo) ms"
vargrep2=$(cat $tmpfileinfo)
varx=$vargrep2
#convert the time to minutes
var2=$(echo "$varx/1000/60" | bc -l)
echo $var2 > $tmpfile
#we are left with a fraction of a minute, which occurs after the decimal, we need to find the decimal point
var3=$(awk 'BEGIN { print index('$var2', ".") }')
#get the characters after the decimal point, this is our fraction of a minute
var4=$(cut -c $var3- $tmpfile)
#convert that fraction of a minute into seconds
var5=$(echo "scale=1; $var4*60" | bc -l | xargs printf "%1.0f")
#simply subtracting a 1 from the index of the decimal point, to be used in order to retrieve the number left of the decimal
varcut=$(echo "$var3 - 1" | bc -l | xargs printf "%1.0f")
#gets the number to the left of the decimal
var6=$(cut -c -$varcut $tmpfile)
#now we need to deal with the decimal in the number that has been converted to seconds
var7=$(awk 'BEGIN { print index('$var5', ".") }')
varcut2=1
#I honestly don't remember why I did this. I think I needed it before I started adding | xargs printf "%1.0f"
if [ "0" != $var7 ]
then
varcut2=$(echo "$var7 - 1" | bc -l | xargs printf "%1.0f")
fi
echo $var5 > $tmpfile
#now we get the seconds as a whole number, by getting the characters left of the decimal
var8=$(cut -c -$varcut2 $tmpfile)
var8=$(cat $tmpfile)
#need to prepend a 0 to the seconds if they are under 10
if [ $var8 -lt 10 ]
then
var8="0$var8"
fi
#print out the time in human readable form, minutes : seconds
echo "$var6:$var8"
#clean up the temp files
rm -f $tmpfile
rm -f $tmpfileinfo
Wow, what a pain in the pee-hole. It took me several hours over two nights and I even lost some sleep over it. So, I decided to try it Jeff’s way, using Python, since he brags about it so much. I had never used it before, and now that I have, I think I’ll be using it a lot! A lot of you are saying, “Well yeah, duh. Idiot.” or something more insulting, and I fully accept that. In fact, I encourage it!
First, we have the simple bash script that is used to execute the entire process from the command line.
#!/bin/bash
tmpfile=assscrambler124524.tmp
xmms2 info > $tmpfile
python ~/scripts/xmms2len.py
rm -f $tmpfile
And now we have the giant, complex, and horrendous python script.
file = open('./assscrambler124524.tmp')
for line in file:
if(line.find('duration',0) > -1) :
#print(line)
s = line
searchstr = 'duration = ';
x = s.rindex(searchstr, 0);
if(x > -1):
timeMillis = s[x+len(searchstr):len(s)].strip()
#print(timeMillis)
timeConverted = float(timeMillis)/1000/60
#print(timeConverted);
stime = str(timeConverted)
decIndex = stime.rindex('.', 0)
timeFraction = float(stime[decIndex:len(stime)])
seconds = int(round(timeFraction*60,0))
strseconds = str(seconds)
minutes = stime[0:decIndex]
strminutes = str(minutes)
if(seconds < 10) :
strseconds = '0' + str(seconds)
print(timeMillis + ' ms\n' + str(minutes) + ':' + strseconds)
break
Wait, that’s it? Just some simple searches, substrings, calculations, easy conversions between types, and that’s all? Not to mention the incredibly easy way to open a file and iterate through its lines.
Now, I commented out some print statements here, and I could have compacted it more, but I wanted it to be reasonably clear. The point of course, and 95% of you know probably know this already, is that python kicks bash’s ass when it comes to things that should be, well, programs. Of course bash scripts will always have their place, and they are necessary for so many things. I still love bash and am very fond of it, but from a programming perspective, it just doesn’t “cut the mustard”, as Jeff would say.
Well, that’s it for my exciting Friday night. Someday I’ll get my crap together and talk more about my xmms2 setup, the xmms2 python equalizer, the xmms2 scrobbler for last.fm, and the other scripts I’ve written for xmms2.
Cya!
My main reference for python: http://www.astro.ufl.edu/~warner/prog/python.html