As of 2016-02-26, there will be no more posts for this blog. s/blog/pba/
Showing posts with label MPD. Show all posts

Just finished some changes for showing song title and artist of music which played by (S)MPlayer in my dzen.

The modified lf-submit.sh (lf-mplayer-wrapper.sh) doesn’t extract time information because it will have to parse MPlayer’s output, though it’s not hard, but I just didn’t want to do it. Beside, the script couldn’t decide the song length, because I might set A-B playing mode. Basically, only song title and artist are available to display and that’s what my dzen used to show me the songs played by MPD.

Except the time and player’s status, my dzen shows me same information as if showing MPD status, including Last.fm playcount and loved status. lf-submit.sh helps save the current song information to /tmp/lf-submit.sh.currentsong and my status.c pick up and show them, then lf-playcount-image.sh helps retrieve data from Last.fm.

I don’t feel I really need song to be shown in dzen when I play a music video, you can just watch pictures, why do you want to read text? Anyway, it just got me something to do.

If you have watched the screencast above, you may notice that there are some glitches when rolling the text after 0‘50”. I knew someday I would have to fix that, problems with characters other than ASCII. Now, I really have to, but later.

Last few days, I have been watching German music video. I found there are some awesome videos and some funny ones. I will post later hopefully.

Oh, sorry for the last 1 minute and 30 second, seeing me fixing that exclamation mark thing!

I have a Bash script which connects to MPD server and display current song and also accepts some keys to control the player. I have stripped some functions from it a few times when I needed to write a Bash script to do something with MPD, e.g. showing Last.fm playcount in Conky. A few times, I wanted to know what metadata of MPD command currentsong provides, I quick hacked the script and made it printed out the returned data.

I think it’s time to write a simple client to accept command and print out the response. Stripping that Bash script was my first thought, then I decided to write a Python script, instead. It’s not because I prefer Python or something, just I hadn’t written a single line Python code for a long time.

Before I showed you that Python code, there is one more thing I just found out. A really really simple client for MPD, which is telnet tool.

$ telnet 0 6600
Trying 0.0.0.0...
Connected to 0.
Escape character is '^]'.
OK MPD 0.15.0
currentsong
file: A/Alexandria Maillot/Just Another Girl/Just Another Girl.mp3
Time: 224
Artist: Alexandria Maillot
AlbumArtist: Alexandria Maillot
Title: Just Another Girl
Album: Just Another Girl
Track: 1/4
Genre: Pop
Composer: Alexandria Maillot and Joby Baker
Pos: 1
Id: 159
OK
stats
artists: 56
albums: 56
songs: 392
uptime: 124
playtime: 54
db_playtime: 84859
db_update: 1291807454
OK
pasus
ACK [5@0] {} unknown command "pasus"
pause
OK
play
OK
close
Connection closed by foreign host.

You don’t really need mpc if you are a script nut with nc (netcat) or expect. If you don’t need to process the response, you can always give commands to MPD, e.g.


echo "next" | telnet 0 6600

This will make MPD to play next song.

Now the Python code:


#!/usr/bin/env python

try:
import readline
except ImportError:
pass
import socket
import sys


HOST = 'localhost'
PORT = 6600
RECV_SIZE = 2**20 # One megabyte
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Connecting to %s:%d...' % (HOST, PORT)
s.connect((HOST, PORT))
except socket.error:
print 'Unable to connect.'
sys.exit(1)

print s.recv(RECV_SIZE)
print '*** <Control+C> to exit ***\n'

while True:
try:
cmd = raw_input(">>> ")
if cmd:
s.send(cmd + '\n')
if 'close' in cmd:
break
print s.recv(RECV_SIZE)
except KeyboardInterrupt:
break

print
s.close()

A sample interaction:


% ./smpdc.py
Connecting to localhost:6600...
OK MPD 0.15.0

*** <Control+C> to exit ***

>>> currentsong
file: A/Alexandria Maillot/Just Another Girl/Just Another Girl.mp3
Time: 224
Artist: Alexandria Maillot
AlbumArtist: Alexandria Maillot
Title: Just Another Girl
Album: Just Another Girl
Track: 1/4
Genre: Pop
Composer: Alexandria Maillot and Joby Baker
Pos: 1
Id: 159
OK

>>> playlist
0:A/A Lion Named Roar/Shoot It Straight.mp3
1:A/Alexandria Maillot/Just Another Girl/Just Another Girl.mp3
2:A/Ana Free/Keep On Walking.mp3
3:A/Ana Free/Questions In My Mind.mp3
4:S/Stars/Stars_Dead_Hearts.mp3
OK

>>> next
OK

>>> currentsong
file: A/Ana Free/Questions In My Mind.mp3
Time: 231
Artist: Ana Free
AlbumArtist: Ana Free
Title: Questions In My Mind
Album: Radian
Track: 1/5
Date: 2010
Genre: Pop Rock
Composer: Ana Gomes Ferreira and Blake Harris Brandes
Pos: 3
Id: 161
OK

>>> close

I wrote this Bash script, lf-playcount-image.sh, for two things:

  1. Get my playcount of currently playing track with MPD on Last.fm, and
  2. Get the album cover art image URLs on Last.fm, so I can use them to show on Conky.

1   Configuration

1.1   For Last.fm

You will need to create a configuration file in ~/.lf-bash/config with these content:


APIKEY=YOUR_LASTFM_APIKEY
USERNAME=YOUR_LASTFM_USERNAME

