How to: Use media keys to control XBMC in the background
#1
Hello,

I am a relatively heavy user of XBMC, and I have it set up as my main media player, as well as a media centre.

I have a Logitech keyboard that has dedicated play/pause, previous and next buttons. For a while I have been frustrated that XBMC would only respond to them while it had focus. If I was working in another program I'd have to switch back to XBMC, in which case I might as well use XBMC's own keyboard commands. Hence I decided to do some digging and try to find a solution.

A quick search on Google revealed that a handful of people were looking for the same thing and that the usual response was a suggestion to use EvenGhost. I've never used this software so I can't comment on it, however I wanted a neater solution that didn't need additional programs running all the time. The best way round this seemed to be to use the new JSON API for XBMC.

It turns out that you can send HTTP JSON commands to XBMC directly from a browser by typing them into the address bar like this[1]:
Code:
http://127.0.0.1:8080/jsonrpc?request={""jsonrpc"": ""2.0"", ""method"": ""Player.PlayPause"", ""params"": { ""playerid"": 0 }, ""id"": 1}

Note that 127.0.0.1 is the IP address of the machine you want to control (in this case the localhost address refers to the computer sending the requests) and 8080 is the port set in XBMC for HTTP control. I imagine user credentials could be inserted here if necessary, but I haven't tried it.

Alternatively a .url shorcut can be used, but this still opens a browser which prompts you to download the response from the JSON request as a file. Scripting seemed the answer, and using VBScript I was able to silently send the HTTP request to XBMC[2]:
Code:
On Error Resume Next
Set web = CreateObject("MSXML2.XMLHTTP")
web.Open "GET", "http://127.0.0.1:8081/jsonrpc?request={""jsonrpc"": ""2.0"", ""method"": ""Player.PlayPause"", ""params"": { ""playerid"": 0 }, ""id"": 1}", False
web.Send
Edit: Checking for errors will prevent problems if XBMC isn't running when the script is executed.

Finally I needed the Logitech SetPoint software to call the script when the appropriate key was pressed, and I achieved this by editing the settings file located at %appdata%\Logitech\SetPoint\user.xml. I replaced the Handler node for the MM PLAY button with the following:
Code:
<Handler Class="FileLauncher">
  <Param BrowseType="1" FileName="C:/Program Files/Scripts/Play-pause.vbs" LookupPath="0" Parameters="" ShowUIDlg="1" Title="Select Program"/>
</Handler>

With similar setup for the previous and next buttons I have control over listening to music in XBMC, without having to constantly switch windows. The same effect can be achieved on other keyboards using a small AutoHotkey script to bind the key presses , but this does mean you have to have additional software running. For the sake of completeness here is the script I used on my laptop:
Code:
Media_Play_Pause::Run "C:\Program Files\Scripts\Play-pause.vbs"
Media_Prev::Run "C:\Program Files\Scripts\Previous.vbs"
Media_next::Run "C:\Program Files\Scripts\Next.vbs"

All of the XBMC API commands can be found on the wiki, and the three I used for play/pause, previous and next are[3][4]:
Code:
{""jsonrpc"": ""2.0"", ""method"": ""Player.PlayPause"", ""params"": { ""playerid"": 0 }, ""id"": 1}
{""jsonrpc"": ""2.0"", ""method"": ""Player.GoTo"", ""params"": { ""playerid"": 0, ""to"": ""previous"" }, ""id"": 1}
{""jsonrpc"": ""2.0"", ""method"": ""Player.GoTo"", ""params"": { ""playerid"": 0, ""to"": ""next"" }, ""id"": 1}

I hope people will find this information useful. Let me know if you have any problems getting it working.

Cheers,
Jon

References
1. http://forum.xbmc.org/showthread.php?tid=154126
2. http://stackoverflow.com/questions/20475...get-in-vbs
3. http://wiki.xbmc.org/?title=JSON-RPC_API#Examples
4. http://wiki.xbmc.org/index.php?title=JSO.../v6#Player
Reply
#2
Thank you muchly!

I wrote up a pure AutoHotKey solution to this, in hopes of improving latency a bit over launching VBScript all the time. Here it is.

Code:
#InstallKeybdHook
#NoEnv

XHR := ComObjCreate("MSXML2.XMLHTTP")
Base := "http://127.0.0.1:8090/jsonrpc?request="
PlayPause := Base . "{""jsonrpc"": ""2.0"", ""method"": ""Player.PlayPause"", ""params"": { ""playerid"": 0 }, ""id"": 1}"
Skip := Base . "{""jsonrpc"": ""2.0"", ""method"": ""Player.GoTo"", ""params"": { ""playerid"": 0, ""to"": ""next"" }, ""id"": 1}"

#UseHook On
Media_Play_Pause::
XHR.open("GET", PlayPause, false)
XHR.send()
return

+Media_Play_Pause::
XHR.Open("GET", Skip, false)
XHR.Send()
return

The last section, in the absence of an actual Skip or Next button on my keyboard, uses Shift + Play/Pause for the purpose.
Reply
#3
(2016-02-13, 07:54)TuggyNE Wrote: I wrote up a pure AutoHotKey solution to this

That's interesting since I ended up doing the same so that I could use one compiled AHK script with multiple devices equipped with media keys. However, I included a library to handle the HTTP requests, which seems a bit heavy-handed since your example achieves the same thing in a few lines using a COM object. I might see if I can get my script working using this instead.

Cheers,
Jon
Reply

Logout Mark Read Team Forum Stats Members Help
How to: Use media keys to control XBMC in the background2