Tools used:
- SIMBL
- Xcode
- class-dump
- Spotify Menubar Source
- spotAPI (SIMBL plugin for global shortcuts)
- JRSwizzle
- Remoteless
- Despotify (not used, but good to read)
Intro
This covers a large amount of what I was thinking when playing about with Spotify Menubar (SM).
I always wondered whether I should try to market SM, on the app store that is. A few friends suggested throwing it up there for 59p and just seeing what happens. I might still do this… when I have £60 for the app store license. Though it is open source and pretty much anyone can just build it themselves. =/ But the app store is about ease, right?
I have occasionally checked the app store for anything Spotify related and nothing came up until recently.
This is kind of interesting to me, considering it is pretty much the same thing. I don’t want to bash it at all. I think it’s great that someone has given it a shot, considering my interest in Spotify has seemed to dwindle. I think the idea is there, but it doesn’t really work for me. The productivity advantage is what I was looking for and having to open a window (view) and navigate to the pause button is effectively the same as alt+tab’ing to spotify, hitting space and hiding it again.
There is also Cockpit by Green&Slimy. Although this costs £16, it has a Spotify controller plugin (clickable controls and shortcuts) and is also a controller for pretty much anything.
A side note: the other day I managed to find out that to get iTunes playlists into Spotify you just need to drag the playlist from iTunes and drop it into Spotify – nice one. :)
What to do with SM (or a Spotify Controller) - SIMBL
The most requested feature for SM was to take it out of the menubar and put it somewhere else. Since it could either be in the dock or the menubar I took this to mean remove it completely from the UI. There are a couple of options that really make this possible:
- Make it a prefpane
- Make it a SIMBL plugin
A SIMBL plugin is a better option. A prefpane would be a little irritating: having to open up preferences>prefpane just to turn it on/off or make changes. There is also the option to remove the dock icon and menubar icon and just have it as a background process. This also strikes me as a bad idea (for usability).
A SIMBL plugin then. What can we do-what information can we get–via a SIMBL plugin. The simple answer is: a lot. With SIMBL, the app is only active when Spotify is active so there is no need to control opening and closing. We also get access to some neat Spotify functions that I’ll come back to in a bit. The only problem is people need to install SIMBL. SM could install the plugin if possible; I don’t think the app store lets apps install other things (?).
The way SM works is by effectively assigning global shortcuts to local shortcuts. This means that only actions that can be performed by a shortcut in Spotify can be performed by SM; an unfortunate limitation. In the SIMBL plugin (spotAPI) I have pretty much recreated the core of SM, creating global hotkeys that trigger keys for Spotify. Though it is much easier from inside of Spotify.
Starring the currently playing song was also asked for a lot. Unless Spotify has a built in shortcut for it, it would not have been possible.
A peak into the inside of Spotify.
Using SIMBL, class-dump and JRSwizzle (JRS) we can have a bit of fun with Spotify and change a few things. Now, I am not a master at any of this and have figured it out in the spare time I was able to spend on SM. Some of the following is also probably not very safe. My plan was to create some sweet and easy functions for me to call to control or read from Spotify: hence spotAPI is somewhat a playground for me to play in.
From terminal (where it would be wise to make a temp directory and cd to it):
class-dump -H <Path to Spotify Executable>
This dumps out a bunch of header files into the current directory. Some of the ones I have found interesting:
- CDStructures.h - Struct definitions.
- *Growl*.h - Intercepting Growl communication.
- SPController.h - The good stuff.
There is an example of using JRS to swizzle the growl notification and intercept it in the source for spotAPI. With JRS we can do the following to swizzle a method:
Class spgrowl = NSClassFromString(@”SPGrowlDelegate”);
Method notification = class_getInstanceMethod(spgrowl, @selector(notificationWithTrackInfo:));
Method swizNotification = class_getInstanceMethod([self class], @selector(swizNotificationWithTrackInfo:));
method_exchangeImplementations(notification, swizNotification);
This is a simple example, but is great because we know how to send information to Growl anyway. It is pretty much a man-in-the-middle attack (or at least I’m looking at it like that), except Growl doesn’t care what it’s getting anyway and it just wants to display something-and we’re already in the Spotfiy process. ;)
The plan here was to just throw out the currently playing song on a distributed notification centre each time there is a change (growl notification). from this an app that shows the currently playing song … Bowtie … could show the song playing in Spotify.
Out of curiosity I also used the SIMBL plugin for Remoteless (iPhone app). Their SIMBL plugin throws out the now playing and artwork, though they mention that some of it relies on image recognition. I can see how image recognition could be used, being much easier on text in a non-cursive and known font than HWR ( :< ), or for grabbing the artwork. Either way, it was much easier to borrow their plugin. :) If you use Spotify and want a remote, it’s pretty good.
Thinking about it.
There’s a lot that can really be done to SM. Searching songs, making use of metadata, hovering controls, anything you really want out of a controller. Ultimately, I would have loved Spotify integration in Bowtie: with the lush visuals and ease. It really just came down to time and the need. I tried to keep this post as a summary, rather than an in depth explanation of everything I tried and I hope it is readable considering it is one of my early attempts. A post going over the final commit will follow soon.
I decided to stop working on Spotify Menubar (SM). For a few reasons: I bought a keyboard that has the built in play/pause and skip buttons, which is why I made Spotify Menubar in the first place, and I have stopped using Spotify to listen to music and gone back to iTunes to built up a music collection again. Between this and not really having the time to seriously update it, I feel I should stop now. Spotify has it’s pros, but I mostly used it for the social features, which I still do, just that I play any music from iTunes.
There were a few features I’d have liked to add to SM, but all required me to make some big changes to the way it works. I’ll go over this in the next post.
Thanks for sending encouraging emails about SM, I tried to reply to all and sorry if I missed yours.
A brief discussion and overview of my last commit can be found at these links: