I am having fun trying to control various media programs via their APIs.
Currently, I am concentrating on Spotify, XBMC and iTunes. I run Spotify and iTunes on Microsoft Windows, and XBMC on a Raspberry Pi. I also occasionally run Spotify on Linux. I also control other media devices like the Virgin TiVo and a Kodak photo frame via IR commands, but at the moment I am concentrating on API control.
XBMC has a comprehensive but somewhat quirky http API.
iTunes has a fairly comprehensive COM API on Windows. I believe this is similar to its MAC API, which I have not used. Again, this API is rather quirky, but in different ways to the XBMC API. Getting a set of commands that works for both is challenging.
Spotify is even more challenging, as its API, libspotify, only works with Premium accounts and I only have the cheaper unlimited account. To get round this, I control it via a mixture of http links and remote control of the GUI.
I invoke the http URLs via the Java Desktop.browse() method, which runs the default browser. How the URLs behave depends on which browser is the default, and which versions of Spotify are installed. Things seem to work best with Chrome and setting (the undocumented) URL parameter autoplay=true. Other browsers do not seem to start playlists. I have not investigated this thoroughly.
It also appears that if the web version of Spotify is installed in Chrome, it gets used rather than the full Spotify client. Again, I have not investigated this thoroughly.
I have recently discovered that you can open the Spotify URI (as opposed to the HTTP link) from Java, using Desktop.open() rather than Desktop.browse(). This avoids the extra browser page, but there is still a problem with it. It seems that if the URI identifies a track, that it automatically plays the track, but if the URI is for a playlist, artist, album etc., it does not autoplay. Some people have put in requests for changes to this. It is not much use to me without the autoplay.
I think I will change my Spotify plugin to allow either http links or spotify URIs and use the browse or open method as appropriate. I can then at least use URIs for individual tracks.
Another issue I have with Spotify is that I have to have a store for a map from names to URLs or URIs. I use the config file for this, so each time I want a new playlist, I have to add an entry to the config file. This has advantages and disadvantages. I will investigate if there is any way to do a search for the URLs without using libspotify. The URL/URI scheme is very flexible. I currently just use it for my playlists, but I can use it without change, for tracks, artists, albums, radio stations, other people’s playlist etc.
Yet another problem that I have hit with Spotify and iTunes is that there seems to be a strange Java bug (or feature), that stops me using my Spotify and iTunes plugins in the same instance of HouseControl. As soon as I register the iTunes plugin, the Java Desktop.browse method starts returning Access is Denied, so the Spoify plugin no longer works. I need to narrow this bug down a bit to see if there is a circumvention. The only circumvention I know at the moment is to use two instances of HouseControl on separate ports. (At least, I assume that is a circumvention – I have not tried it).
Getting back to iTunes, the COM API for that seems to work fine.
There are three main things that I want to do:
- Play a playlist
- Search for artists, albums, tracks etc., and play them
- Play a specific edition of a podcast
I use commands:
play playlist and start search-keywords
for the first two of these. Note that these are the commands I use for all media devices and programs, not just iTunes, so I need to make them appropriate for all the media programs and devices.
I have not found an effective way of playing an individual podcast yet. I need some way to find the latest or the unplayed episodes. This needs investigation.
iTunes has an oddity, that it cannot play a track collection. It can play playlists, and individual tracks, but not track collections. Track collections are returned from searches. So to play a track collection, I am currently creating a temporary playlist. This works, but is a bitty messy.
The iTunes search allows you to search specific fields like album, artist, track, genres, etc. or to search all of them. I currently search all the fields. I might need to invent a syntax to search for searching the individually fields.
An oddity, that effects both the iTunes and the XBMC API, is that what is playing is not related to what is playing on the screen, which can be confusing. You have to use separate API calls to play something and then to display it on the screen. I have not decided what o do about this. In fact, I have not tried the iTunes API calls for changing the screen display yet.
I have not added features for creating playlist yet, but renaming the temporary playlist that I create from the iTunes GUI works quite well.
As I said above, XBMC has a comprehensive API, but is has quirks and some bugs.
XBMC has separate players for videos, music and photos. This makes things like skip, play etc. a bit harder as you need to specify which of these types of media you want to manipulate. For music and video, you need to remember which of them is playing. Playing a video and music at the same time is not likely, unless it is a silent video. With photos, however, you can have a slide show and a music playlist at the same time, and you need to specify which you want to skip etc.
I added a player command to support this. It sets the current player, but it is not a very good solution to the problem.
XBMC does many things, including most streaming services, using add-ons written in python. These map quite well onto my services.
Library mode is a strange thing in XBMC. Things work completely differently, depending on whether you are in library mode, or file mode.
The complete separation of what is displayed on the screen from what is playing is also odd.
The configurable skins with their own left hand menu is a bit odd.
The context menu is a bit odd.
The way the database is updated is a bit odd.
Overall, XBMC is powerful, but has a lot of oddities
It is also surprising difficult to use saved playlists in XBMC. The playlist section of the API deals with the current playlist, and not saved playlists. There are two types of playlist in XBMC: smart ones and normal manual ones. To start a saved playlist, you need to know where it is saved. This is a bit system dependent, despite the rather odd special:// syntax. There also seems to be an oddity with saved music playlists, where the latest versions of XBMC seem to think they are photo slideshows and not music and fails to play them. You seem to have to do some advanced configuration to get round this. I am probably missing something with all this, but it is very strange. I still have some work to do to get playlists working.
I don’t use XBMC for broadcast channels, as I don’t know of any way to do that with a Raspberry Pi. I use the Virgin Media TiVo for broadcast TV (and lots more). My use of XBMC is mainly for playing my own music, looking at my photo collection and accessing streaming services not on the Virgin TiVo. Youtube is much more usable on XBMC, than on Virgin TiVo.
Perhaps the Plex fork of XBMC is more logical. It has the reputation of being simpler to use but less configurable. Perhaps I will try it sometime. There is a Rasplex distribution for the Raspberry Pi.
It is quite a challenge to design and implement, a set of commands that works well for all these services.
When I have all this working well, it should be very impressive. I have about 12 different media devices in my living room alone: TV, Raspberry Pi, laptop, netbook, desktop computer, photo frame, Android phone, Android tablet, Wii U, iPod nano, Kindle, PSP. I have more when my family are here. I could issue voice commands to have them all playing different videos, music and photos. I could get one of them to read some poetry by text to speech. I could have the lights flashing in time to the music, and the blinds opening and closing. I could have Keith the robot dancing, and one or two Lego robots playing along. I could have the door bell and smoke alarms following the beat and the fan going on and off. I might make a video of it all.