Fix some playqueue inconsistencies using Plex Companion

- Also fix movie helper and TV show helper add-ons
This commit is contained in:
croneter 2018-04-08 14:34:38 +02:00
parent 7ae831f7c3
commit 30abe0f2fb
5 changed files with 31 additions and 19 deletions

View file

@ -3,8 +3,8 @@
<requires> <requires>
<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="plugin.video.plexkodiconnect.movies" version="2.0.0" /> <import addon="plugin.video.plexkodiconnect.movies" version="2.0.1" />
<import addon="plugin.video.plexkodiconnect.tvshows" version="2.0.1" /> <import addon="plugin.video.plexkodiconnect.tvshows" version="2.0.2" />
</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>

View file

@ -636,7 +636,7 @@ def init_plex_playqueue(itemid, librarySectionUUID, mediatype='movie',
xml[0].tag xml[0].tag
except (IndexError, TypeError, AttributeError): except (IndexError, TypeError, AttributeError):
LOG.error("Error retrieving metadata for %s", url) LOG.error("Error retrieving metadata for %s", url)
return None return
return xml return xml

View file

@ -49,10 +49,11 @@ def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
the first pass - e.g. if you're calling this function from the original the first pass - e.g. if you're calling this function from the original
service.py Python instance service.py Python instance
""" """
LOG.info('playback_triage called with plex_id %s, plex_type %s, path %s', LOG.info('playback_triage called with plex_id %s, plex_type %s, path %s, '
plex_id, plex_type, path) 'resolve %s,', plex_id, plex_type, path, resolve)
global RESOLVE global RESOLVE
RESOLVE = resolve # If started via Kodi context menu, we never resolve
RESOLVE = resolve if not state.CONTEXT_MENU_PLAY else False
if not state.AUTHENTICATED: if not state.AUTHENTICATED:
LOG.error('Not yet authenticated for PMS, abort starting playback') LOG.error('Not yet authenticated for PMS, abort starting playback')
# "Unauthorized for PMS" # "Unauthorized for PMS"
@ -64,7 +65,7 @@ def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
pos = js.get_position(playqueue.playlistid) pos = js.get_position(playqueue.playlistid)
# Can return -1 (as in "no playlist") # Can return -1 (as in "no playlist")
pos = pos if pos != -1 else 0 pos = pos if pos != -1 else 0
LOG.debug('playQueue position: %s for %s', pos, playqueue) LOG.debug('playQueue position %s for %s', pos, playqueue)
# Have we already initiated playback? # Have we already initiated playback?
try: try:
item = playqueue.items[pos] item = playqueue.items[pos]
@ -98,7 +99,7 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
try: try:
_init_existing_kodi_playlist(playqueue, pos) _init_existing_kodi_playlist(playqueue, pos)
except PL.PlaylistError: except PL.PlaylistError:
LOG.error('Aborting playback_init for longer Kodi playlist') LOG.error('Playback_init for existing Kodi playlist failed')
_ensure_resolve(abort=True) _ensure_resolve(abort=True)
return return
# Now we need to use setResolvedUrl for the item at position ZERO # Now we need to use setResolvedUrl for the item at position ZERO
@ -107,7 +108,8 @@ 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
# Fail the item we're trying to play now so we can restart the player # Pass dummy PKC video with 0 length so Kodi immediately stops playback
# and we can build our own playqueue.
_ensure_resolve() _ensure_resolve()
api = API(xml[0]) api = API(xml[0])
trailers = False trailers = False
@ -120,6 +122,10 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
else: else:
trailers = True trailers = True
LOG.debug('Playing trailers: %s', trailers) LOG.debug('Playing trailers: %s', trailers)
if RESOLVE:
# Sleep a bit to let setResolvedUrl do its thing - bit ugly
while not state.PKC_CAUSED_STOP_DONE:
sleep(50)
playqueue.clear() playqueue.clear()
if plex_type != v.PLEX_TYPE_CLIP: if plex_type != v.PLEX_TYPE_CLIP:
# Post to the PMS to create a playqueue - in any case due to Companion # Post to the PMS to create a playqueue - in any case due to Companion
@ -132,13 +138,13 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
plex_id, xml.attrib.get('librarySectionUUID')) plex_id, xml.attrib.get('librarySectionUUID'))
# "Play error" # "Play error"
dialog('notification', lang(29999), lang(30128), icon='{error}') dialog('notification', lang(29999), lang(30128), icon='{error}')
_ensure_resolve(abort=True) # Do NOT use _ensure_resolve() because we resolved above already
state.CONTEXT_MENU_PLAY = False
state.FORCE_TRANSCODE = False
state.RESUME_PLAYBACK = False
return return
# Should already be empty, but just in case
PL.get_playlist_details_from_xml(playqueue, xml) PL.get_playlist_details_from_xml(playqueue, xml)
stack = _prep_playlist_stack(xml) stack = _prep_playlist_stack(xml)
# Sleep a bit to let setResolvedUrl do its thing - bit ugly
sleep(200)
_process_stack(playqueue, stack) _process_stack(playqueue, stack)
# Always resume if playback initiated via PMS and there IS a resume # Always resume if playback initiated via PMS and there IS a resume
# point # point
@ -146,7 +152,6 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
# Reset some playback variables # Reset some playback variables
state.CONTEXT_MENU_PLAY = False state.CONTEXT_MENU_PLAY = False
state.FORCE_TRANSCODE = False state.FORCE_TRANSCODE = False
# Do NOT set offset, because Kodi player will return here to resolveURL
# New thread to release this one sooner (e.g. harddisk spinning up) # New thread to release this one sooner (e.g. harddisk spinning up)
thread = Thread(target=threaded_playback, thread = Thread(target=threaded_playback,
args=(playqueue.kodi_pl, pos, offset)) args=(playqueue.kodi_pl, pos, offset))
@ -173,9 +178,10 @@ def _ensure_resolve(abort=False):
""" """
if RESOLVE: if RESOLVE:
LOG.debug('Passing dummy path to Kodi') LOG.debug('Passing dummy path to Kodi')
if not state.CONTEXT_MENU_PLAY: # if not state.CONTEXT_MENU_PLAY:
# Because playback won't start with context menu play # Because playback won't start with context menu play
state.PKC_CAUSED_STOP = True state.PKC_CAUSED_STOP = True
state.PKC_CAUSED_STOP_DONE = False
result = Playback_Successful() result = Playback_Successful()
result.listitem = PKC_ListItem(path=NULL_VIDEO) result.listitem = PKC_ListItem(path=NULL_VIDEO)
pickle_me(result) pickle_me(result)
@ -345,7 +351,8 @@ def process_indirect(key, offset, resolve=True):
Set resolve to False if playback should be kicked off directly, not via Set resolve to False if playback should be kicked off directly, not via
setResolvedUrl setResolvedUrl
""" """
LOG.info('process_indirect called with key: %s, offset: %s', key, offset) LOG.info('process_indirect called with key: %s, offset: %s, resolve: %s',
key, offset, resolve)
global RESOLVE global RESOLVE
RESOLVE = resolve RESOLVE = resolve
result = Playback_Successful() result = Playback_Successful()

