Fix some playqueue inconsistencies using Plex Companion
- Also fix movie helper and TV show helper add-ons
This commit is contained in:
parent
7ae831f7c3
commit
30abe0f2fb
5 changed files with 31 additions and 19 deletions
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
Loading…
Reference in a new issue