Move plex node navigation, playback to main thread
This commit is contained in:
parent
ec1bae3c51
commit
bf6bc26d46
4 changed files with 96 additions and 82 deletions
|
@ -63,6 +63,9 @@ class Main():
|
||||||
if mode == 'play':
|
if mode == 'play':
|
||||||
self.play()
|
self.play()
|
||||||
|
|
||||||
|
elif mode == 'plex_node':
|
||||||
|
self.play()
|
||||||
|
|
||||||
elif mode == 'ondeck':
|
elif mode == 'ondeck':
|
||||||
entrypoint.getOnDeck(itemid,
|
entrypoint.getOnDeck(itemid,
|
||||||
params.get('type'),
|
params.get('type'),
|
||||||
|
@ -83,9 +86,6 @@ class Main():
|
||||||
entrypoint.getInProgressEpisodes(params['tagname'],
|
entrypoint.getInProgressEpisodes(params['tagname'],
|
||||||
int(params['limit']))
|
int(params['limit']))
|
||||||
|
|
||||||
elif mode == 'Plex_Node':
|
|
||||||
entrypoint.Plex_Node(itemid, params.get('viewOffset'))
|
|
||||||
|
|
||||||
elif mode == 'browseplex':
|
elif mode == 'browseplex':
|
||||||
entrypoint.browse_plex(key=params.get('key'),
|
entrypoint.browse_plex(key=params.get('key'),
|
||||||
plex_section_id=params.get('id'))
|
plex_section_id=params.get('id'))
|
||||||
|
@ -168,6 +168,9 @@ class Main():
|
||||||
entrypoint.doMainListing()
|
entrypoint.doMainListing()
|
||||||
|
|
||||||
def play(self):
|
def play(self):
|
||||||
|
"""
|
||||||
|
Start up playback_starter in main Python thread
|
||||||
|
"""
|
||||||
# Put the request into the 'queue'
|
# Put the request into the 'queue'
|
||||||
while window('plex_play_new_item'):
|
while window('plex_play_new_item'):
|
||||||
sleep(50)
|
sleep(50)
|
||||||
|
|
|
@ -3,20 +3,18 @@ import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import Queue
|
import Queue
|
||||||
from socket import SHUT_RDWR
|
from socket import SHUT_RDWR
|
||||||
|
from urllib import urlencode
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep, executebuiltin
|
||||||
|
|
||||||
from utils import settings, ThreadMethodsAdditionalSuspend, ThreadMethods, \
|
from utils import settings, ThreadMethodsAdditionalSuspend, ThreadMethods
|
||||||
window
|
|
||||||
from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
||||||
httppersist, plexsettings
|
httppersist, plexsettings
|
||||||
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
import player
|
import player
|
||||||
from entrypoint import Plex_Node
|
|
||||||
import variables as v
|
import variables as v
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
@ -93,23 +91,27 @@ class PlexCompanion(Thread):
|
||||||
self.mgr.playqueue.init_playqueue_from_plex_children(
|
self.mgr.playqueue.init_playqueue_from_plex_children(
|
||||||
api.getRatingKey())
|
api.getRatingKey())
|
||||||
else:
|
else:
|
||||||
thread = Thread(target=Plex_Node,
|
params = {
|
||||||
args=('{server}%s' % data.get('key'),
|
'mode': 'plex_node',
|
||||||
data.get('offset'),
|
'key': '{server}%s' % data.get('key'),
|
||||||
True,
|
'view_offset': data.get('offset'),
|
||||||
False),)
|
'play_directly': 'true',
|
||||||
thread.setDaemon(True)
|
'node': 'false'
|
||||||
thread.start()
|
}
|
||||||
|
executebuiltin('RunPlugin(plugin://%s?%s)'
|
||||||
|
% (v.ADDON_ID, urlencode(params)))
|
||||||
|
|
||||||
elif (task['action'] == 'playlist' and
|
elif (task['action'] == 'playlist' and
|
||||||
data.get('address') == 'node.plexapp.com'):
|
data.get('address') == 'node.plexapp.com'):
|
||||||
# E.g. watch later initiated by Companion
|
# E.g. watch later initiated by Companion
|
||||||
thread = Thread(target=Plex_Node,
|
params = {
|
||||||
args=('{server}%s' % data.get('key'),
|
'mode': 'plex_node',
|
||||||
data.get('offset'),
|
'key': '{server}%s' % data.get('key'),
|
||||||
True),)
|
'view_offset': data.get('offset'),
|
||||||
thread.setDaemon(True)
|
'play_directly': 'true'
|
||||||
thread.start()
|
}
|
||||||
|
executebuiltin('RunPlugin(plugin://%s?%s)'
|
||||||
|
% (v.ADDON_ID, urlencode(params)))
|
||||||
|
|
||||||
elif task['action'] == 'playlist':
|
elif task['action'] == 'playlist':
|
||||||
# Get the playqueue ID
|
# Get the playqueue ID
|
||||||
|
|
|
@ -97,62 +97,6 @@ def togglePlexTV():
|
||||||
sound=False)
|
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 #####
|
##### DO RESET AUTH #####
|
||||||
def resetAuth():
|
def resetAuth():
|
||||||
# User tried login and failed too many times
|
# User tried login and failed too many times
|
||||||
|
@ -969,10 +913,9 @@ def __build_item(xml_element):
|
||||||
if (api.getKey().startswith('/system/services') or
|
if (api.getKey().startswith('/system/services') or
|
||||||
api.getKey().startswith('http')):
|
api.getKey().startswith('http')):
|
||||||
params = {
|
params = {
|
||||||
'mode': "Plex_Node",
|
'mode': 'plex_node',
|
||||||
'id': xml_element.attrib.get('key'),
|
'key': xml_element.attrib.get('key'),
|
||||||
'viewOffset': xml_element.attrib.get('viewOffset', '0'),
|
'view_offset': xml_element.attrib.get('viewOffset', '0'),
|
||||||
'plex_type': xml_element.attrib.get('type')
|
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
params = {
|
params = {
|
||||||
|
|
|
@ -4,6 +4,8 @@ import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from urlparse import parse_qsl
|
from urlparse import parse_qsl
|
||||||
|
|
||||||
|
from xbmc import Player
|
||||||
|
|
||||||
from PKC_listitem import PKC_ListItem
|
from PKC_listitem import PKC_ListItem
|
||||||
from pickler import pickle_me, Playback_Successful
|
from pickler import pickle_me, Playback_Successful
|
||||||
from playbackutils import PlaybackUtils
|
from playbackutils import PlaybackUtils
|
||||||
|
@ -12,6 +14,9 @@ from PlexFunctions import GetPlexMetadata
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
from playqueue import lock
|
from playqueue import lock
|
||||||
import variables as v
|
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__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
@ -66,9 +71,64 @@ class Playback_Starter(Thread):
|
||||||
% self.playqueue.playqueues)
|
% self.playqueue.playqueues)
|
||||||
return result
|
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):
|
def triage(self, item):
|
||||||
mode, params = item.split('?', 1)
|
_, params = item.split('?', 1)
|
||||||
params = dict(parse_qsl(params))
|
params = dict(parse_qsl(params))
|
||||||
|
mode = params.get('mode')
|
||||||
log.debug('Received mode: %s, params: %s' % (mode, params))
|
log.debug('Received mode: %s, params: %s' % (mode, params))
|
||||||
try:
|
try:
|
||||||
if mode == 'play':
|
if mode == 'play':
|
||||||
|
@ -76,6 +136,12 @@ class Playback_Starter(Thread):
|
||||||
params.get('dbid'))
|
params.get('dbid'))
|
||||||
elif mode == 'companion':
|
elif mode == 'companion':
|
||||||
result = self.process_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:
|
except:
|
||||||
log.error('Error encountered for mode %s, params %s'
|
log.error('Error encountered for mode %s, params %s'
|
||||||
% (mode, params))
|
% (mode, params))
|
||||||
|
|
Loading…
Add table
Reference in a new issue