Revamp playback start, part 7
This commit is contained in:
parent
0e3a7a1673
commit
dfd5297cd3
3 changed files with 75 additions and 124 deletions
|
@ -820,7 +820,7 @@ def __build_item(xml_element):
|
|||
params = {
|
||||
'mode': 'plex_node',
|
||||
'key': xml_element.attrib.get('key'),
|
||||
'view_offset': xml_element.attrib.get('viewOffset', '0'),
|
||||
'offset': xml_element.attrib.get('viewOffset', '0'),
|
||||
}
|
||||
url = "plugin://%s?%s" % (v.ADDON_ID, urlencode(params))
|
||||
elif api.getType() == v.PLEX_TYPE_PHOTO:
|
||||
|
@ -828,9 +828,8 @@ def __build_item(xml_element):
|
|||
else:
|
||||
params = {
|
||||
'mode': 'play',
|
||||
'filename': api.getKey(),
|
||||
'id': api.getRatingKey(),
|
||||
'dbid': listitem.getProperty('dbid')
|
||||
'plex_id': api.getRatingKey(),
|
||||
'plex_type': api.getType(),
|
||||
}
|
||||
url = "plugin://%s?%s" % (v.ADDON_ID, urlencode(params))
|
||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||
|
|
|
@ -9,6 +9,7 @@ from xbmc import Player, sleep
|
|||
|
||||
from PlexAPI import API
|
||||
from PlexFunctions import GetPlexMetadata, init_plex_playqueue
|
||||
from downloadutils import DownloadUtils as DU
|
||||
import plexdb_functions as plexdb
|
||||
import playlist_func as PL
|
||||
import playqueue as PQ
|
||||
|
@ -28,6 +29,71 @@ 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)
|
||||
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
|
||||
def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
|
||||
"""
|
||||
|
@ -154,12 +220,6 @@ def playback_init(plex_id, plex_type, playqueue):
|
|||
playqueue.clear()
|
||||
PL.get_playlist_details_from_xml(playqueue, xml)
|
||||
stack = _prep_playlist_stack(xml)
|
||||
# if resume:
|
||||
# # Need to handle this differently so only 1 dialog is displayed whether
|
||||
# # user wants to resume to start at the beginning
|
||||
# LOG.info('Resume detected')
|
||||
# play_resume(playqueue, xml, stack)
|
||||
# return
|
||||
# Sleep a bit to let setResolvedUrl do its thing - bit ugly
|
||||
sleep(200)
|
||||
_process_stack(playqueue, stack)
|
||||
|
|
|
@ -4,20 +4,8 @@ from logging import getLogger
|
|||
from threading import Thread
|
||||
from urlparse import parse_qsl
|
||||
|
||||
from xbmc import Player
|
||||
|
||||
from PKC_listitem import PKC_ListItem
|
||||
from pickler import pickle_me, Playback_Successful
|
||||
from playbackutils import PlaybackUtils
|
||||
import playback
|
||||
from utils import window
|
||||
from PlexFunctions import GetPlexMetadata
|
||||
from PlexAPI import API
|
||||
import playqueue as PQ
|
||||
import variables as v
|
||||
from downloadutils import DownloadUtils
|
||||
from PKC_listitem import convert_PKC_to_listitem
|
||||
import plexdb_functions as plexdb
|
||||
from context_entry import ContextMenu
|
||||
import state
|
||||
|
||||
|
@ -32,118 +20,22 @@ class Playback_Starter(Thread):
|
|||
"""
|
||||
Processes new plays
|
||||
"""
|
||||
def process_play(self, plex_id, kodi_id=None):
|
||||
"""
|
||||
Processes Kodi playback init for ONE item
|
||||
"""
|
||||
LOG.info("Process_play called with plex_id %s, kodi_id %s",
|
||||
plex_id, kodi_id)
|
||||
if not state.AUTHENTICATED:
|
||||
LOG.error('Not yet authenticated for PMS, abort starting playback')
|
||||
# Todo: Warn user with dialog
|
||||
return
|
||||
xml = GetPlexMetadata(plex_id)
|
||||
try:
|
||||
xml[0].attrib
|
||||
except (IndexError, TypeError, AttributeError):
|
||||
LOG.error('Could not get a PMS xml for plex id %s', plex_id)
|
||||
return
|
||||
api = API(xml[0])
|
||||
if api.getType() == v.PLEX_TYPE_PHOTO:
|
||||
# Photo
|
||||
result = Playback_Successful()
|
||||
listitem = PKC_ListItem()
|
||||
listitem = api.CreateListItemFromPlexItem(listitem)
|
||||
result.listitem = listitem
|
||||
else:
|
||||
# Video and Music
|
||||
playqueue = PQ.get_playqueue_from_type(
|
||||
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
|
||||
with PQ.LOCK:
|
||||
result = PlaybackUtils(xml, playqueue).play(
|
||||
plex_id,
|
||||
kodi_id,
|
||||
xml.attrib.get('librarySectionUUID'))
|
||||
LOG.info('Done process_play, playqueues: %s', PQ.PLAYQUEUES)
|
||||
return result
|
||||
|
||||
def process_plex_node(self, url, viewOffset, directplay=False,
|
||||
node=True):
|
||||
"""
|
||||
Called for Plex directories or redirect for playback (e.g. trailers,
|
||||
clips, watchlater)
|
||||
"""
|
||||
LOG.info('process_plex_node called with url: %s, viewOffset: %s',
|
||||
url, viewOffset)
|
||||
# Plex redirect, e.g. watch later. Need to get actual URLs
|
||||
if url.startswith('http') or url.startswith('{server}'):
|
||||
xml = DownloadUtils().downloadUrl(url)
|
||||
else:
|
||||
xml = DownloadUtils().downloadUrl('{server}%s' % url)
|
||||
try:
|
||||
xml[0].attrib
|
||||
except:
|
||||
LOG.error('Could not download PMS metadata')
|
||||
return
|
||||
if viewOffset != '0':
|
||||
try:
|
||||
viewOffset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(viewOffset))
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
window('plex_customplaylist.seektime', value=str(viewOffset))
|
||||
LOG.info('Set resume point to %s', viewOffset)
|
||||
api = API(xml[0])
|
||||
typus = v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()]
|
||||
if node is True:
|
||||
plex_id = None
|
||||
kodi_id = 'plexnode'
|
||||
else:
|
||||
plex_id = api.getRatingKey()
|
||||
kodi_id = None
|
||||
with plexdb.Get_Plex_DB() as plex_db:
|
||||
plexdb_item = plex_db.getItem_byId(plex_id)
|
||||
try:
|
||||
kodi_id = plexdb_item[0]
|
||||
except TypeError:
|
||||
LOG.info('Couldnt find item %s in Kodi db',
|
||||
api.getRatingKey())
|
||||
playqueue = PQ.get_playqueue_from_type(typus)
|
||||
with PQ.LOCK:
|
||||
result = PlaybackUtils(xml, playqueue).play(
|
||||
plex_id,
|
||||
kodi_id=kodi_id,
|
||||
plex_lib_UUID=xml.attrib.get('librarySectionUUID'))
|
||||
if directplay:
|
||||
if result.listitem:
|
||||
listitem = convert_PKC_to_listitem(result.listitem)
|
||||
Player().play(listitem.getfilename(), listitem)
|
||||
return Playback_Successful()
|
||||
else:
|
||||
return result
|
||||
|
||||
def triage(self, item):
|
||||
_, params = item.split('?', 1)
|
||||
params = dict(parse_qsl(params))
|
||||
mode = params.get('mode')
|
||||
LOG.debug('Received mode: %s, params: %s', mode, params)
|
||||
if mode == 'play':
|
||||
result = playback.playback_triage(plex_id=params.get('plex_id'),
|
||||
plex_type=params.get('plex_type'),
|
||||
path=params.get('path'))
|
||||
elif mode == 'companion':
|
||||
result = self.process_companion()
|
||||
playback.playback_triage(plex_id=params.get('plex_id'),
|
||||
plex_type=params.get('plex_type'),
|
||||
path=params.get('path'))
|
||||
elif mode == 'plex_node':
|
||||
result = self.process_plex_node(
|
||||
params.get('key'),
|
||||
params.get('view_offset'),
|
||||
directplay=True if params.get('play_directly') else False,
|
||||
node=False if params.get('node') == 'false' else True)
|
||||
playback.process_indirect(params['key'], params['offset'])
|
||||
elif mode == 'context_menu':
|
||||
ContextMenu()
|
||||
result = Playback_Successful()
|
||||
# Let default.py know!
|
||||
# pickle_me(result)
|
||||
# Let default.py know!
|
||||
pickle_me(result)
|
||||
|
||||
def run(self):
|
||||
queue = state.COMMAND_PIPELINE_QUEUE
|
||||
|
|
Loading…
Reference in a new issue