You are not logged in.

#1 2008-06-05 13:18:20

Kane
Member
Registered: 2006-10-08
Posts: 220

Help with dynamic playlist for mpd

Hi guys,
I use mpd with sonata for playing my music, and after trying exaile there is one thing id really like for mpd, and that is the dynamic playlist function.
When you're playing a song in exaile with dynamic playlist enabled, it queries audioscrobbler and automatically adds similar artists/songs to your playlist (if you have them on your pc).
I dont want to use exaile as it just feels too big and slow and bloated (not KISS tongue), i know a little bit of python so i thought i'll try and make my own little script/program as Sonata has audioscrobbler support, but i dont think there is anyway to query similar artists.
I think im going to try and make this as a daemon type program that will run in the background adding songs to the playlist.

Ive found the code from the exaile source (audioscrobbler.py) which queries lastfm e.g.

>>> lips = AudioScrobblerQuery(artist='The Flaming Lips')
>>> for artist in lips.similar():
...     print artist.name, artist.mbid

This will print a list of similar artists to the flaming lips.

I've not done much with python so i thought this would be a good way to try and improve.

Does anyone have any suggestions as to what the best way to go about searching and comparing the results to my mpd database, would the best way just to be to search the mpd.db?

And if anyone else has any ideas/comments id like to hear them.

Edit:
I just found this too, so i may only need to change some things to integrate it with mpd rather than amarok
http://www.kde-apps.org/content/show.php?content=31920

Thanks

Last edited by Kane (2008-06-05 13:24:33)

Offline

#2 2008-06-05 15:31:11

burk
Member
From: Norway
Registered: 2007-06-17
Posts: 46

Re: Help with dynamic playlist for mpd

You could use mpc search, check the mpc manual to see how to use it smile

Offline

#3 2008-06-05 15:43:14

Kane
Member
Registered: 2006-10-08
Posts: 220

Re: Help with dynamic playlist for mpd

i was thinking of using mpc, as thats what im using bound to my ati_remote, but then i found python-mpd smile which should make things "cleaner"

ive got this so far, sorry if it hurts your eyes, but i havnt done any programming in a loooong time.

import audioscrobbler
import mpd


client = mpd.MPDClient()
client.connect("localhost", 6600)
#print client.mpd_version
#print client.status()
cursong = client.currentsong()
print cursong['artist'] + " - " + cursong['title'] + "\n"


test = audioscrobbler.AudioScrobblerQuery(artist=cursong['artist'])

artistlist = []
i = 1
for artist in test.similar():
    aname = artist.name
    print aname
    artistlist.append(aname)
    i = i + 1

#    print artist.name

print "\n\n\n"

for i in range(0,5):
    print artistlist[i]


client.disconnect()

Just a bit of testing.
Ive got the top 5 similar bands, now i just need to get their top track list, and search mpd database to find a match, then add it smile

Last edited by Kane (2008-06-05 15:44:36)

Offline

#4 2008-06-05 17:59:02

stonecrest
Member
From: Boulder
Registered: 2005-01-22
Posts: 1,190

Re: Help with dynamic playlist for mpd

For what it's worth, there is a pending patch to implement this for Sonata, but I haven't tried it or looked at it yet.

https://developer.berlios.de/patch/?fun … up_id=7323


I am a gated community.

Offline

#5 2008-06-05 18:05:42

Kane
Member
Registered: 2006-10-08
Posts: 220

Re: Help with dynamic playlist for mpd

So ive been waiting for this for how many months, and now i decide to have a go ..... typical tongue lol.

I actually think i remember seeing that patch a while ago,
lets see if i can get it working smile

Thanks

Offline

#6 2008-06-05 22:23:16

Kane
Member
Registered: 2006-10-08
Posts: 220

Re: Help with dynamic playlist for mpd

hmmm nope,

In the patch file thats posted on http://developer.berlios.de/patch/download.php?id=2419
there is more than 1 file that needs to be patched (i think) but ive not done much patching, so do i just put the whole raw patch from the link in a file and call it something like patch1 and then in the sonata PKGBUILD add something like patch < patch1 ?

Sorry if this is a really dumb question
Thanks

Offline

#7 2008-06-05 22:35:51

droog
Member
Registered: 2004-11-18
Posts: 877

Re: Help with dynamic playlist for mpd

on the bottom of this page it shows how to apply patches in makepkg its pretty easy, add the patch to source array then patch -p1 -i ../nameof.patch | return 1 to the build.

http://wiki.archlinux.org/index.php/Patching_in_ABS

Offline

#8 2008-06-05 22:55:33

Kane
Member
Registered: 2006-10-08
Posts: 220

Re: Help with dynamic playlist for mpd

ive done that but when i try and apply the patch i get:

patch -p 1 -i as.patch 
can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|Index: sonata/audioscrobbler.py
|===================================================================
|--- sonata/audioscrobbler.py    (revision 793)
|+++ sonata/audioscrobbler.py    (arbetskopia)
--------------------------
File to patch: sonata/audioscrobbler.py
patching file sonata/audioscrobbler.py
Reversed (or previously applied) patch detected!  Assume -R? [n]

Offline

#9 2008-06-05 23:58:38

Kane
Member
Registered: 2006-10-08
Posts: 220

Re: Help with dynamic playlist for mpd

well i just modified the patch into a little script, it does what i need tongue

its here if anyone wants it

import audioscrobbler
import mpd
import random
import time


lastsong = {}

def timer_control():
    get_similar()
    time.sleep(10)
    timer_control()

def get_similar():
    audioscrobbler
    client = mpd.MPDClient()
    client.connect("localhost", 6600)
    mpdstatus = client.status()
    prevsonginfo = client.currentsong()
    global lastsong
    if mpdstatus['state'] == "stop": return
    if prevsonginfo == lastsong: return 
    
    lastsong = prevsonginfo
    similarartists = ""
    song = prevsonginfo
    #if not song: break #No song, do nothing
    prevartist = song['artist']

    # Is the info already cached?
    similar_cache = {}
    if similar_cache.has_key(prevartist):
        similarartists = similar_cache[prevartist]
    else:
        #Not cached so fetch from Audioscrobbler
        try:
            similarartists = [artist.name for artist in audioscrobbler.AudioScrobblerQuery(artist=prevartist).similar()]
            # Cache search results and save some time next search
            similar_cache[prevartist] = similarartists
        except audioscrobbler.AudioScrobblerError:
            similar_cache[prevartist] = None # Empty cache
            return # Do nothing!

    if not similarartists: return # Empty list

    # Split list in half and sort upper half
    # this means good matches will have priority
    # but makes sure artist A does not always result in artist B
    half_idx = len(similarartists)/2
    upperhalf = similarartists[:half_idx]
    lowerhalf = similarartists[half_idx:]
    random.shuffle(upperhalf)
    artistlist = upperhalf
    artistlist.extend(lowerhalf)
    # Try each artist in order
    for artist in artistlist:
        try:
            print "Trying:",artist
            songs = client.search("artist", artist)
            if not songs: continue
            selected_song = random.sample(songs, 1)[0]
            client.add(selected_song['file'])
            print "Added", selected_song['title'],"by",selected_song['artist']
            # Delete old song from playlist?
            break
        except mpd.MPDError, e:
            print "MPDError", e.message
            continue
        except ValueError, e:
            print "ValueError:",e.message
            continue


timer_control()

Last edited by Kane (2008-06-06 16:22:49)

Offline

#10 2009-09-17 04:30:13

johntramp
Member
Registered: 2006-03-02
Posts: 21

Re: Help with dynamic playlist for mpd

How do we use this script?

Offline

Board footer

Powered by FluxBB