diff --git a/resources/lib/PlexFunctions.py b/resources/lib/PlexFunctions.py
index 94cfcda5..ce8d9624 100644
--- a/resources/lib/PlexFunctions.py
+++ b/resources/lib/PlexFunctions.py
@@ -291,15 +291,6 @@ def init_plex_playqueue(itemid, librarySectionUUID, mediatype='movie',
return xml
-def getPlexRepeat(kodiRepeat):
- plexRepeat = {
- 'off': '0',
- 'one': '1',
- 'all': '2' # does this work?!?
- }
- return plexRepeat.get(kodiRepeat)
-
-
def PMSHttpsEnabled(url):
"""
Returns True if the PMS can talk https, False otherwise.
diff --git a/resources/lib/json_rpc.py b/resources/lib/json_rpc.py
index 7667fc89..90dc7af5 100644
--- a/resources/lib/json_rpc.py
+++ b/resources/lib/json_rpc.py
@@ -360,6 +360,22 @@ def get_episodes(params):
return ret
+def get_item(playerid):
+ """
+ Returns the following for the currently playing item:
+ {
+ u'title': u'Okja',
+ u'type': u'movie',
+ u'id': 258,
+ u'file': u'smb://...movie.mkv',
+ u'label': u'Okja'
+ }
+ """
+ return jsonrpc('Player.GetItem').execute({
+ 'playerid': playerid,
+ 'properties': ['title', 'file']})['result']['item']
+
+
def get_player_props(playerid):
"""
Returns a dict for the active Kodi player with the following values:
@@ -367,14 +383,14 @@ def get_player_props(playerid):
'type' [str] the Kodi player type, e.g. 'video'
'time' The current item's time in Kodi time
'totaltime' The current item's total length in Kodi time
- 'speed' [int] playback speed, defaults to 0
+ 'speed' [int] playback speed, 0 is paused, 1 is playing
'shuffled' [bool] True if shuffled
'repeat' [str] 'off', 'one', 'all'
'position' [int] position in playlist (or -1)
'playlistid' [int] the Kodi playlist id (or -1)
}
"""
- ret = jsonrpc('Player.GetProperties').execute({
+ return jsonrpc('Player.GetProperties').execute({
'playerid': playerid,
'properties': ['type',
'time',
@@ -383,8 +399,11 @@ def get_player_props(playerid):
'shuffled',
'repeat',
'position',
- 'playlistid']})
- return ret['result']
+ 'playlistid',
+ 'currentvideostream',
+ 'currentaudiostream',
+ 'subtitleenabled',
+ 'currentsubtitle']})['result']
def current_audiostream(playerid):
diff --git a/resources/lib/kodimonitor.py b/resources/lib/kodimonitor.py
index 6bc0639a..3cb82380 100644
--- a/resources/lib/kodimonitor.py
+++ b/resources/lib/kodimonitor.py
@@ -13,7 +13,9 @@ from utils import window, settings, CatchExceptions, tryDecode, tryEncode, \
from PlexFunctions import scrobble
from kodidb_functions import get_kodiid_from_filename
from PlexAPI import API
+import json_rpc as js
import state
+import variables as v
###############################################################################
@@ -178,69 +180,48 @@ class KodiMonitor(Monitor):
def PlayBackStart(self, data):
"""
- Called whenever a playback is started
+ Called whenever a playback is started. Example data:
+ {
+ u'item': {u'type': u'movie', u'title': u''},
+ u'player': {u'playerid': 1, u'speed': 1}
+ }
"""
- # Get currently playing file - can take a while. Will be utf-8!
- try:
- currentFile = self.xbmcplayer.getPlayingFile()
- except:
- currentFile = None
- count = 0
- while currentFile is None:
- sleep(100)
- try:
- currentFile = self.xbmcplayer.getPlayingFile()
- except:
- pass
- if count == 50:
- log.info("No current File, cancel OnPlayBackStart...")
- return
- else:
- count += 1
- # Just to be on the safe side
- currentFile = tryDecode(currentFile)
- log.debug("Currently playing file is: %s" % currentFile)
-
+ log.debug('PlayBackStart called with: %s', data)
# Get the type of media we're playing
try:
- typus = data['item']['type']
+ kodi_type = data['item']['type']
+ playerid = data['player']['playerid']
+ json_data = js.get_item(playerid)
except (TypeError, KeyError):
- log.info("Item is invalid for PMS playstate update.")
+ log.info('Aborting playback report - item is invalid for updates')
return
- log.debug("Playing itemtype is (or appears to be): %s" % typus)
-
- # Try to get a Kodi ID
- # If PKC was used - native paths, not direct paths
- plex_id = window('plex_%s.itemid' % tryEncode(currentFile))
- # Get rid of the '' if the window property was not set
- plex_id = None if not plex_id else plex_id
- kodiid = None
- if plex_id is None:
- log.debug('Did not get Plex id from window properties')
- try:
- kodiid = data['item']['id']
- except (TypeError, KeyError):
- log.debug('Did not get a Kodi id from Kodi, darn')
- # For direct paths, if we're not streaming something
- # When using Widgets, Kodi doesn't tell us shit so we need this hack
- if (kodiid is None and plex_id is None and typus != 'song'
- and not currentFile.startswith('http')):
- (kodiid, typus) = get_kodiid_from_filename(currentFile)
- if kodiid is None:
- return
-
- if plex_id is None:
- # Get Plex' item id
- with plexdb.Get_Plex_DB() as plexcursor:
- plex_dbitem = plexcursor.getItem_byKodiId(kodiid, typus)
- try:
- plex_id = plex_dbitem[0]
- except TypeError:
- log.info("No Plex id returned for kodiid %s. Aborting playback"
- " report" % kodiid)
- return
- log.debug("Found Plex id %s for Kodi id %s for type %s"
- % (plex_id, kodiid, typus))
+ try:
+ kodi_id = json_data['id']
+ kodi_type = json_data['type']
+ except KeyError:
+ log.info('Aborting playback report - no Kodi id for %s', json_data)
+ return
+ # Get Plex' item id
+ with plexdb.Get_Plex_DB() as plex_db:
+ plex_dbitem = plex_db.getItem_byKodiId(kodi_id, kodi_type)
+ try:
+ plex_id = plex_dbitem[0]
+ plex_type = plex_dbitem[2]
+ except TypeError:
+ # No plex id, hence item not in the library. E.g. clips
+ plex_id = None
+ plex_type = None
+ state.PLAYER_STATES[playerid].update(js.get_player_props(playerid))
+ state.PLAYER_STATES[playerid]['file'] = json_data['file']
+ state.PLAYER_STATES[playerid]['kodi_id'] = kodi_id
+ state.PLAYER_STATES[playerid]['kodi_type'] = kodi_type
+ state.PLAYER_STATES[playerid]['plex_id'] = plex_id
+ state.PLAYER_STATES[playerid]['plex_type'] = plex_type
+ log.debug('Set the player state %s', state.PLAYER_STATES[playerid])
+ # Set other stuff like volume
+ state.PLAYER_STATES[playerid]['volume'] = js.get_volume()
+ state.PLAYER_STATES[playerid]['muted'] = js.get_muted()
+ return
# Switch subtitle tracks if applicable
subtitle = window('plex_%s.subtitle' % tryEncode(currentFile))
diff --git a/resources/lib/player.py b/resources/lib/player.py
index 85d971d2..e1d8e2ac 100644
--- a/resources/lib/player.py
+++ b/resources/lib/player.py
@@ -37,6 +37,7 @@ class PKC_Player(Player):
Will be called when xbmc starts playing a file.
Window values need to have been set in Kodimonitor.py
"""
+ return
self.stopAll()
# Get current file (in utf-8!)
diff --git a/resources/lib/plexbmchelper/subscribers.py b/resources/lib/plexbmchelper/subscribers.py
index ebdb8fe5..4183428d 100644
--- a/resources/lib/plexbmchelper/subscribers.py
+++ b/resources/lib/plexbmchelper/subscribers.py
@@ -72,70 +72,62 @@ class SubscriptionManager:
msg += self.getTimelineXML(players.get(v.KODI_TYPE_VIDEO),
v.PLEX_TYPE_VIDEO)
msg += "\n"
+ log.debug('msg is: %s', msg)
return msg
def getTimelineXML(self, player, ptype):
if player is None:
status = 'stopped'
- time = 0
else:
playerid = player['playerid']
- info = self.getPlayerProperties(playerid)
+ info = state.PLAYER_STATES[playerid]
# save this info off so the server update can use it too
- self.playerprops[playerid] = info
- status = info['state']
- time = info['time']
+ # self.playerprops[playerid] = info
+ status = ("paused", "playing")[info['speed']]
ret = ('\n '
return ret
- ret += ' time="%s"' % time
+ ret += ' time="%s"' % kodi_time_to_millis(info['time'])
+ ret += ' duration="%s"' % kodi_time_to_millis(info['totaltime'])
+ ret += ' shuffle="%s"' % ("0", "1")[info['shuffled']]
+ ret += ' repeat="%s"' % v.PLEX_REPEAT_FROM_KODI_REPEAT[info['repeat']]
+ if ptype != v.KODI_TYPE_PHOTO:
+ ret += ' volume="%s"' % info['volume']
+ ret += ' mute="%s"' % ("0", "1")[info['muted']]
pbmc_server = window('pms_server')
+ server = self.getServerByHost(self.server)
if pbmc_server:
- (self.protocol, self.server, self.port) = \
- pbmc_server.split(':')
+ (self.protocol, self.server, self.port) = pbmc_server.split(':')
self.server = self.server.replace('/', '')
- keyid = None
- count = 0
- while not keyid:
- if count > 30:
- break
- keyid = window('plex_currently_playing_itemid')
- sleep(100)
- count += 1
- if keyid:
- self.lastkey = "/library/metadata/%s" % keyid
- self.ratingkey = keyid
- ret += ' key="%s"' % self.lastkey
- ret += ' ratingKey="%s"' % self.ratingkey
- serv = self.getServerByHost(self.server)
- if info.get('playQueueID'):
- self.containerKey = "/playQueues/%s" % info.get('playQueueID')
- ret += ' playQueueID="%s"' % info.get('playQueueID')
- ret += ' playQueueVersion="%s"' % info.get('playQueueVersion')
- ret += ' playQueueItemID="%s"' % info.get('playQueueItemID')
+ if info['plex_id']:
+ self.lastkey = "/library/metadata/%s" % info['plex_id']
+ self.ratingkey = info['plex_id']
+ ret += ' key="/library/metadata/%s"' % info['plex_id']
+ ret += ' ratingKey="%s"' % info['plex_id']
+ # PlayQueue stuff
+ playqueue = self.playqueue.playqueues[playerid]
+ pos = info['position']
+ try:
+ ret += ' playQueueItemID="%s"' % playqueue.items[pos].ID or 'null'
+ self.containerKey = "/playQueues/%s" % playqueue.ID or 'null'
+ ret += ' playQueueID="%s"' % playqueue.ID or 'null'
+ ret += ' playQueueVersion="%s"' % playqueue.version or 'null'
ret += ' containerKey="%s"' % self.containerKey
- ret += ' guid="%s"' % info['guid']
- elif keyid:
- self.containerKey = self.lastkey
- ret += ' containerKey="%s"' % self.containerKey
-
- ret += ' duration="%s"' % info['duration']
- ret += ' machineIdentifier="%s"' % serv.get('uuid', "")
- ret += ' protocol="%s"' % serv.get('protocol', "http")
- ret += ' address="%s"' % serv.get('server', self.server)
- ret += ' port="%s"' % serv.get('port', self.port)
- ret += ' volume="%s"' % info['volume']
- ret += ' shuffle="%s"' % info['shuffle']
- ret += ' mute="%s"' % info['mute']
- ret += ' repeat="%s"' % info['repeat']
- ret += ' itemType="%s"' % ptype
+ ret += ' guid="%s"' % playqueue.items[pos].guid or 'null'
+ except IndexError:
+ pass
+ ret += ' machineIdentifier="%s"' % server.get('uuid', "")
+ ret += ' protocol="%s"' % server.get('protocol', 'http')
+ ret += ' address="%s"' % server.get('server', self.server)
+ ret += ' port="%s"' % server.get('port', self.port)
+ # Temp. token set?
if state.PLEX_TRANSIENT_TOKEN:
ret += ' token="%s"' % state.PLEX_TRANSIENT_TOKEN
- elif info['plex_transient_token']:
- ret += ' token="%s"' % info['plex_transient_token']
+ elif playqueue.plex_transient_token:
+ ret += ' token="%s"' % playqueue.plex_transient_token
# Might need an update in the future
if ptype == 'video':
ret += ' subtitleStreamID="-1"'
@@ -236,37 +228,26 @@ class SubscriptionManager:
del self.subscribers[sub.uuid]
def getPlayerProperties(self, playerid):
+ # Get the playqueue
+ playqueue = self.playqueue.playqueues[playerid]
+ # get info from the player
+ props = state.PLAYER_STATES[playerid]
+ info = {
+ 'time': kodi_time_to_millis(props['time']),
+ 'duration': kodi_time_to_millis(props['totaltime']),
+ 'state': ("paused", "playing")[int(props['speed'])],
+ 'shuffle': ("0", "1")[props.get('shuffled', False)],
+ 'repeat': v.PLEX_REPEAT_FROM_KODI_REPEAT[props.get('repeat')]
+ }
+ pos = props['position']
try:
- # Get the playqueue
- playqueue = self.playqueue.playqueues[playerid]
- # get info from the player
- props = js.get_player_props(playerid)
- info = {
- 'time': kodi_time_to_millis(props['time']),
- 'duration': kodi_time_to_millis(props['totaltime']),
- 'state': ("paused", "playing")[int(props['speed'])],
- 'shuffle': ("0", "1")[props.get('shuffled', False)],
- 'repeat': pf.getPlexRepeat(props.get('repeat')),
- }
- pos = props['position']
- try:
- info['playQueueItemID'] = playqueue.items[pos].ID or 'null'
- info['guid'] = playqueue.items[pos].guid or 'null'
- info['playQueueID'] = playqueue.ID or 'null'
- info['playQueueVersion'] = playqueue.version or 'null'
- info['itemType'] = playqueue.items[pos].plex_type or 'null'
- except:
- info['itemType'] = props.get('type') or 'null'
+ info['playQueueItemID'] = playqueue.items[pos].ID or 'null'
+ info['guid'] = playqueue.items[pos].guid or 'null'
+ info['playQueueID'] = playqueue.ID or 'null'
+ info['playQueueVersion'] = playqueue.version or 'null'
+ info['itemType'] = playqueue.items[pos].plex_type or 'null'
except:
- import traceback
- log.error("Traceback:\n%s" % traceback.format_exc())
- info = {
- 'time': 0,
- 'duration': 0,
- 'state': 'stopped',
- 'shuffle': False,
- 'repeat': 0
- }
+ info['itemType'] = props.get('type') or 'null'
# get the volume from the application
info['volume'] = js.get_volume()
@@ -323,5 +304,6 @@ class Subscriber:
response = self.doUtils(url,
postBody=msg,
action_type="POST")
+ log.debug('response is: %s', response)
if response in [False, None, 401]:
self.subMgr.removeSubscriber(self.uuid)
diff --git a/resources/lib/state.py b/resources/lib/state.py
index 2020fc71..c88a8224 100644
--- a/resources/lib/state.py
+++ b/resources/lib/state.py
@@ -75,8 +75,33 @@ PLEX_USER_ID = None
# another user playing something! Token identifies user
PLEX_TRANSIENT_TOKEN = None
-# Kodi player states
-PLAYER_STATES = {}
+# Kodi player states - here, initial values are set
+PLAYER_STATES = {
+ 1: {
+ 'type': 'movie',
+ 'time': 0,
+ 'totaltime': 0,
+ 'speed': 0,
+ 'shuffled': False,
+ 'repeat': '0',
+ 'position': -1,
+ 'playlistid': -1,
+ 'currentvideostream': -1,
+ 'currentaudiostream': -1,
+ 'subtitleenabled': False,
+ 'currentsubtitle': -1,
+ ######
+ 'file': '',
+ 'kodi_id': None,
+ 'kodi_type': None,
+ 'plex_id': None,
+ 'plex_type': None,
+ 'volume': 100,
+ 'muted': False
+ },
+ 2: {},
+ 3: {}
+}
PLAYED_INFO = {}
# Kodi webserver details
diff --git a/resources/lib/variables.py b/resources/lib/variables.py
index 9dcc4560..d660f22f 100644
--- a/resources/lib/variables.py
+++ b/resources/lib/variables.py
@@ -214,6 +214,20 @@ KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE = {
}
+KODI_PLAYLIST_TYPE_FROM_KODI_TYPE = {
+ KODI_TYPE_VIDEO: KODI_TYPE_VIDEO,
+ KODI_TYPE_MOVIE: KODI_TYPE_VIDEO,
+ KODI_TYPE_EPISODE: KODI_TYPE_VIDEO,
+ KODI_TYPE_SEASON: KODI_TYPE_VIDEO,
+ KODI_TYPE_SHOW: KODI_TYPE_VIDEO,
+ KODI_TYPE_CLIP: KODI_TYPE_VIDEO,
+ KODI_TYPE_ARTIST: KODI_TYPE_AUDIO,
+ KODI_TYPE_ALBUM: KODI_TYPE_AUDIO,
+ KODI_TYPE_SONG: KODI_TYPE_AUDIO,
+ KODI_TYPE_AUDIO: KODI_TYPE_AUDIO,
+ KODI_TYPE_PHOTO: KODI_TYPE_PHOTO
+}
+
REMAP_TYPE_FROM_PLEXTYPE = {
PLEX_TYPE_MOVIE: 'movie',
PLEX_TYPE_CLIP: 'clip',
@@ -371,3 +385,9 @@ SORT_METHODS_ALBUMS = (
XML_HEADER = '\n'
COMPANION_OK_MESSAGE = XML_HEADER + ''
+
+PLEX_REPEAT_FROM_KODI_REPEAT = {
+ 'off': '0',
+ 'one': '1',
+ 'all': '2' # does this work?!?
+}