Enable Kodi playback for an entire PMS xml

This commit is contained in:
croneter 2018-01-31 07:42:23 +01:00
parent 336d50cd3a
commit 0eb526add4
3 changed files with 109 additions and 95 deletions

View file

@ -1653,13 +1653,19 @@ class API():
url = "%s&X-Plex-Token=%s" % (url, window('pms_token')) url = "%s&X-Plex-Token=%s" % (url, window('pms_token'))
return url return url
def GetPlayQueueItemID(self): def getItemId(self):
""" """
Returns current playQueueItemID for the item. Returns current playQueueItemID or if unsuccessful the playListItemID
If not found, None is returned
If not found, empty str is returned
""" """
return self.item.attrib.get('playQueueItemID') try:
answ = self.item.attrib['playQueueItemID']
except KeyError:
try:
answ = self.item.attrib['playListItemID']
except KeyError:
answ = None
return answ
def getDataFromPartOrMedia(self, key): def getDataFromPartOrMedia(self, key):
""" """

View file

@ -29,73 +29,6 @@ LOG = getLogger("PLEX." + __name__)
############################################################################### ###############################################################################
def process_indirect(key, offset, resolve=True):
"""
Called e.g. for Plex "Play later" - Plex items where we need to fetch an
additional xml for the actual playurl. In the PMS metadata, indirect="1" is
set.
Will release default.py with setResolvedUrl
Set resolve to False if playback should be kicked off directly, not via
setResolvedUrl
"""
LOG.info('process_indirect called with key: %s, offset: %s', key, offset)
result = Playback_Successful()
if key.startswith('http') or key.startswith('{server}'):
xml = DU().downloadUrl(key)
elif key.startswith('/system/services'):
xml = DU().downloadUrl('http://node.plexapp.com:32400%s' % key)
else:
xml = DU().downloadUrl('{server}%s' % key)
try:
xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not download PMS metadata')
if resolve is True:
# Release default.py
pickle_me(result)
return
if offset != '0':
offset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(offset))
# Todo: implement offset
api = API(xml[0])
listitem = PKC_ListItem()
api.CreateListItemFromPlexItem(listitem)
playqueue = PQ.get_playqueue_from_type(
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
playqueue.clear()
item = PL.Playlist_Item()
item.xml = xml[0]
item.offset = int(offset)
item.plex_type = v.PLEX_TYPE_CLIP
item.playmethod = 'DirectStream'
item.init_done = True
# Need to get yet another xml to get the final playback url
xml = DU().downloadUrl('http://node.plexapp.com:32400%s'
% xml[0][0][0].attrib['key'])
try:
xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not download last xml for playurl')
if resolve is True:
# Release default.py
pickle_me(result)
return
playurl = xml[0].attrib['key']
item.file = playurl
listitem.setPath(tryEncode(playurl))
playqueue.items.append(item)
if resolve is True:
result.listitem = listitem
pickle_me(result)
else:
thread = Thread(target=Player().play,
args={'item': tryEncode(playurl), 'listitem': listitem})
thread.setDaemon(True)
LOG.info('Done initializing PKC playback, starting Kodi player')
thread.start()
@LOCKER.lockthis @LOCKER.lockthis
def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True): def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
""" """
@ -277,14 +210,16 @@ def _prep_playlist_stack(xml):
'listitem': listitem, 'listitem': listitem,
'part': part, 'part': part,
'playcount': api.getViewCount(), 'playcount': api.getViewCount(),
'offset': api.getResume() 'offset': api.getResume(),
'id': api.getItemId()
}) })
return stack return stack
def _process_stack(playqueue, stack): def _process_stack(playqueue, stack, fill_queue=False):
""" """
Takes our stack and adds the items to the PKC and Kodi playqueues. Takes our stack and adds the items to the PKC and Kodi playqueues.
Pass fill_queue=True in order to append Playlist_Items to playqueue.items
""" """
# getposition() can return -1 # getposition() can return -1
pos = max(playqueue.kodi_pl.getposition(), 0) + 1 pos = max(playqueue.kodi_pl.getposition(), 0) + 1
@ -307,8 +242,11 @@ def _process_stack(playqueue, stack):
playlist_item.playcount = item['playcount'] playlist_item.playcount = item['playcount']
playlist_item.offset = item['offset'] playlist_item.offset = item['offset']
playlist_item.part = item['part'] playlist_item.part = item['part']
playlist_item.id = item['id']
playlist_item.init_done = True playlist_item.init_done = True
pos += 1 pos += 1
if fill_queue:
playqueue.items.append(playlist_item)
def conclude_playback(playqueue, pos): def conclude_playback(playqueue, pos):
@ -354,3 +292,92 @@ def conclude_playback(playqueue, pos):
result.listitem = listitem result.listitem = listitem
pickle_me(result) pickle_me(result)
LOG.info('Done concluding playback') LOG.info('Done concluding playback')
def process_indirect(key, offset, resolve=True):
"""
Called e.g. for Plex "Play later" - Plex items where we need to fetch an
additional xml for the actual playurl. In the PMS metadata, indirect="1" is
set.
Will release default.py with setResolvedUrl
Set resolve to False if playback should be kicked off directly, not via
setResolvedUrl
"""
LOG.info('process_indirect called with key: %s, offset: %s', key, offset)
result = Playback_Successful()
if key.startswith('http') or key.startswith('{server}'):
xml = DU().downloadUrl(key)
elif key.startswith('/system/services'):
xml = DU().downloadUrl('http://node.plexapp.com:32400%s' % key)
else:
xml = DU().downloadUrl('{server}%s' % key)
try:
xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not download PMS metadata')
if resolve is True:
# Release default.py
pickle_me(result)
return
if offset != '0':
offset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(offset))
# Todo: implement offset
api = API(xml[0])
listitem = PKC_ListItem()
api.CreateListItemFromPlexItem(listitem)
playqueue = PQ.get_playqueue_from_type(
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
playqueue.clear()
item = PL.Playlist_Item()
item.xml = xml[0]
item.offset = int(offset)
item.plex_type = v.PLEX_TYPE_CLIP
item.playmethod = 'DirectStream'
item.init_done = True
# Need to get yet another xml to get the final playback url
xml = DU().downloadUrl('http://node.plexapp.com:32400%s'
% xml[0][0][0].attrib['key'])
try:
xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not download last xml for playurl')
if resolve is True:
# Release default.py
pickle_me(result)
return
playurl = xml[0].attrib['key']
item.file = playurl
listitem.setPath(tryEncode(playurl))
playqueue.items.append(item)
if resolve is True:
result.listitem = listitem
pickle_me(result)
else:
thread = Thread(target=Player().play,
args={'item': tryEncode(playurl), 'listitem': listitem})
thread.setDaemon(True)
LOG.info('Done initializing PKC playback, starting Kodi player')
thread.start()
def play_xml(playqueue, xml):
"""
Play all items contained in the xml passed in. Called by Plex Companion.
"""
LOG.info("play_xml called")
stack = _prep_playlist_stack(xml)
_process_stack(playqueue, stack, fill_queue=True)
LOG.debug('Playqueue after play_xml update: %s', playqueue)
for startpos, item in enumerate(playqueue.items):
if item.id == playqueue.selectedItemID:
break
else:
startpos = 0
# New thread to release this one sooner (e.g. harddisk spinning up)
thread = Thread(target=Player().play,
args=(playqueue.kodi_pl, None, False, startpos))
thread.setDaemon(True)
LOG.info('Done play_xml, starting Kodi player at position %s', startpos)
thread.start()

View file

@ -10,7 +10,7 @@ from utils import window
import playlist_func as PL import playlist_func as PL
from PlexFunctions import ConvertPlexToKodiTime, GetAllPlexChildren from PlexFunctions import ConvertPlexToKodiTime, GetAllPlexChildren
from PlexAPI import API from PlexAPI import API
from playbackutils import PlaybackUtils from playback import play_xml
import json_rpc as js import json_rpc as js
import variables as v import variables as v
@ -124,23 +124,4 @@ def update_playqueue_from_PMS(playqueue,
return return
playqueue.repeat = 0 if not repeat else int(repeat) playqueue.repeat = 0 if not repeat else int(repeat)
playqueue.plex_transient_token = transient_token playqueue.plex_transient_token = transient_token
PlaybackUtils(xml, playqueue).play_all() play_xml(playqueue, xml)
window('plex_customplaylist', value="true")
if offset not in (None, "0"):
window('plex_customplaylist.seektime',
str(ConvertPlexToKodiTime(offset)))
for startpos, item in enumerate(playqueue.items):
if item.id == playqueue.selectedItemID:
break
else:
startpos = 0
# Start playback. Player does not return in time
LOG.debug('Playqueues after Plex Companion update are now: %s',
PLAYQUEUES)
thread = Thread(target=Player().play,
args=(playqueue.kodi_pl,
None,
False,
startpos))
thread.setDaemon(True)
thread.start()