View file

@ -151,6 +151,7 @@ class PKC_Player(xbmc.Player):
LOG.debug("ONPLAYBACK_ENDED") LOG.debug("ONPLAYBACK_ENDED")
if state.PKC_CAUSED_STOP is True: if state.PKC_CAUSED_STOP is True:
state.PKC_CAUSED_STOP = False state.PKC_CAUSED_STOP = False
state.PKC_CAUSED_STOP_DONE = True
LOG.debug('PKC caused this playback stop - ignoring') LOG.debug('PKC caused this playback stop - ignoring')
else: else:
playback_cleanup(ended=True) playback_cleanup(ended=True)

View file

@ -95,8 +95,12 @@ WEBSOCKET_QUEUE = None
# Which Kodi player is/has been active? (either int 1, 2 or 3) # Which Kodi player is/has been active? (either int 1, 2 or 3)
ACTIVE_PLAYERS = [] ACTIVE_PLAYERS = []
# Failsafe for throwing failing ListItems() back to Kodi's setResolvedUrl # Failsafe for throwing an empty video back to Kodi's setResolvedUrl to set
# up our own playlist from the very beginning
PKC_CAUSED_STOP = False PKC_CAUSED_STOP = False
# Flag if the 0 length PKC video has already failed so we can start resolving
# playback (set in player.py)
PKC_CAUSED_STOP_DONE = True
# Kodi player states - here, initial values are set # Kodi player states - here, initial values are set
PLAYER_STATES = { PLAYER_STATES = {