Merge pull request #861 from croneter/fix-crash

Another attempt to keep Kodi from crashing on playback startup
This commit is contained in:
croneter 2019-05-30 14:32:37 +02:00 committed by GitHub
commit ab47b63bc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 28 deletions

View file

@ -4,8 +4,8 @@
<import addon="xbmc.python" version="2.1.0"/>
<import addon="script.module.requests" version="2.9.1" />
<import addon="script.module.defusedxml" version="0.5.0"/>
<import addon="plugin.video.plexkodiconnect.movies" version="2.1.0" />
<import addon="plugin.video.plexkodiconnect.tvshows" version="2.1.0" />
<import addon="plugin.video.plexkodiconnect.movies" version="2.1.1" />
<import addon="plugin.video.plexkodiconnect.tvshows" version="2.1.1" />
</requires>
<extension point="xbmc.python.pluginsource" library="default.py">
<provides>video audio image</provides>

View file

@ -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)

View file

@ -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':

View file

@ -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')

View file

@ -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)