Enable playback of existing Kodi playqueue
This commit is contained in:
parent
0b2592be5e
commit
733e915506
1 changed files with 66 additions and 25 deletions
|
@ -24,9 +24,9 @@ import variables as v
|
||||||
import state
|
import state
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
LOG = getLogger("PLEX." + __name__)
|
LOG = getLogger("PLEX." + __name__)
|
||||||
|
# Do we need to return ultimately with a setResolvedUrl?
|
||||||
|
RESOLVE = True
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,13 +49,13 @@ def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
|
||||||
"""
|
"""
|
||||||
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)
|
plex_id, plex_type, path)
|
||||||
|
global RESOLVE
|
||||||
|
RESOLVE = resolve
|
||||||
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')
|
||||||
if resolve is True:
|
|
||||||
# Release default.py
|
|
||||||
pickle_me(Playback_Successful())
|
|
||||||
# "Unauthorized for PMS"
|
# "Unauthorized for PMS"
|
||||||
dialog('notification', lang(29999), lang(30017))
|
dialog('notification', lang(29999), lang(30017))
|
||||||
|
_ensure_resolve()
|
||||||
return
|
return
|
||||||
playqueue = PQ.get_playqueue_from_type(
|
playqueue = PQ.get_playqueue_from_type(
|
||||||
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type])
|
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type])
|
||||||
|
@ -67,19 +67,13 @@ def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
|
||||||
try:
|
try:
|
||||||
playqueue.items[pos]
|
playqueue.items[pos]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# Release our default.py before starting our own Kodi player instance
|
_playback_init(plex_id, plex_type, playqueue, pos)
|
||||||
if resolve is True:
|
|
||||||
state.PKC_CAUSED_STOP = True
|
|
||||||
result = Playback_Successful()
|
|
||||||
result.listitem = PKC_ListItem(path='PKC_Dummy_Path_Which_Fails')
|
|
||||||
pickle_me(result)
|
|
||||||
playback_init(plex_id, plex_type, playqueue)
|
|
||||||
else:
|
else:
|
||||||
# kick off playback on second pass
|
# kick off playback on second pass
|
||||||
conclude_playback(playqueue, pos)
|
_conclude_playback(playqueue, pos)
|
||||||
|
|
||||||
|
|
||||||
def playback_init(plex_id, plex_type, playqueue):
|
def _playback_init(plex_id, plex_type, playqueue, pos):
|
||||||
"""
|
"""
|
||||||
Playback setup if Kodi starts playing an item for the first time.
|
Playback setup if Kodi starts playing an item for the first time.
|
||||||
"""
|
"""
|
||||||
|
@ -91,9 +85,23 @@ def playback_init(plex_id, plex_type, playqueue):
|
||||||
LOG.error('Could not get a PMS xml for plex id %s', plex_id)
|
LOG.error('Could not get a PMS xml for plex id %s', plex_id)
|
||||||
# "Play error"
|
# "Play error"
|
||||||
dialog('notification', lang(29999), lang(30128), icon='{error}')
|
dialog('notification', lang(29999), lang(30128), icon='{error}')
|
||||||
|
_ensure_resolve()
|
||||||
return
|
return
|
||||||
trailers = False
|
if playqueue.kodi_pl.size() > 1:
|
||||||
|
# Special case - we already got a filled Kodi playqueue
|
||||||
|
try:
|
||||||
|
_init_existing_kodi_playlist(playqueue)
|
||||||
|
except PL.PlaylistError:
|
||||||
|
LOG.error('Aborting playback_init for longer Kodi playlist')
|
||||||
|
_ensure_resolve()
|
||||||
|
return
|
||||||
|
# Now we need to use setResolvedUrl for the item at position pos
|
||||||
|
_conclude_playback(playqueue, pos)
|
||||||
|
return
|
||||||
|
# "Usual" case - consider trailers and parts and build both Kodi and Plex
|
||||||
|
# playqueues
|
||||||
api = API(xml[0])
|
api = API(xml[0])
|
||||||
|
trailers = False
|
||||||
if (plex_type == v.PLEX_TYPE_MOVIE and not api.resume_point() and
|
if (plex_type == v.PLEX_TYPE_MOVIE and not api.resume_point() and
|
||||||
settings('enableCinema') == "true"):
|
settings('enableCinema') == "true"):
|
||||||
if settings('askCinema') == "true":
|
if settings('askCinema') == "true":
|
||||||
|
@ -115,6 +123,7 @@ def playback_init(plex_id, plex_type, playqueue):
|
||||||
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()
|
||||||
return
|
return
|
||||||
# Should already be empty, but just in case
|
# Should already be empty, but just in case
|
||||||
PL.get_playlist_details_from_xml(playqueue, xml)
|
PL.get_playlist_details_from_xml(playqueue, xml)
|
||||||
|
@ -139,6 +148,39 @@ def playback_init(plex_id, plex_type, playqueue):
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_resolve():
|
||||||
|
"""
|
||||||
|
Will check whether RESOLVE=True and if so, fail Kodi playback startup
|
||||||
|
with the path 'PKC_Dummy_Path_Which_Fails' using setResolvedUrl (and some
|
||||||
|
pickling)
|
||||||
|
|
||||||
|
This way we're making sure that other Python instances (calling default.py)
|
||||||
|
will be destroyed.
|
||||||
|
"""
|
||||||
|
if RESOLVE is True:
|
||||||
|
state.PKC_CAUSED_STOP = True
|
||||||
|
result = Playback_Successful()
|
||||||
|
result.listitem = PKC_ListItem(path='PKC_Dummy_Path_Which_Fails')
|
||||||
|
pickle_me(result)
|
||||||
|
|
||||||
|
|
||||||
|
def _init_existing_kodi_playlist(playqueue):
|
||||||
|
"""
|
||||||
|
Will take the playqueue's kodi_pl with MORE than 1 element and initiate
|
||||||
|
playback (without adding trailers)
|
||||||
|
"""
|
||||||
|
LOG.debug('Kodi playlist size: %s', playqueue.kodi_pl.size())
|
||||||
|
for i, kodi_item in enumerate(js.playlist_get_items(playqueue.playlistid)):
|
||||||
|
if i == 0:
|
||||||
|
item = PL.init_Plex_playlist(playqueue, kodi_item=kodi_item)
|
||||||
|
else:
|
||||||
|
item = PL.add_item_to_PMS_playlist(playqueue,
|
||||||
|
i,
|
||||||
|
kodi_item=kodi_item)
|
||||||
|
item.force_transcode = state.FORCE_TRANSCODE
|
||||||
|
LOG.debug('Done building Plex playlist from Kodi playlist')
|
||||||
|
|
||||||
|
|
||||||
def _prep_playlist_stack(xml):
|
def _prep_playlist_stack(xml):
|
||||||
stack = []
|
stack = []
|
||||||
for item in xml:
|
for item in xml:
|
||||||
|
@ -152,7 +194,9 @@ def _prep_playlist_stack(xml):
|
||||||
kodi_id = plex_dbitem[0] if plex_dbitem else None
|
kodi_id = plex_dbitem[0] if plex_dbitem else None
|
||||||
kodi_type = plex_dbitem[4] if plex_dbitem else None
|
kodi_type = plex_dbitem[4] if plex_dbitem else None
|
||||||
else:
|
else:
|
||||||
# We will never store clips (trailers) in the Kodi DB
|
# We will never store clips (trailers) in the Kodi DB.
|
||||||
|
# Also set kodi_id to None for playback via PMS, so that we're
|
||||||
|
# using add-on paths.
|
||||||
kodi_id = None
|
kodi_id = None
|
||||||
kodi_type = None
|
kodi_type = None
|
||||||
for part, _ in enumerate(item[0]):
|
for part, _ in enumerate(item[0]):
|
||||||
|
@ -165,8 +209,7 @@ def _prep_playlist_stack(xml):
|
||||||
'plex_type': api.plex_type()
|
'plex_type': api.plex_type()
|
||||||
}
|
}
|
||||||
path = ('plugin://%s/?%s'
|
path = ('plugin://%s/?%s'
|
||||||
% (v.ADDON_TYPE[api.plex_type()],
|
% (v.ADDON_TYPE[api.plex_type()], urlencode(params)))
|
||||||
urlencode(params)))
|
|
||||||
listitem = api.create_listitem()
|
listitem = api.create_listitem()
|
||||||
listitem.setPath(try_encode(path))
|
listitem.setPath(try_encode(path))
|
||||||
else:
|
else:
|
||||||
|
@ -217,7 +260,7 @@ def _process_stack(playqueue, stack):
|
||||||
pos += 1
|
pos += 1
|
||||||
|
|
||||||
|
|
||||||
def conclude_playback(playqueue, pos):
|
def _conclude_playback(playqueue, pos):
|
||||||
"""
|
"""
|
||||||
ONLY if actually being played (e.g. at 5th position of a playqueue).
|
ONLY if actually being played (e.g. at 5th position of a playqueue).
|
||||||
|
|
||||||
|
@ -281,6 +324,8 @@ def process_indirect(key, offset, resolve=True):
|
||||||
setResolvedUrl
|
setResolvedUrl
|
||||||
"""
|
"""
|
||||||
LOG.info('process_indirect called with key: %s, offset: %s', key, offset)
|
LOG.info('process_indirect called with key: %s, offset: %s', key, offset)
|
||||||
|
global RESOLVE
|
||||||
|
RESOLVE = resolve
|
||||||
result = Playback_Successful()
|
result = Playback_Successful()
|
||||||
if key.startswith('http') or key.startswith('{server}'):
|
if key.startswith('http') or key.startswith('{server}'):
|
||||||
xml = DU().downloadUrl(key)
|
xml = DU().downloadUrl(key)
|
||||||
|
@ -292,9 +337,7 @@ def process_indirect(key, offset, resolve=True):
|
||||||
xml[0].attrib
|
xml[0].attrib
|
||||||
except (TypeError, IndexError, AttributeError):
|
except (TypeError, IndexError, AttributeError):
|
||||||
LOG.error('Could not download PMS metadata')
|
LOG.error('Could not download PMS metadata')
|
||||||
if resolve is True:
|
_ensure_resolve()
|
||||||
# Release default.py
|
|
||||||
pickle_me(result)
|
|
||||||
return
|
return
|
||||||
if offset != '0':
|
if offset != '0':
|
||||||
offset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(offset))
|
offset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(offset))
|
||||||
|
@ -317,9 +360,7 @@ def process_indirect(key, offset, resolve=True):
|
||||||
xml[0].attrib
|
xml[0].attrib
|
||||||
except (TypeError, IndexError, AttributeError):
|
except (TypeError, IndexError, AttributeError):
|
||||||
LOG.error('Could not download last xml for playurl')
|
LOG.error('Could not download last xml for playurl')
|
||||||
if resolve is True:
|
_ensure_resolve()
|
||||||
# Release default.py
|
|
||||||
pickle_me(result)
|
|
||||||
return
|
return
|
||||||
playurl = xml[0].attrib['key']
|
playurl = xml[0].attrib['key']
|
||||||
item.file = playurl
|
item.file = playurl
|
||||||
|
|
Loading…
Reference in a new issue