diff --git a/addon.xml b/addon.xml index ed6fb609..a91219ec 100644 --- a/addon.xml +++ b/addon.xml @@ -4,8 +4,8 @@ - - + + video audio image diff --git a/default.py b/default.py index 1c9b3f96..745ba009 100644 --- a/default.py +++ b/default.py @@ -157,17 +157,11 @@ class Main(): # Handle -1 received, not waiting for main thread return # Wait for the result from the main PKC thread - result = transfer.wait_for_transfer() - if result is None: - LOG.error('Error encountered, aborting') - utils.dialog('notification', - heading='{plex}', - message=utils.lang(30128), - icon='{error}', - time=3000) - xbmcplugin.setResolvedUrl(HANDLE, False, xbmcgui.ListItem()) - elif result is True: + result = transfer.wait_for_transfer(source='main') + if result is True: xbmcplugin.setResolvedUrl(HANDLE, False, xbmcgui.ListItem()) + # Tell main thread that we're done + transfer.send(True, target='main') else: # Received a xbmcgui.ListItem() xbmcplugin.setResolvedUrl(HANDLE, True, result) diff --git a/resources/lib/playback.py b/resources/lib/playback.py index 648fcbcb..6aabdd51 100644 --- a/resources/lib/playback.py +++ b/resources/lib/playback.py @@ -177,10 +177,10 @@ def _playback_init(plex_id, plex_type, playqueue, pos): plex_type in v.PLEX_VIDEOTYPES and playqueue.kodi_pl.size() > 1): LOG.debug('Detected widget playback for videos') - # Need to clear playlist because playqueue.kodi_pl.size() could return - # more than one - since playback was initiated from the audio queue! - playqueue.clear() - if playqueue.kodi_pl.size() > 1: + # playqueue.kodi_pl.size() could return more than one - since playback + # was initiated from the audio queue! + pass + elif playqueue.kodi_pl.size() > 1: # Special case - we already got a filled Kodi playqueue try: _init_existing_kodi_playlist(playqueue, pos) @@ -199,8 +199,7 @@ def _playback_init(plex_id, plex_type, playqueue, pos): return # "Usual" case - consider trailers and parts and build both Kodi and Plex # playqueues - # Pass dummy PKC video with 0 length so Kodi immediately stops playback - # and we can build our own playqueue. + # Release default.py _ensure_resolve() api = API(xml[0]) trailers = False @@ -270,9 +269,14 @@ def _ensure_resolve(abort=False): if RESOLVE: # Releases the other Python thread without a ListItem transfer.send(True) - # Shows PKC error message - # transfer.send(None) + # Wait for default.py to have completed xbmcplugin.setResolvedUrl() + transfer.wait_for_transfer(source='default') if abort: + utils.dialog('notification', + heading='{plex}', + message=utils.lang(30128), + icon='{error}', + time=3000) # Reset some playback variables app.PLAYSTATE.context_menu_play = False app.PLAYSTATE.force_transcode = False @@ -403,8 +407,7 @@ def _conclude_playback(playqueue, pos): playurl = item.file if not playurl: LOG.info('Did not get a playurl, aborting playback silently') - app.PLAYSTATE.resume_playback = False - transfer.send(True) + _ensure_resolve(abort=True) return listitem.setPath(utils.try_encode(playurl)) if item.playmethod == 'DirectStream': diff --git a/resources/lib/playback_starter.py b/resources/lib/playback_starter.py index 5800f0eb..9c84e18d 100644 --- a/resources/lib/playback_starter.py +++ b/resources/lib/playback_starter.py @@ -29,6 +29,8 @@ class PlaybackTask(backgroundthread.Task): # E.g. other add-ons scanning for Extras folder LOG.debug('Detected 3rd party add-on call - ignoring') transfer.send(True) + # Wait for default.py to have completed xbmcplugin.setResolvedUrl() + transfer.wait_for_transfer(source='default') return params = dict(utils.parse_qsl(params)) mode = params.get('mode') diff --git a/resources/lib/transfer.py b/resources/lib/transfer.py index 236e4a14..8539f166 100644 --- a/resources/lib/transfer.py +++ b/resources/lib/transfer.py @@ -14,7 +14,8 @@ import xbmcgui LOG = getLogger('PLEX.transfer') MONITOR = xbmc.Monitor() WINDOW = xbmcgui.Window(10000) -WINDOW_RESULT = 'plexkodiconnect.result'.encode('utf-8') +WINDOW_UPSTREAM = 'plexkodiconnect.result.upstream'.encode('utf-8') +WINDOW_DOWNSTREAM = 'plexkodiconnect.result.downstream'.encode('utf-8') WINDOW_COMMAND = 'plexkodiconnect.command'.encode('utf-8') @@ -90,7 +91,7 @@ def de_serialize(answ): raise NotImplementedError('Not implemented: %s' % answ) -def send(pkc_listitem): +def send(pkc_listitem, target='default'): """ Pickles the obj to the window variable. Use to transfer Python objects between different PKC python instances (e.g. if default.py is @@ -98,18 +99,27 @@ def send(pkc_listitem): obj can be pretty much any Python object. However, classes and functions won't work. See the Pickle documentation + + Set target='default' if you send data TO another Python default.py + instance, 'main' if your default.py needs to send to the main thread """ + window = WINDOW_DOWNSTREAM if target == 'default' else WINDOW_UPSTREAM LOG.debug('Sending: %s', pkc_listitem) - kodi_window(WINDOW_RESULT, + kodi_window(window, value=json.dumps(serialize(pkc_listitem))) -def wait_for_transfer(): +def wait_for_transfer(source='main'): + """ + Set source='default' if you wait for data FROM another Python default.py + instance, 'main' if your default.py needs to wait for the main thread + """ + window = WINDOW_DOWNSTREAM if source == 'main' else WINDOW_UPSTREAM result = '' while not result: - result = kodi_window(WINDOW_RESULT) + result = kodi_window(window) if result: - kodi_window(WINDOW_RESULT, clear=True) + kodi_window(window, clear=True) LOG.debug('Received') result = json.loads(result) return de_serialize(result)