diff --git a/resources/lib/kodimonitor.py b/resources/lib/kodimonitor.py index 102df474..0bebae33 100644 --- a/resources/lib/kodimonitor.py +++ b/resources/lib/kodimonitor.py @@ -209,18 +209,24 @@ class KodiMonitor(Monitor): # Kodi remembers the last setResolvedUrl - which is empty in our case kodi_item = js.get_item(data['playlistid']) LOG.debug('kodi_item: %s', kodi_item) - # if kodi_item.get('file') == '': - # LOG.info('Detected re-start of playback of last item') - # old = state.OLD_PLAYER_STATES[data['playlistid']] - # kwargs = { - # 'plex_id': old['plex_id'], - # 'plex_type': old['plex_type'], - # 'path': old['file'], - # 'resolve': False - # } - # thread = Thread(target=playback_triage, kwargs=kwargs) - # thread.start() - # return + if (state.RESUMABLE is True and + data['position'] == 0 and + data['item'].get('title') is not None and + getCondVisibility('Window.IsVisible(MyVideoNav.xml)')): + # Hack we need for RESUMABLE items because Kodi lost the path of the + # last played item that is now being replayed (see playback.py's + # Player().play()) + LOG.info('Detected re-start of playback of last item') + old = state.OLD_PLAYER_STATES[data['playlistid']] + kwargs = { + 'plex_id': old['plex_id'], + 'plex_type': old['plex_type'], + 'path': old['file'], + 'resolve': False + } + thread = Thread(target=playback_triage, kwargs=kwargs) + thread.start() + return # Have we initiated the playqueue already? If not, ignore this if not playqueue.items: LOG.debug('Playqueue not initiated - ignoring') @@ -414,6 +420,8 @@ class SpecialMonitor(Thread): if (not is_playing and getCondVisibility('Window.IsVisible(DialogContextMenu.xml)') and getInfoLabel('Control.GetLabel(1002)') == getLocalizedString(12021)): + # Remember that the item IS indeed resumable + state.RESUMABLE = True control = int(Window(10106).getFocusId()) if control == 1002: # Start from beginning diff --git a/resources/lib/playback.py b/resources/lib/playback.py index 5cb3b221..d6d05219 100644 --- a/resources/lib/playback.py +++ b/resources/lib/playback.py @@ -173,6 +173,12 @@ def playback_init(plex_id, plex_type, playqueue): args=(playqueue.kodi_pl, )) thread.setDaemon(True) LOG.info('Done initializing PKC playback, starting Kodi player') + # By design, PKC will start Kodi playback using Player().play(). Kodi + # caches paths like our plugin://pkc. If we use Player().play() between + # 2 consecutive startups of exactly the same Kodi library item, Kodi's + # cache will have been flushed for some reason. Hence the 2nd call for + # plugin://pkc will be lost; Kodi will try to startup playback for an empty + # path: log entry is "CGUIWindowVideoBase::OnPlayMedia " thread.start() @@ -287,6 +293,8 @@ def conclude_playback(playqueue, pos): LOG.info('Resuming playback at %s', item.offset) listitem.setProperty('StartOffset', str(item.offset)) listitem.setProperty('resumetime', str(item.offset)) + # Reset the resumable flag + state.RESUMABLE = False result.listitem = listitem pickle_me(result) LOG.info('Done concluding playback') diff --git a/resources/lib/state.py b/resources/lib/state.py index c2a99e09..50578541 100644 --- a/resources/lib/state.py +++ b/resources/lib/state.py @@ -134,6 +134,8 @@ PLAYSTATE = { # paths for playback (since we're not receiving a Kodi id) PLEX_IDS = {} PLAYED_INFO = {} +# Flag whether Kodi item where the playback is being started is even resumable +RESUMABLE = False # Set by SpecialMonitor - did user choose to resume playback or start from the # beginning? RESUME_PLAYBACK = False