For using Track.getinfo API, it’s required to supply API key. Since this is a Bash script, I don’t think it’s wise that I give you my API key even it’s not kind of secret key. You can apply for one. There are two things, I should tell you. First, I don’t have a key, either; Second, in that API page, there is an example link, just below the title. Take a look closer, I am sure you will understand why I want you to look at that link. Yes, I want you to see the response from Last.fm, not the parameters in that link. I swear! [finger crossed behind my back]

1.2   For Conky

The following is my own Conky code:


${if_running mpd}${color lightblue}MPD: ${color #408040}$mpd_status$color$alignr ${if_running mpdscribble}s$endif${if_match "$mpd_repeat" == "On"}r$endif${if_match "$mpd_random" == "On"}z$endif $mpd_vol%
${alignc}${color red}$mpd_title$color
${alignc}${color #9999ff}$mpd_album$color
${alignc}${color green}$mpd_artist$color
${alignc}${color yellow}Played <b>${execi 6 lf-playcount-image.sh}</b><b>${execi 6 cut -f 2 -d \ "/tmp/lf-playcount-image"}</b> times$color
[$mpd_elapsed/$mpd_length] ${color #ccddff}${mpd_bar 3,0}$color<b>${execpi 6 echo "\${image /tmp/lf-images/large.png -p 125,600 -s 200x200 -n -f 6}"}</b>${endif}

It looks like:

http://farm5.static.flickr.com/4134/4935908273_01a7596905_z.jpg

The first $execi is to let the script to update. It will get song info from MPD directly and use it to query on Last.fm. A cache file will be stored at /tmp/lf-playcount-image, it only gets updated when different song is played. In other words, if you play only one song repeatedly, the playcount will not be updated, this is a caveat.

The cache file will read:


a687c5e49a9740c93ae30eb38c8bc729 36 http://userserve-ak.last.fm/serve/64s/50562771.png http://userserve-ak.last.fm/serve/126/50562771.png http://userserve-ak.last.fm/serve/174s/50562771.png http://userserve-ak.last.fm/serve/300x300/50562771.png

First one is a hash for identify if it’s the same song. Second is the playcount, then small image URL, medium image URL, large image URL, and extra large image URL. They are space-separated values.

Once this script retrieves these information from Last.fm, it will also try to download those images to /tmp/lf-images/. That directory might look like:


% ll /tmp/lf-images/
total 700
-rw-r--r-- 1 livibetter livibetter 2374 May 20 2008 http:--cdn.last.fm-flatness-catalogue-album-jewelcase_large.png
-rw-r--r-- 1 livibetter livibetter 2081 May 20 2008 http:--cdn.last.fm-flatness-catalogue-album-jewelcase_medium.png
-rw-r--r-- 1 livibetter livibetter 1444 Jun 18 2009 http:--cdn.last.fm-flatness-catalogue-album-jewelcase_small.png
-rw-r--r-- 1 livibetter livibetter 33671 Aug 29 09:14 http:--userserve-ak.last.fm-serve-126-50562771.png
-rw-r--r-- 1 livibetter livibetter 162117 Aug 28 11:38 http:--userserve-ak.last.fm-serve-174s-50562771.png
-rw-r--r-- 1 livibetter livibetter 471950 Aug 29 09:14 http:--userserve-ak.last.fm-serve-300x300-50562771.png
-rw-r--r-- 1 livibetter livibetter 9718 Aug 21 23:53 http:--userserve-ak.last.fm-serve-64s-50562771.png
lrwxrwxrwx 1 livibetter livibetter 78 Aug 29 09:19 large.png -> /tmp/lf-images/http:--cdn.last.fm-flatness-catalogue-album-jewelcase_large.png
lrwxrwxrwx 1 livibetter livibetter 79 Aug 29 09:19 medium.png -> /tmp/lf-images/http:--cdn.last.fm-flatness-catalogue-album-jewelcase_medium.png
lrwxrwxrwx 1 livibetter livibetter 78 Aug 29 09:19 small.png -> /tmp/lf-images/http:--cdn.last.fm-flatness-catalogue-album-jewelcase_small.png

As you can see, it creates symbolic links, so you can always get the current song’s cover art at /tmp/lf-images/{small,large,medium,extralarge}.png. In the example above, there is no extra large image. The other files are cached, so this script won’t download multiple times for same image.

Second $execi is to get the playcount, it has nothing special if you know shell script.

The $execpi is to create a Conky $image variable, still nothing too special.

2   Notes

I haven’t tested this script seriously, you may see some error which I clearly haven’t met. If so and you want it to get fixed, please provide your Last.fm username, song’s title and album. These information is enough for me to reproduce the issue.

And if you are interested in the song from the screenshot above, its page on Last.fm is here, I also wrote about it few days ago.

3   Updated: Showing Love status

If you also want to show the love status like:

http://farm2.static.flickr.com/1061/5155271854_c5ea850aba.jpg

Be sure to read this follow-up post. <3

Just finished this hours-project. I happened to read this thread and know the FIGlet and TOIlet, hours later, I am showing you MPDisp. I used FIGlet not TOIlet because TOIlet doesn't support center aligning. Here is a screenshot:

MPDisp

You can read and download the code. The only dependency should be FIGlet (do I really need to say you need MPD?). It doesn't rely on (nc)mpc(pp), it contacts MPD directly. All it does is show the song information and give you a little bit of control, see the key list:

  • p - Pause/Resume
  • Enter - Play
  • s - Stop
  • n - Next song
  • p - Previous song
  • r - Repeat mode on/off
  • S - Single mode on/off
  • R - Random mode on/off
  • q - Quit
  • Q - Quit with MPD
I was thinking to use TOIlet, it has a feature called filter, which can render with colors. But it can't align text center. I might try to see what I can do to next.

The only problem I have seen is if you have too small window, text will be messed up, and I am not intended to solve it right now.