tadhg.com
tadhg.com
 

AutoHotkey Script for Last.fm

23:54 Fri 23 Mar 2007. Updated: 09:20 03 Apr 2007
[, , ]

My site is down at the moment, but the blog posting goes on…

I’ve been playing with AutoHotkey (which I highly recommend), and automating some things that I should have had working a long time ago, like a hotkey for pausing WinAmp (someone else has written a WinAmp script for AutoHotkey). After getting used to that, I decided I wanted one for the Last.fm player, so I wrote it.

For those of you wondering about what AutoHotkey is, it’s essentially a scripting environment for Windows with a good hotkey-management system built in, allowing you to run programs with a single key combination. As well as launching applications, you can manipulate them in other ways, as with this Last.fm player script.

The script can take the following commands:

  • “Toggle” to switch between playing and stopping.
  • “Skip” to skip the current track.
  • “Profile” to toggle the “My Profile” panel.
  • “Recommend” to open the recommendation dialog.
  • “Tag” to open the tag dialog.
  • “Love” to mark the current track as loved.
  • “Ban” to mark the current track as banned.
  • “IsPlaying” to mark the current track as banned.

Using AutoHotKey, I’ve assigned these keys to it:

#^NumpadMult::ControlLastFM("Toggle") ; Winkey + Control + Numpad Star to toggle
#^NumpadDiv::ControlLastFM("Skip") ; Winkey + Control + Numpad Slash to skip

It took me a while to figure out how to make it work, and I really needed the “Window Spy” utility that comes with AutoHotKey to find out what certain widgets were. Specifically, figuring out how to tell AutoHotKey to tell the player to do anything was very tough, and it took at least an hour of experimentation before I found the correct combination of ControlClick and the “ClassNN” value for the various controls (as opposed to their “HWND” value, or their text).

At the moment, I’m working on a combination script, one that detects whether Last.fm or WinAmp is currently playing, pauses the one that is, and then later resumes that one. All from one shortcut. I think the pieces are all there, and hopefully I’ll have that done soon.

This is the Last.fm controller script (download it here):

; AutoHotkey Version: 1.x
; Language:       English
; Platform:       Win9x/NT/2000/XP
; Author:         Tadhg O'Higgins
; Site:             http://tadhg.com/
;
; Script Function:
;	Controls the Last.fm player
;

;Last.fm Control Functions
ControlLastFM(Command) {
        ;Valid values for Command:
        ;       "Toggle" to switch between playing and stopping.
        ;       "Skip" to skip the current track.
        ;       "Profile" to toggle the "My Profile" panel.
        ;       "Recommend" to open the recommendation dialog.
        ;       "Tag" to open the tag dialog.
        ;       "Love" to mark the current track as loved.
        ;       "Ban" to mark the current track.
        ;       "IsPlaying" to return 1 if it's playing and 0 otherwise.
        
        ;Last.fm player widget values:
        Toggle := "QWidget2"
        Skip := "QWidget5"
        Profile := "QWidget14"
        Recommend := "QWidget12"
        Tag := "QWidget11"
        Love := "QWidget9"
        Ban := "QWidget8"
        Station := "stationTimeBar"
        
        ;Get the variable value (using the above list kind of like a HashMap, or JavaScript object in the object["keyname"] style).
        CommandRef = % %Command%
        
        ;Make sure the window exists.
        IfWinNotExist, Last.fm
                return
        else {
                ; Toggle and Profile don't need to know if it's playing a the moment or not.
                if (Command == "Toggle"||Command == "Profile") {
                        ControlClick, %CommandRef%, Last.fm, , , , NA
                } else {
                        ;Find out whether it's playing at the moment.
                        ControlGet, lfmPlaying, Visible, , stationTimeBar, Last.fm
                        
                        ;If we just want to know whether it's playing or not, return that.
                        if (Command == "IsPlaying") {
                                return %lfmPlaying%
                        }
                        ;If it is playing, apply the command.
                        if (lfmPlaying == 1) {
                                ControlClick, %CommandRef%, Last.fm, , , , NA
                        }
                        if (lfmPlaying == 0) {
                                ;Do nothing.
                        }
                }
        }
        
        return
}

