Merge pull request #861 from croneter/fix-crash
Another attempt to keep Kodi from crashing on playback startup
This commit is contained in:
commit
ab47b63bc5
5 changed files with 37 additions and 28 deletions
|
@ -4,8 +4,8 @@
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
<import addon="script.module.requests" version="2.9.1" />
|
<import addon="script.module.requests" version="2.9.1" />
|
||||||
<import addon="script.module.defusedxml" version="0.5.0"/>
|
<import addon="script.module.defusedxml" version="0.5.0"/>
|
||||||
<import addon="plugin.video.plexkodiconnect.movies" version="2.1.0" />
|
<import addon="plugin.video.plexkodiconnect.movies" version="2.1.1" />
|
||||||
<import addon="plugin.video.plexkodiconnect.tvshows" version="2.1.0" />
|
<import addon="plugin.video.plexkodiconnect.tvshows" version="2.1.1" />
|
||||||
</requires>
|
</requires>
|
||||||
<extension point="xbmc.python.pluginsource" library="default.py">
|
<extension point="xbmc.python.pluginsource" library="default.py">
|
||||||
<provides>video audio image</provides>
|
<provides>video audio image</provides>
|
||||||
|
|
14
default.py
14
default.py
|
@ -157,17 +157,11 @@ class Main():
|
||||||
# Handle -1 received, not waiting for main thread
|
# Handle -1 received, not waiting for main thread
|
||||||
return
|
return
|
||||||
# Wait for the result from the main PKC thread
|
# Wait for the result from the main PKC thread
|
||||||
result = transfer.wait_for_transfer()
|
result = transfer.wait_for_transfer(source='main')
|
||||||
if result is None:
|
if result is True:
|
||||||
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:
|
|
||||||
xbmcplugin.setResolvedUrl(HANDLE, False, xbmcgui.ListItem())
|
xbmcplugin.setResolvedUrl(HANDLE, False, xbmcgui.ListItem())
|
||||||
|
# Tell main thread that we're done
|
||||||
|
transfer.send(True, target='main')
|
||||||
else:
|
else:
|
||||||
# Received a xbmcgui.ListItem()
|
# Received a xbmcgui.ListItem()
|
||||||
xbmcplugin.setResolvedUrl(HANDLE, True, result)
|
xbmcplugin.setResolvedUrl(HANDLE, True, result)
|
||||||
|
|
|
@ -177,10 +177,10 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
|
||||||
plex_type in v.PLEX_VIDEOTYPES and
|
plex_type in v.PLEX_VIDEOTYPES and
|
||||||
playqueue.kodi_pl.size() > 1):
|
playqueue.kodi_pl.size() > 1):
|
||||||
LOG.debug('Detected widget playback for videos')
|
LOG.debug('Detected widget playback for videos')
|
||||||
# Need to clear playlist because playqueue.kodi_pl.size() could return
|
# playqueue.kodi_pl.size() could return more than one - since playback
|
||||||
# more than one - since playback was initiated from the audio queue!
|
# was initiated from the audio queue!
|
||||||
playqueue.clear()
|
pass
|
||||||
if playqueue.kodi_pl.size() > 1:
|
elif playqueue.kodi_pl.size() > 1:
|
||||||
# Special case - we already got a filled Kodi playqueue
|
# Special case - we already got a filled Kodi playqueue
|
||||||
try:
|
try:
|
||||||
_init_existing_kodi_playlist(playqueue, pos)
|
_init_existing_kodi_playlist(playqueue, pos)
|
||||||
|
@ -199,8 +199,7 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
|
||||||
return
|
return
|
||||||
# "Usual" case - consider trailers and parts and build both Kodi and Plex
|
# "Usual" case - consider trailers and parts and build both Kodi and Plex
|
||||||
# playqueues
|
# playqueues
|
||||||
# Pass dummy PKC video with 0 length so Kodi immediately stops playback
|
# Release default.py
|
||||||
# and we can build our own playqueue.
|
|
||||||
_ensure_resolve()
|
_ensure_resolve()
|
||||||
api = API(xml[0])
|
api = API(xml[0])
|
||||||
trailers = False
|
trailers = False
|
||||||
|
@ -270,9 +269,14 @@ def _ensure_resolve(abort=False):
|
||||||
if RESOLVE:
|
if RESOLVE:
|
||||||
# Releases the other Python thread without a ListItem
|
# Releases the other Python thread without a ListItem
|
||||||
transfer.send(True)
|
transfer.send(True)
|
||||||
# Shows PKC error message
|
# Wait for default.py to have completed xbmcplugin.setResolvedUrl()
|
||||||
# transfer.send(None)
|
transfer.wait_for_transfer(source='default')
|
||||||
if abort:
|
if abort:
|
||||||
|
utils.dialog('notification',
|
||||||
|
heading='{plex}',
|
||||||
|
message=utils.lang(30128),
|
||||||
|
icon='{error}',
|
||||||
|
time=3000)
|
||||||
# Reset some playback variables
|
# Reset some playback variables
|
||||||
app.PLAYSTATE.context_menu_play = False
|
app.PLAYSTATE.context_menu_play = False
|
||||||
app.PLAYSTATE.force_transcode = False
|
app.PLAYSTATE.force_transcode = False
|
||||||
|
@ -403,8 +407,7 @@ def _conclude_playback(playqueue, pos):
|
||||||
playurl = item.file
|
playurl = item.file
|
||||||
if not playurl:
|
if not playurl:
|
||||||
LOG.info('Did not get a playurl, aborting playback silently')
|
LOG.info('Did not get a playurl, aborting playback silently')
|
||||||
app.PLAYSTATE.resume_playback = False
|
_ensure_resolve(abort=True)
|
||||||
transfer.send(True)
|
|
||||||
return
|
return
|
||||||
listitem.setPath(utils.try_encode(playurl))
|
listitem.setPath(utils.try_encode(playurl))
|
||||||
if item.playmethod == 'DirectStream':
|
if item.playmethod == 'DirectStream':
|
||||||
|
|
|
@ -29,6 +29,8 @@ class PlaybackTask(backgroundthread.Task):
|
||||||
# E.g. other add-ons scanning for Extras folder
|
# E.g. other add-ons scanning for Extras folder
|
||||||
LOG.debug('Detected 3rd party add-on call - ignoring')
|
LOG.debug('Detected 3rd party add-on call - ignoring')
|
||||||
transfer.send(True)
|
transfer.send(True)
|
||||||
|
# Wait for default.py to have completed xbmcplugin.setResolvedUrl()
|
||||||
|
transfer.wait_for_transfer(source='default')
|
||||||
return
|
return
|
||||||
params = dict(utils.parse_qsl(params))
|
params = dict(utils.parse_qsl(params))
|
||||||
mode = params.get('mode')
|
mode = params.get('mode')
|
||||||
|
|
|
@ -14,7 +14,8 @@ import xbmcgui
|
||||||
LOG = getLogger('PLEX.transfer')
|
LOG = getLogger('PLEX.transfer')
|
||||||
MONITOR = xbmc.Monitor()
|
MONITOR = xbmc.Monitor()
|
||||||
WINDOW = xbmcgui.Window(10000)
|
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')
|
WINDOW_COMMAND = 'plexkodiconnect.command'.encode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ def de_serialize(answ):
|
||||||
raise NotImplementedError('Not implemented: %s' % 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
|
Pickles the obj to the window variable. Use to transfer Python
|
||||||
objects between different PKC python instances (e.g. if default.py is
|
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
|
obj can be pretty much any Python object. However, classes and
|
||||||
functions won't work. See the Pickle documentation
|
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)
|
LOG.debug('Sending: %s', pkc_listitem)
|
||||||
kodi_window(WINDOW_RESULT,
|
kodi_window(window,
|
||||||
value=json.dumps(serialize(pkc_listitem)))
|
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 = ''
|
result = ''
|
||||||
while not result:
|
while not result:
|
||||||
result = kodi_window(WINDOW_RESULT)
|
result = kodi_window(window)
|
||||||
if result:
|
if result:
|
||||||
kodi_window(WINDOW_RESULT, clear=True)
|
kodi_window(window, clear=True)
|
||||||
LOG.debug('Received')
|
LOG.debug('Received')
|
||||||
result = json.loads(result)
|
result = json.loads(result)
|
||||||
return de_serialize(result)
|
return de_serialize(result)
|
||||||
|
|
Loading…
Reference in a new issue