Move plex node navigation, playback to main thread

This commit is contained in:
tomkat83 2017-03-13 21:39:07 +01:00
parent ec1bae3c51
commit bf6bc26d46
4 changed files with 96 additions and 82 deletions

View file

@ -63,6 +63,9 @@ class Main():
if mode == 'play':
self.play()
elif mode == 'plex_node':
self.play()
elif mode == 'ondeck':
entrypoint.getOnDeck(itemid,
params.get('type'),
@ -83,9 +86,6 @@ class Main():
entrypoint.getInProgressEpisodes(params['tagname'],
int(params['limit']))
elif mode == 'Plex_Node':
entrypoint.Plex_Node(itemid, params.get('viewOffset'))
elif mode == 'browseplex':
entrypoint.browse_plex(key=params.get('key'),
plex_section_id=params.get('id'))
@ -168,6 +168,9 @@ class Main():
entrypoint.doMainListing()
def play(self):
"""
Start up playback_starter in main Python thread
"""
# Put the request into the 'queue'
while window('plex_play_new_item'):
sleep(50)

View file

@ -3,20 +3,18 @@ import logging
from threading import Thread
import Queue
from socket import SHUT_RDWR
from urllib import urlencode
from xbmc import sleep
from xbmc import sleep, executebuiltin
from utils import settings, ThreadMethodsAdditionalSuspend, ThreadMethods, \
window
from utils import settings, ThreadMethodsAdditionalSuspend, ThreadMethods
from plexbmchelper import listener, plexgdm, subscribers, functions, \
httppersist, plexsettings
from PlexFunctions import ParseContainerKey, GetPlexMetadata
from PlexAPI import API
import player
from entrypoint import Plex_Node
import variables as v
###############################################################################
log = logging.getLogger("PLEX."+__name__)
@ -93,23 +91,27 @@ class PlexCompanion(Thread):
self.mgr.playqueue.init_playqueue_from_plex_children(
api.getRatingKey())
else:
thread = Thread(target=Plex_Node,
args=('{server}%s' % data.get('key'),
data.get('offset'),
True,
False),)
thread.setDaemon(True)
thread.start()
params = {
'mode': 'plex_node',
'key': '{server}%s' % data.get('key'),
'view_offset': data.get('offset'),
'play_directly': 'true',
'node': 'false'
}
executebuiltin('RunPlugin(plugin://%s?%s)'
% (v.ADDON_ID, urlencode(params)))
elif (task['action'] == 'playlist' and
data.get('address') == 'node.plexapp.com'):
# E.g. watch later initiated by Companion
thread = Thread(target=Plex_Node,
args=('{server}%s' % data.get('key'),
data.get('offset'),
True),)
thread.setDaemon(True)
thread.start()
params = {
'mode': 'plex_node',
'key': '{server}%s' % data.get('key'),
'view_offset': data.get('offset'),
'play_directly': 'true'
}
executebuiltin('RunPlugin(plugin://%s?%s)'
% (v.ADDON_ID, urlencode(params)))
elif task['action'] == 'playlist':
# Get the playqueue ID

View file

@ -97,62 +97,6 @@ def togglePlexTV():
sound=False)
def Plex_Node(url, viewOffset, playdirectly=False, node=True):
"""
Called only for a SINGLE element for Plex.tv watch later
Always to return with a "setResolvedUrl"
"""
log.info('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.DownloadUtils().downloadUrl(url)
else:
xml = downloadutils.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' % str(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 = Playqueue().get_playqueue_from_type(typus)
result = pbutils.PlaybackUtils(xml, playqueue).play(
plex_id,
kodi_id=kodi_id,
plex_lib_UUID=xml.attrib.get('librarySectionUUID'))
if result.listitem:
listitem = convert_PKC_to_listitem(result.listitem)
else:
return
if playdirectly:
Player().play(listitem.getfilename(), listitem)
else:
xbmcplugin.setResolvedUrl(HANDLE, True, listitem)
##### DO RESET AUTH #####
def resetAuth():
# User tried login and failed too many times
@ -969,10 +913,9 @@ def __build_item(xml_element):
if (api.getKey().startswith('/system/services') or
api.getKey().startswith('http')):
params = {
'mode': "Plex_Node",
'id': xml_element.attrib.get('key'),
'viewOffset': xml_element.attrib.get('viewOffset', '0'),
'plex_type': xml_element.attrib.get('type')
'mode': 'plex_node',
'key': xml_element.attrib.get('key'),
'view_offset': xml_element.attrib.get('viewOffset', '0'),
}
else:
params = {

View file

@ -4,6 +4,8 @@ import logging
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
@ -12,6 +14,9 @@ from PlexFunctions import GetPlexMetadata
from PlexAPI import API
from playqueue import lock
import variables as v
from downloadutils import DownloadUtils
from PKC_listitem import convert_PKC_to_listitem
import plexdb_functions as plexdb
###############################################################################
log = logging.getLogger("PLEX."+__name__)
@ -66,9 +71,64 @@ class Playback_Starter(Thread):
% self.playqueue.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' % str(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 = self.playqueue.get_playqueue_from_type(typus)
with 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)
else:
return result
def triage(self, item):
mode, params = item.split('?', 1)
_, params = item.split('?', 1)
params = dict(parse_qsl(params))
mode = params.get('mode')
log.debug('Received mode: %s, params: %s' % (mode, params))
try:
if mode == 'play':
@ -76,6 +136,12 @@ class Playback_Starter(Thread):
params.get('dbid'))
elif mode == 'companion':
result = self.process_companion()
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)
except:
log.error('Error encountered for mode %s, params %s'
% (mode, params))