15 Responses to “AutoHotkey Script for Last.fm”

  1. kevintel Says:

    The Mac has something like it too, I think it’s a program called BSD which has a ‘perl’ command to make other programs do stuff but it’s not as good. Thing is now you can run Windows on the Mac since Microsoft bought out iMac a few years ago, so you can use all the Windows commands in Apple now.

    I don’t understand why iMac still makes it all look funny though.

  2. Tadhg Says:

    I’m not completely sure, but I think that Kev’s pointing and laughing at the paucity of Windows scripting when compared to the options in OS X.

    And AutoHotkey, while powerful and useful and really great to have, is painful to code with in a number of ways, and doesn’t really compare to either scripting in Terminal or (I suspect) to writing equivalent scripts in Cocoa.

  3. Matt Says:

    Nice script, one change I had to make to mine so I could use it from within WoW (my reason for looking for this). Perfect though, now I can skip the horrible songs without crashing my game. ;)

    The action line needs to say:
    ControlClick, %CommandRef%, Last.fm , , , , NA

    So that it won’t alt-tab out and focus on the window. Works great. At the end of the file for my hotkeys I just put:

    ; Shift-Ctrl-L to love
    ^!l::
    ControlLastFM(“Love”)
    return

    ; Shift-Ctrl-B to ban
    ^!b::
    ControlLastFM(“Ban”)
    return

    ; Shift-Ctrl S to skip
    ^!s::
    ControlLastFM(“Skip”)
    return

  4. Tadhg Says:

    Matt: thanks for the suggestion, I’ve incorporated it into the script. Glad you found it useful!

  5. Matt Says:

    I’ve still been using this script alot, I have a new addition that I’ve also been using for audio confirmation that the hotkeys actually happen and I hit the right keys. ;) (I don’t trust anything) Was on the autohotkey forum. I orginally wanted this so that it could say the title and author of the track, but this data, hidden behind all of these QWidgets seems unattainable. You can’t even copy and paste anything that I’ve tried. I tried searching through memory to find where this is stored but didn’t know enough about this at the time. :( Would love this ability.

    Throw that script at the top of the files (Win 2K/XP), add the line

    say(Command)

    right after the lines where it says

    IfWinNotExist, Last.fm
    return
    else {
    say(Command) .

    and it will say the command to you. Very cool!

    ;http://www.autohotkey.com/forum/topic4828.html
    say(string)
    {
    FileAppend,
    ( LTRim
    Dim voic
    Set voic = WScript.CreateObject(“SAPI.SpVoice”)
    Set voic.voice = voic.GetVoices(“”, “Language=809″).Item(0)
    voic.Speak(“%string%”)
    Set voic = nothing
    ), %A_ScriptDir%\lastfm.vbs
    RunWait, WSCRIPT.EXE “%A_ScriptDir%\lastfm.vbs”,,, WSCRIPT_PID
    FileDelete, %A_ScriptDir%\lastfm.vbs
    }

  6. Tadhg Says:

    Matt: thanks for the new addition—I haven’t tried it out yet because I’ve been using Songbird instead of WinAmp, and haven’t yet determined how to control it with AHK. In addition, the most recent update of the Last.fm player seems to have broken my script, so I have some work to do on it.

  7. Matt Says:

    Yea :/ I hacked up a version that ‘works’ with the new version and actually has a feature I’ve wanted, but its far from perfect. I’d say it works out better for me though but its got some serious hacks in it because I think theres still some bugs in autohotkey, cause I can’t get controlget to work on pid’s, id’s, classes… Ah well. I’ll email it to you, but I think we’re the only people that are looking at it. Songbird, haven’t heard of it.

  8. Tadhg Says:

    Matt: that new version would be helpful, you can get me at tadhg @ (this domain).

    Songbird is a music player based on the Mozilla XUL platform that I’m trying out at the moment. It’s not bad. Nowhere near as good as WinAmp, but on the other hand it’s open source.

  9. kevintel Says:

    I’m right with you there, Tadhg. I always pick ideologically sound software before quality products that are best for my needs. That way, what I lose in productivity helps some rabid old crusty think he can change the world.

  10. Tadhg Says:

    Kev: hahahaha. Well, in actual fact what I’m trying to avoid is the lost productivity that comes from the proprietary app at some point in the future no longer doing what I want, in a variety of ways…

    Proprietary software, whether you care to admit it or not, carries with it a number of risks that are not present in software libre. That’s on top of the “ideological” issues. My take on software is that in principle it’s better (ethically/morally) to use free rather than proprietary software. In practice I use proprietary software where the inconvenience or quality dropoff is too high for me at the moment. This doesn’t stop me from looking around for open source alternatives, which is what I’m doing with Songbird.

    I don’t expect to convince you on this point, because you apparently believe that no ethical/moral considerations exist,and that the only consideration one should apply when picking applications to use is the extent to which they solve your problem (i.e. how good they are as apps). You might agree that if there were no difference in quality, the open source one is the one to be used (you might not). My stance is quite different, and I am willing to put up with some quality dropoff in order to use free software. In most cases I don’t have to put up with much dropoff.

    Incidentally, my long-term productivity has risen, not fallen, due to my interest in open source technologies—that interest has forced me to learn a bunch of things I would otherwise not have learned, and those new skills have made me a more productive computer user. So doing the right thing in this sphere has also been beneficial for me.

    I assume your reference is to Stallman. If so, it’s a little off—like him or not, rabid old crusty or not, crazy loon or not, Stallman has already had a profound, and highly beneficial, impact on the world. A lot of things you use every day might not have existed at all if not for GNU tools, and a lot of things wouldn’t have come to be without his (completely radical at the time) insistence that software should be free-as-in-speech. So, nice try with the CyniSpeak, but the truth is that the issues raised by the free software movement—which boil down to “who controls the infrastructure?” and “who controls the information?”—are both important and amenable to influence by individuals. My choice of software application has almost no impact on its own, but then most of the time that I act according to principle the same is true. That’s not a reason to act otherwise.

  11. kevintel Says:

    But that’s my point too, Tadhg. I agree with you. The thing about proprietary software is that even though it might work better today, it’s just a ploy to draw you into their nefarious plans to control you and your data by providing you with quality software that does what you want. I’ve had to deal with this before myself; iTunes has tricked me into using an iPod! Once I had it I thought I could turn the iPod into something else, like a blender because that would be handy in the kitchen, but apparently I can’t because it’s a small portable music player and it’s going to stay that way thanks to iTunes (which is closed-source software).

    All your EULAs are belong to us!

    Actually, on a more serious note: you’re going to put up some shelves. So, you need a hammer, and you go to the hardware store. In the hardware store there is a good quality Stanley hammer, some other medium-quality hammers, and a cheap but somewhat shoddy G00znr hammer from some guys who make them part-time (during the day-job they make saws for… Stanley) which you’ll have to assemble yourself. Anyway, to make the ethical choice, you buy the G00znr hammer, take it home, spend a couple of hours assembling it and setting it up, and eventually get 2 of your 4 shelves up (one has been destroyed during the learning process, and you ran out of time and got too fucked off before putting up the last one). But you know what, if everybody used a G00znr hammer, we’d get used to putting less stuff on shelves, and the world might be a better place. The guys at Stanley would be out of jobs, and have more free time to improve the G00znr hammer. Maybe we might find we don’t need shelves, and we can start asking ourselves “Where do nails come from?”.

    Q: How many Open Source advocates does it take to change a lightbulb?
    A: Maybe the real question is, ‘do we need light?’, because the lightbulb is a proprietary non-open system, we should explore alternatives to light which negate the need to use lightbulbs. ..

  12. Tadhg Says:

    Kev: just like last time, I’m having a hard time figuring out what your position here is. You could try stating it clearly instead of using analogies or parodies of other people’s standpoints.

    For reference, here’s a clear statement of my position on the subject:
    I believe that software freedom is important, that the freedom to improve, customize, and share programs is one that significantly benefits the entire computer-using population, and that because of this openness is a factor when determining what software to use—a significant enough factor that it will sometimes outweigh functional considerations.

    Attempting to extract viable arguments from your first paragraph, I come up with the following:
    1. It’s ridiculous to consider notions of infrastructure/information control when using proprietary software because those companies are too focused on providing quality software to bother with that kind of thing.
    2. Given that point 1 makes it unnecessary to consider issues of control, there’s no reason at all not to use proprietary software if it’s “higher-quality” than competing free software.
    3. Free software supporters (like myself) are crazed zealots who make utterly unreasonable demands on proprietary applications (or, perhaps, on everything), seeking to expand/alter their functionality beyond all recognition.

    You’re wrong about point 1. You can call it tinfoil-hat propaganda all you like, but the fact is that proprietary software gives its owners the power to lock in users in a variety of ways that the users tend to find unpleasant. You can argue that the market punishes such behavior, and in many circumstances it does, but not in all, and I prefer to avoid (where possible) getting into a situation where I have to depend on the market for such protection. A fairly obvious example of this is the incompatibility between versions of Microsoft Word, which is used by Microsoft to force people to upgrade. Microsoft has the right to do this, but I see no reason to willingly put myself into that trap.

    As you’re wrong about point 1, your point 2 clearly also suffers, but there is a larger question there, of the degree to which an application being open should influence a decision to use it, beyond other factors such as functionality. It should be clear that if there is no difference in functionality, or if the proprietary software lacks functionality, one should choose the free software application. Beyond that, the question is the extent to which one should give up “quality” for openness. I believe that this extent should be significant, but it’s not easy to quantify precisely. There is a practical (meaning non-moral) aspect to this also: my support of a free software application makes it more likely that the application will improve over time. I started using Mozilla fairly early, and it was functionally worse than IE at the time. Now its descendant, Firefox, is far superior, functionally. So it made practical sense for me to put my support behind the project early, despite the inconvenience, because it helped to get to a much better product later.

    Point 3 is an ad hominem attack pandering to stereotypes. What I tend to want out of software is quite reasonable indeed—apart from the freedoms to modify and share themselves, which you apparently consider unreasonable. But beyond those, I tend to want things that will be useful to me in the actions that the software is supposed to be helping me with. In this, I am quite probably typical of most users who prefer free software.

    Your hammer analogy is laughably bad. Really. Almost any analogy using a physical object is bad, but wow, this is one of the worst. Primarily because hammers are simple objects, whereas software applications are not, but also because hammer production requires significant resources per hammer, involves economies of scale, and so on—factors that do not apply to software.

    Further, hammers are much more like open-source programs than they are like proprietary programs. Hammer too slippery? Add some grip tape—done. Handle too long? Saw some off. Proprietary programs tend not to allow modifications of this sort.

    The key point of your terrible analogy seems to be mockery of not using the best tools for a given project. There are terrible tools out there regardless of whether they’re proprietary or not. If you’re making the argument that free software applications are worse than proprietary ones, good luck. There are too many areas where the reverse is true to make that a reasonable conclusion. If you’re making the argument that you should never use anything but the best tool for the job, I addressed that above—there are advantages in the long term to using the free software tools, and each user needs to make their own determination regarding what tradeoffs they will accept. Personally, I accept some but not all, which is why I don’t, for example, use the GIMP. But I would prefer not to become dependent on any further proprietary software if I can avoid it.

    Lastly, that attempt at a lightbulb joke is just awful. The lightbulb is a classic example of an open standard. Everybody knows how it works, how to make one is well known, they’re quite standardized, specifications are readily available, etc. The typical lightbulb is an open, non-proprietary system! Even if this were not the case, the advocates would hardly argue that we don’t need light, they’d try to come up with alternative methods for light provision, some of which would fail, others of which would work, etc. In any case, way off the mark. You could at least have tried something like: “How many Open Source advocates does it take to change a lightbulb? None—they’d tell you to heat your own damn filament.” That approach would at least play on the fact that open source types have tended to be less concerned with ease of use.

    Regardless of all that, I just don’t see that you’re making any decent case at all for why I shouldn’t decide to try out Songbird instead of WinAmp even though I consider WinAmp to currently be a superior music player. Also, you appear to have not addressed any of the points from my last reply.

  13. jeremiah Says:

    When I got this working on my computer, I had to make some changes to it since Last.fm no longer appears in the title bar of the app. Here’s what I ended up with:

    ; Au; AutoHotkey Version: 1.x
    ; Language: English
    ; Platform: Win9x/NT/2000/XP
    ; Author: Tadhg O’Higgins
    ; Site: http://tadhg.com/
    ;
    ; Script Function:
    ; Controls the Last.fm player
    ;

    ;Last.fm Control Functions
    ControlLastFM(Command) {
    ;Valid values for Command:
    ; “Toggle” to switch between playing and stopping.
    ; “Skip” to skip the current track.
    ; “Profile” to toggle the “My Profile” panel.
    ; “Recommend” to open the recommendation dialog.
    ; “Tag” to open the tag dialog.
    ; “Love” to mark the current track as loved.
    ; “Ban” to mark the current track.
    ; “IsPlaying” to return 1 if it’s playing and 0 otherwise.

        ;Last.fm player widget values:
        Toggle := "QWidget2"
        Skip := "QWidget4"
        Profile := "QWidget14"
        Recommend := "QWidget12"
        Tag := "QWidget11"
        Love := "QWidget9"
        Ban := "QWidget8"
        Station := "stationTimeBar"
    
        ;Get the variable value (using the above list kind of like a HashMap, or JavaScript object in the object["keyname"] style).
        CommandRef = % %Command%
    

    ; IfWinNotExist, Last.fm
    ; MsgBox I can’t see a Last.fm window

    ; IfWinExist, , Last.fm
    ; MsgBox I found it

        ;Make sure the window exists.
        IfWinNotExist, , Last.fm
                return
        else {
                ; Toggle and Profile don't need to know if it's playing a the moment or not.
                if (Command == "Toggle"||Command == "Profile") {
                        ControlClick, %CommandRef%, Last.fm, , , , NA
                } else {
                        ;Find out whether it's playing at the moment.
                        ;ControlGet, lfmPlaying, Visible, , stationTimeBar, Last.fm
                        ControlGet, lfmPlaying, Visible, , QWidget72, , Last.fm
    
                        ;If we just want to know whether it's playing or not, return that.
                        if (Command == "IsPlaying") {
                                return %lfmPlaying%
                        }
                        ;If it is playing, apply the command.
                        if (lfmPlaying == 1) {
                                ;ControlClick, %CommandRef%, Last.fm, , , , NA
                                ControlClick, %CommandRef%, , Last.fm, , , NA
                        }
                        if (lfmPlaying == 0) {
                                ;Do nothing.
                        }
                }
        }
    
        return
    

    }

    ; Ctrl+Alt+L to love
    ^!l::
    ControlLastFM(“Love”)
    return

    ; Ctrl+Alt+B to ban
    ^!b::
    ControlLastFM(“Ban”)
    return

    ; Ctrl+Alt+S to skip
    ^!s::
    ControlLastFM(“Skip”)
    return

  14. Tadhg Says:

    Jeremiah: Thanks for your contribution, I haven’t had a chance to play with it yet, I’ll try to use it soon!

  15. Manually route a global keyboard shortcut to a specific application on Windows7? Drija Says:

    [...] This script was reccomended by Lifehacker, and looks pretty good to me. Never used last.fm, so that’s all I’ve got [...]

Leave a Reply