Fix PKC sometimes telling wrong item being played

This commit is contained in:
Croneter 2018-03-29 07:33:07 +02:00
parent 9f82b05c11
commit f23f6da627
2 changed files with 44 additions and 36 deletions

View file

@ -60,6 +60,7 @@ class KodiMonitor(Monitor):
""" """
def __init__(self): def __init__(self):
self.xbmcplayer = Player() self.xbmcplayer = Player()
self._already_slept = False
Monitor.__init__(self) Monitor.__init__(self)
for playerid in state.PLAYER_STATES: for playerid in state.PLAYER_STATES:
state.PLAYER_STATES[playerid] = copy.deepcopy(state.PLAYSTATE) state.PLAYER_STATES[playerid] = copy.deepcopy(state.PLAYSTATE)
@ -257,30 +258,17 @@ class KodiMonitor(Monitor):
else: else:
LOG.debug('Detected PKC clear - ignoring') LOG.debug('Detected PKC clear - ignoring')
def _get_ids(self, json_item): def _get_ids(self, kodi_id, kodi_type, path):
""" """
Returns the tuple (plex_id, plex_type) or (None, None)
""" """
kodi_id = json_item.get('id')
kodi_type = json_item.get('type')
path = json_item.get('file')
# Plex id will NOT be set with direct paths
plex_id = state.PLEX_IDS.get(path)
try:
plex_type = v.PLEX_TYPE_FROM_KODI_TYPE[kodi_type]
except KeyError:
plex_type = None
# No Kodi id returned by Kodi, even if there is one. Ex: Widgets # No Kodi id returned by Kodi, even if there is one. Ex: Widgets
if plex_id and not kodi_id: plex_id = None
with plexdb.Get_Plex_DB() as plex_db: plex_type = None
plex_dbitem = plex_db.getItem_byId(plex_id)
try:
kodi_id = plex_dbitem[0]
except TypeError:
kodi_id = None
# If using direct paths and starting playback from a widget # If using direct paths and starting playback from a widget
if not kodi_id and kodi_type and path and not path.startswith('http'): if not kodi_id and kodi_type and path:
kodi_id = kodiid_from_filename(path, kodi_type) kodi_id = kodiid_from_filename(path, kodi_type)
if not plex_id and kodi_id and kodi_type: if kodi_id:
with plexdb.Get_Plex_DB() as plex_db: with plexdb.Get_Plex_DB() as plex_db:
plex_dbitem = plex_db.getItem_byKodiId(kodi_id, kodi_type) plex_dbitem = plex_db.getItem_byKodiId(kodi_id, kodi_type)
try: try:
@ -289,7 +277,7 @@ class KodiMonitor(Monitor):
except TypeError: except TypeError:
# No plex id, hence item not in the library. E.g. clips # No plex id, hence item not in the library. E.g. clips
pass pass
return kodi_id, kodi_type, plex_id, plex_type return plex_id, plex_type
@staticmethod @staticmethod
def _add_remaining_items_to_playlist(playqueue): def _add_remaining_items_to_playlist(playqueue):
@ -309,6 +297,24 @@ class KodiMonitor(Monitor):
except PL.PlaylistError: except PL.PlaylistError:
LOG.info('Could not build Plex playlist for: %s', items) LOG.info('Could not build Plex playlist for: %s', items)
def _json_item(self, playerid):
"""
Uses JSON RPC to get the playing item's info and returns the tuple
kodi_id, kodi_type, path
or None each time if not found.
"""
if not self._already_slept:
# SLEEP before calling this for the first time just after playback
# start as Kodi updates this info very late!! Might get previous
# element otherwise
self._already_slept = True
sleep(1000)
json_item = js.get_item(playerid)
LOG.debug('Kodi playing item properties: %s', json_item)
return (json_item.get('id'),
json_item.get('type'),
json_item.get('file'))
@LOCKER.lockthis @LOCKER.lockthis
def PlayBackStart(self, data): def PlayBackStart(self, data):
""" """
@ -319,9 +325,9 @@ class KodiMonitor(Monitor):
} }
Unfortunately when using Widgets, Kodi doesn't tell us shit Unfortunately when using Widgets, Kodi doesn't tell us shit
""" """
self._already_slept = False
# Get the type of media we're playing # Get the type of media we're playing
try: try:
kodi_type = data['item']['type']
playerid = data['player']['playerid'] playerid = data['player']['playerid']
except (TypeError, KeyError): except (TypeError, KeyError):
LOG.info('Aborting playback report - item invalid for updates %s', LOG.info('Aborting playback report - item invalid for updates %s',
@ -338,36 +344,41 @@ class KodiMonitor(Monitor):
state.ACTIVE_PLAYERS.append(playerid) state.ACTIVE_PLAYERS.append(playerid)
playqueue = PQ.PLAYQUEUES[playerid] playqueue = PQ.PLAYQUEUES[playerid]
info = js.get_player_props(playerid) info = js.get_player_props(playerid)
json_item = js.get_item(playerid)
pos = info['position'] if info['position'] != -1 else 0 pos = info['position'] if info['position'] != -1 else 0
LOG.debug('Detected position %s for %s', pos, playqueue) LOG.debug('Detected position %s for %s', pos, playqueue)
LOG.debug('Detected Kodi playing item properties: %s', json_item)
status = state.PLAYER_STATES[playerid] status = state.PLAYER_STATES[playerid]
path = json_item.get('file') kodi_id = data.get('id')
kodi_type = data.get('type')
path = data.get('file')
try: try:
item = playqueue.items[pos] item = playqueue.items[pos]
except IndexError: except IndexError:
# PKC playqueue not yet initialized # PKC playqueue not yet initialized
LOG.debug('Position %s not in PKC playqueue yet', pos)
initialize = True initialize = True
else: else:
if item.kodi_id: if not kodi_id:
if (item.kodi_id != json_item.get('id') or kodi_id, kodi_type, path = self._json_item(playerid)
item.kodi_type != json_item.get('type')): if kodi_id and item.kodi_id:
if item.kodi_id != kodi_id or item.kodi_type != kodi_type:
LOG.debug('Detected different Kodi id')
initialize = True initialize = True
else: else:
initialize = False initialize = False
else: else:
# E.g. clips set-up previously with no Kodi DB entry # E.g. clips set-up previously with no Kodi DB entry
if item.file != json_item.get('file'): if not path:
kodi_id, kodi_type, path = self._json_item(playerid)
if item.file != path:
LOG.debug('Detected different path')
initialize = True initialize = True
else: else:
initialize = False initialize = False
if initialize: if initialize:
LOG.debug('Need to initialize Plex and PKC playqueue') LOG.debug('Need to initialize Plex and PKC playqueue')
if not json_item.get('id') or not json_item.get('type'): if not kodi_id or not kodi_type:
LOG.debug('No Kodi id or type obtained - aborting report') kodi_id, kodi_type, path = self._json_item(playerid)
return plex_id, plex_type = self._get_ids(kodi_id, kodi_type, path)
kodi_id, kodi_type, plex_id, plex_type = self._get_ids(json_item)
if not plex_id: if not plex_id:
LOG.debug('No Plex id obtained - aborting playback report') LOG.debug('No Plex id obtained - aborting playback report')
return return
@ -381,7 +392,6 @@ class KodiMonitor(Monitor):
container_key = '/playQueues/%s' % container_key container_key = '/playQueues/%s' % container_key
elif plex_id is not None: elif plex_id is not None:
container_key = '/library/metadata/%s' % plex_id container_key = '/library/metadata/%s' % plex_id
LOG.debug('Set the Plex container_key to: %s', container_key)
else: else:
LOG.debug('No need to initialize playqueues') LOG.debug('No need to initialize playqueues')
kodi_id = item.kodi_id kodi_id = item.kodi_id
@ -393,6 +403,7 @@ class KodiMonitor(Monitor):
else: else:
container_key = '/library/metadata/%s' % plex_id container_key = '/library/metadata/%s' % plex_id
status.update(info) status.update(info)
LOG.debug('Set the Plex container_key to: %s', container_key)
status['container_key'] = container_key status['container_key'] = container_key
status['file'] = path status['file'] = path
status['kodi_id'] = kodi_id status['kodi_id'] = kodi_id

View file

@ -143,9 +143,6 @@ PLAYSTATE = {
'playmethod': None, 'playmethod': None,
'playcount': None 'playcount': None
} }
# Dict containing all filenames as keys with plex id as values - used for addon
# paths for playback (since we're not receiving a Kodi id)
PLEX_IDS = {}
PLAYED_INFO = {} PLAYED_INFO = {}
# Set by SpecialMonitor - did user choose to resume playback or start from the # Set by SpecialMonitor - did user choose to resume playback or start from the
# beginning? # beginning?