XBMC’s JSON-RPC API – REALLY Pausing a video

In an earlier post, “Calling XBMC’s JSON-RPC API using Python’s requests library – Pause a video“, I showed an example of pausing the actively playing file using the XBMC JSON-RPC API’s Player.PlayPause method. The problem with this method, as you could probably already tell from its name, is that it acts like a toggle – if the video is playing, it pauses it. If it is already paused, it is unpaused. Great for remote controls, but useless for anything else.

It took quite a bit of searching to figure out how to only pause a file if it is currently busy playing. The answer is to use the Player.GetProperties method to retrieve the “speed” of the currently playing file, which tells us if the file is playing or not. So, to pause we need 3 calls to the API:

– Player.GetActivePlayers to get the actively playing file’s “playerid”
– Player.GetProperties passing the playerid from the response of Player.GetActivePlayers to get the “speed” which should tell us if the file is paused or not
– Player.PlayPause called only if the speed returned is not 0

The code:

import requests
import json
import urllib

#Required header for XBMC JSON-RPC calls, otherwise you'll get a
#415 HTTP response code - Unsupported media type
headers = {'content-type': 'application/json'}

#Host name where XBMC is running, leave as localhost if on this PC
#Make sure "Allow control of XBMC via HTTP" is set to ON in Settings ->
#Services -> Webserver
xbmc_host = 'localhost'

#Configured in Settings -> Services -> Webserver -> Port
xbmc_port = 8888

#Base URL of the json RPC calls. For GET calls we append a "request" URI
#parameter. For POSTs, we add the payload as JSON the the HTTP request body
xbmc_json_rpc_url = "http://" + xbmc_host + ":" + str(xbmc_port) + "/jsonrpc"

#Payload for the method to get the currently playing / paused video or audio
payload = {"jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1}
url_param = urllib.urlencode({'request': json.dumps(payload)})

response = requests.get(xbmc_json_rpc_url + '?' + url_param,
                        headers=headers)

#response.text will look like this if something is playing
#{"id":1,"jsonrpc":"2.0","result":[{"playerid":1,"type":"video"}]}
#and if nothing is playing:
#{"id":1,"jsonrpc":"2.0","result":[]}

data = json.loads(response.text)
#result is an empty list if nothing is playing or paused.
if data['result']:
    #We need the specific "playerid" of the currently playing file in order
    #to pause it
    player_id = data['result'][0]["playerid"]
    
    payload = {"jsonrpc": "2.0", "method": "Player.GetProperties",
               "params": { "playerid": player_id, "properties" : ["speed"] }, "id": 1}
    url_param = urllib.urlencode({'request': json.dumps(payload)})
    response = requests.get(xbmc_json_rpc_url + '?' + url_param,
                        headers=headers)
                        
    data = json.loads(response.text)         

    if data["result"]["speed"]:
        payload = {"jsonrpc": "2.0", "method": "Player.PlayPause",
                   "params": { "playerid": player_id }, "id": 1}
        response = requests.post(xbmc_json_rpc_url, data=json.dumps(payload),
                                 headers=headers)

        #response.text will look like this if we're successful:
        #{"id":1,"jsonrpc":"2.0","result":{"speed":0}}

2 thoughts on “XBMC’s JSON-RPC API – REALLY Pausing a video

  1. Hi,

    Thanks for this script, I’ve successfully implemented it in my domotica environment 🙂 This was my first Python experience ever, unfortunately the script didn’t work out of the box and I had to dig deep into it ;-). After trial and error I figured out that ‘data=json.dumps(payload)’ shouldn’t be included in the requests.get lines. After I removed that, all works perfectly well!

    Cheers! Joost

    • Thanks Joost, you are quite correct – I have removed the argument from the code snippet above (mistakenly left in after copying a call to post())

Leave a Reply

Your email address will not be published. Required fields are marked *