Revamp playback start, part 2
This commit is contained in:
parent
24f2f60209
commit
fb7eafb27a
6 changed files with 310 additions and 135 deletions
|
@ -291,12 +291,11 @@ class Movies(Items):
|
||||||
path = playurl.replace(filename, "")
|
path = playurl.replace(filename, "")
|
||||||
if doIndirect:
|
if doIndirect:
|
||||||
# Set plugin path and media flags using real filename
|
# Set plugin path and media flags using real filename
|
||||||
path = "plugin://plugin.video.plexkodiconnect/movies/"
|
path = "plugin://plugin.video.plexkodiconnect"
|
||||||
params = {
|
params = {
|
||||||
'filename': API.getKey(),
|
'mode': 'play',
|
||||||
'id': itemid,
|
'plex_id': itemid,
|
||||||
'dbid': movieid,
|
'plex_type': v.PLEX_TYPE_MOVIE
|
||||||
'mode': "play"
|
|
||||||
}
|
}
|
||||||
filename = "%s?%s" % (path, urlencode(params))
|
filename = "%s?%s" % (path, urlencode(params))
|
||||||
playurl = filename
|
playurl = filename
|
||||||
|
|
|
@ -12,11 +12,11 @@ from PlexFunctions import scrobble
|
||||||
from kodidb_functions import kodiid_from_filename
|
from kodidb_functions import kodiid_from_filename
|
||||||
from plexbmchelper.subscribers import LOCKER
|
from plexbmchelper.subscribers import LOCKER
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
|
import playqueue as PQ
|
||||||
import json_rpc as js
|
import json_rpc as js
|
||||||
import playlist_func as PL
|
import playlist_func as PL
|
||||||
import state
|
import state
|
||||||
import variables as v
|
import variables as v
|
||||||
import playqueue as PQ
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -254,31 +254,16 @@ class KodiMonitor(Monitor):
|
||||||
return
|
return
|
||||||
playqueue.clear()
|
playqueue.clear()
|
||||||
|
|
||||||
@LOCKER.lockthis
|
def _get_ids(self, json_item):
|
||||||
def PlayBackStart(self, data):
|
|
||||||
"""
|
"""
|
||||||
Called whenever playback is started. Example data:
|
|
||||||
{
|
|
||||||
u'item': {u'type': u'movie', u'title': u''},
|
|
||||||
u'player': {u'playerid': 1, u'speed': 1}
|
|
||||||
}
|
|
||||||
Unfortunately when using Widgets, Kodi doesn't tell us shit
|
|
||||||
"""
|
"""
|
||||||
# Get the type of media we're playing
|
kodi_id = json_item.get('id')
|
||||||
try:
|
kodi_type = json_item.get('type')
|
||||||
kodi_type = data['item']['type']
|
path = json_item.get('file')
|
||||||
playerid = data['player']['playerid']
|
|
||||||
except (TypeError, KeyError):
|
|
||||||
LOG.info('Aborting playback report - item invalid for updates %s',
|
|
||||||
data)
|
|
||||||
return
|
|
||||||
json_data = js.get_item(playerid)
|
|
||||||
path = json_data.get('file')
|
|
||||||
kodi_id = json_data.get('id')
|
|
||||||
if not path and not kodi_id:
|
if not path and not kodi_id:
|
||||||
LOG.info('Aborting playback report - no Kodi id or file for %s',
|
LOG.info('Aborting playback report - no Kodi id or file for %s',
|
||||||
json_data)
|
json_item)
|
||||||
return
|
raise RuntimeError
|
||||||
# Plex id will NOT be set with direct paths
|
# Plex id will NOT be set with direct paths
|
||||||
plex_id = state.PLEX_IDS.get(path)
|
plex_id = state.PLEX_IDS.get(path)
|
||||||
try:
|
try:
|
||||||
|
@ -306,28 +291,49 @@ class KodiMonitor(Monitor):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# No plex id, hence item not in the library. E.g. clips
|
# No plex id, hence item not in the library. E.g. clips
|
||||||
pass
|
pass
|
||||||
info = js.get_player_props(playerid)
|
return kodi_id, kodi_type, plex_id, plex_type
|
||||||
state.PLAYER_STATES[playerid].update(info)
|
|
||||||
state.PLAYER_STATES[playerid]['file'] = path
|
@LOCKER.lockthis
|
||||||
state.PLAYER_STATES[playerid]['kodi_id'] = kodi_id
|
def PlayBackStart(self, data):
|
||||||
state.PLAYER_STATES[playerid]['kodi_type'] = kodi_type
|
"""
|
||||||
state.PLAYER_STATES[playerid]['plex_id'] = plex_id
|
Called whenever playback is started. Example data:
|
||||||
state.PLAYER_STATES[playerid]['plex_type'] = plex_type
|
{
|
||||||
LOG.debug('Set the player state: %s', state.PLAYER_STATES[playerid])
|
u'item': {u'type': u'movie', u'title': u''},
|
||||||
# Check whether we need to init our playqueues (e.g. direct play)
|
u'player': {u'playerid': 1, u'speed': 1}
|
||||||
init = False
|
}
|
||||||
playqueue = PQ.PLAYQUEUES[playerid]
|
Unfortunately when using Widgets, Kodi doesn't tell us shit
|
||||||
|
"""
|
||||||
|
# Get the type of media we're playing
|
||||||
try:
|
try:
|
||||||
playqueue.items[info['position']]
|
kodi_type = data['item']['type']
|
||||||
|
playerid = data['player']['playerid']
|
||||||
|
except (TypeError, KeyError):
|
||||||
|
LOG.info('Aborting playback report - item invalid for updates %s',
|
||||||
|
data)
|
||||||
|
return
|
||||||
|
playqueue = PQ.PLAYQUEUES[playerid]
|
||||||
|
info = js.get_player_props(playerid)
|
||||||
|
json_item = js.get_item(playerid)
|
||||||
|
path = json_item.get('file')
|
||||||
|
pos = info['position'] if info['position'] != -1 else 0
|
||||||
|
LOG.info('Detected position %s for %s', pos, playqueue)
|
||||||
|
try:
|
||||||
|
item = playqueue.items[pos]
|
||||||
|
# See if playback.py already initiated playback
|
||||||
|
init_done = item.init_done
|
||||||
except IndexError:
|
except IndexError:
|
||||||
init = True
|
init_done = False
|
||||||
if init is False and plex_id is not None:
|
if init_done is True:
|
||||||
if plex_id != playqueue.items[info['position']].plex_id:
|
kodi_id = item.kodi_id
|
||||||
init = True
|
kodi_type = item.kodi_type
|
||||||
elif init is False and path != playqueue.items[info['position']].file:
|
plex_id = item.plex_id
|
||||||
init = True
|
plex_type = item.plex_type
|
||||||
if init is True:
|
else:
|
||||||
LOG.debug('Need to initialize Plex and PKC playqueue')
|
try:
|
||||||
|
kodi_id, kodi_type, plex_id, plex_type = self._get_ids(json_item)
|
||||||
|
except RuntimeError:
|
||||||
|
return
|
||||||
|
LOG.info('Need to initialize Plex and PKC playqueue')
|
||||||
if plex_id:
|
if plex_id:
|
||||||
PL.init_Plex_playlist(playqueue, plex_id=plex_id)
|
PL.init_Plex_playlist(playqueue, plex_id=plex_id)
|
||||||
else:
|
else:
|
||||||
|
@ -335,17 +341,25 @@ class KodiMonitor(Monitor):
|
||||||
kodi_item={'id': kodi_id,
|
kodi_item={'id': kodi_id,
|
||||||
'type': kodi_type,
|
'type': kodi_type,
|
||||||
'file': path})
|
'file': path})
|
||||||
# Set the Plex container key (e.g. using the Plex playqueue)
|
# Set the Plex container key (e.g. using the Plex playqueue)
|
||||||
container_key = None
|
container_key = None
|
||||||
if info['playlistid'] != -1:
|
if info['playlistid'] != -1:
|
||||||
# -1 is Kodi's answer if there is no playlist
|
# -1 is Kodi's answer if there is no playlist
|
||||||
container_key = PQ.PLAYQUEUES[playerid].id
|
container_key = PQ.PLAYQUEUES[playerid].id
|
||||||
if container_key is not None:
|
if container_key is not None:
|
||||||
container_key = '/playQueues/%s' % container_key
|
container_key = '/playQueues/%s' % container_key
|
||||||
elif plex_id is not None:
|
elif plex_id is not None:
|
||||||
container_key = '/library/metadata/%s' % plex_id
|
container_key = '/library/metadata/%s' % plex_id
|
||||||
state.PLAYER_STATES[playerid]['container_key'] = container_key
|
state.PLAYER_STATES[playerid]['container_key'] = container_key
|
||||||
LOG.debug('Set the Plex container_key to: %s', container_key)
|
LOG.debug('Set the Plex container_key to: %s', container_key)
|
||||||
|
|
||||||
|
state.PLAYER_STATES[playerid].update(info)
|
||||||
|
state.PLAYER_STATES[playerid]['file'] = path
|
||||||
|
state.PLAYER_STATES[playerid]['kodi_id'] = kodi_id
|
||||||
|
state.PLAYER_STATES[playerid]['kodi_type'] = kodi_type
|
||||||
|
state.PLAYER_STATES[playerid]['plex_id'] = plex_id
|
||||||
|
state.PLAYER_STATES[playerid]['plex_type'] = plex_type
|
||||||
|
LOG.debug('Set the player state: %s', state.PLAYER_STATES[playerid])
|
||||||
|
|
||||||
def StartDirectPath(self, plex_id, type, currentFile):
|
def StartDirectPath(self, plex_id, type, currentFile):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,52 +1,213 @@
|
||||||
"""
|
"""
|
||||||
Used to kick off Kodi playback
|
Used to kick off Kodi playback
|
||||||
"""
|
"""
|
||||||
|
from logging import getLogger
|
||||||
|
from threading import Thread, Lock
|
||||||
|
from urllib import urlencode
|
||||||
|
|
||||||
|
from xbmc import Player, getCondVisibility, sleep
|
||||||
|
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
|
from PlexFunctions import GetPlexMetadata, init_plex_playqueue
|
||||||
|
import plexdb_functions as plexdb
|
||||||
|
import playlist_func as PL
|
||||||
import playqueue as PQ
|
import playqueue as PQ
|
||||||
from playutils import PlayUtils
|
from playutils import PlayUtils
|
||||||
from PKC_listitem import PKC_ListItem, convert_PKC_to_listitem
|
from PKC_listitem import PKC_ListItem
|
||||||
from pickler import Playback_Successful
|
from pickler import pickle_me, Playback_Successful
|
||||||
from utils import settings, dialog, language as lang
|
import json_rpc as js
|
||||||
|
from utils import window, settings, dialog, language as lang, Lock_Function
|
||||||
|
import variables as v
|
||||||
|
import state
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
LOG = getLogger("PLEX." + __name__)
|
||||||
|
LOCKER = Lock_Function(Lock())
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
def playback_setup(plex_id, kodi_id, kodi_type, path):
|
@LOCKER.lockthis
|
||||||
|
def playback_triage(plex_id=None, plex_type=None, path=None):
|
||||||
"""
|
"""
|
||||||
Get XML
|
Hit this function for addon path playback, Plex trailers, etc.
|
||||||
For the single element, e.g. including trailers and parts
|
Will setup playback first, then on second call complete playback.
|
||||||
For playQueue (init by Companion or Alexa)
|
|
||||||
Set up
|
|
||||||
PKC/Kodi/Plex Playqueue
|
|
||||||
Trailers
|
|
||||||
Clips
|
|
||||||
Several parts
|
|
||||||
companion playqueue
|
|
||||||
Alexa music album
|
|
||||||
|
|
||||||
|
Returns Playback_Successful() with potentially a PKC_ListItem() attached
|
||||||
|
(to be consumed by setResolvedURL)
|
||||||
"""
|
"""
|
||||||
|
LOG.info('playback_triage called with plex_id %s, plex_type %s, path %s',
|
||||||
|
plex_id, plex_type, path)
|
||||||
|
if not state.AUTHENTICATED:
|
||||||
|
LOG.error('Not yet authenticated for PMS, abort starting playback')
|
||||||
|
# "Unauthorized for PMS"
|
||||||
|
dialog('notification', lang(29999), lang(30017))
|
||||||
|
# Don't cause second notification to appear
|
||||||
|
return Playback_Successful()
|
||||||
|
playqueue = PQ.get_playqueue_from_type(
|
||||||
|
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type])
|
||||||
|
pos = js.get_position(playqueue.playlistid)
|
||||||
|
pos = pos if pos != -1 else 0
|
||||||
|
LOG.info('playQueue position: %s for %s', pos, playqueue)
|
||||||
|
# Have we already initiated playback?
|
||||||
|
init_done = True
|
||||||
|
try:
|
||||||
|
item = playqueue.items[pos]
|
||||||
|
except IndexError:
|
||||||
|
init_done = False
|
||||||
|
else:
|
||||||
|
init_done = item.init_done
|
||||||
|
# Either init the playback now, or - on 2nd pass - kick off playback
|
||||||
|
if init_done is False:
|
||||||
|
playback_init(plex_id, path, playqueue)
|
||||||
|
else:
|
||||||
|
conclude_playback(playqueue, pos)
|
||||||
|
|
||||||
|
|
||||||
|
def playback_init(plex_id, path, playqueue):
|
||||||
|
"""
|
||||||
|
Playback setup. Path is the original path PKC default.py has been called
|
||||||
|
with
|
||||||
|
"""
|
||||||
|
contextmenu_play = window('plex_contextplay') == 'true'
|
||||||
|
window('plex_contextplay', clear=True)
|
||||||
|
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)
|
||||||
|
# "Play error"
|
||||||
|
dialog('notification', lang(29999), lang(30128))
|
||||||
|
return
|
||||||
|
result = Playback_Successful()
|
||||||
|
listitem = PKC_ListItem()
|
||||||
|
# Set the original path again so Kodi will return a 2nd time to PKC
|
||||||
|
listitem.setPath(path)
|
||||||
|
api = API(xml[0])
|
||||||
|
plex_type = api.getType()
|
||||||
|
size_playlist = playqueue.kodi_pl.size()
|
||||||
|
# Can return -1
|
||||||
|
start_pos = max(playqueue.kodi_pl.getposition(), 0)
|
||||||
|
LOG.info("Playlist size %s", size_playlist)
|
||||||
|
LOG.info("Playlist starting position %s", start_pos)
|
||||||
|
resume, _ = api.getRuntime()
|
||||||
trailers = False
|
trailers = False
|
||||||
if (api.getType() == v.PLEX_TYPE_MOVIE and
|
if (plex_type == v.PLEX_TYPE_MOVIE and
|
||||||
not seektime and
|
not resume and
|
||||||
sizePlaylist < 2 and
|
size_playlist < 2 and
|
||||||
settings('enableCinema') == "true"):
|
settings('enableCinema') == "true"):
|
||||||
if settings('askCinema') == "true":
|
if settings('askCinema') == "true":
|
||||||
trailers = dialog('yesno', lang(29999), "Play trailers?")
|
# "Play trailers?"
|
||||||
|
trailers = dialog('yesno', lang(29999), lang(33016))
|
||||||
trailers = True if trailers else False
|
trailers = True if trailers else False
|
||||||
else:
|
else:
|
||||||
trailers = True
|
trailers = True
|
||||||
# Post to the PMS. REUSE THE PLAYQUEUE!
|
# Post to the PMS. REUSE THE PLAYQUEUE!
|
||||||
xml = init_plex_playqueue(plex_id,
|
xml = init_plex_playqueue(plex_id,
|
||||||
plex_lib_UUID,
|
xml.attrib.get('librarySectionUUID'),
|
||||||
mediatype=api.getType(),
|
mediatype=plex_type,
|
||||||
trailers=trailers)
|
trailers=trailers)
|
||||||
pass
|
if xml is None:
|
||||||
|
LOG.error('Could not get a playqueue xml for plex id %s, UUID %s',
|
||||||
|
plex_id, xml.attrib.get('librarySectionUUID'))
|
||||||
|
# "Play error"
|
||||||
|
dialog('notification', lang(29999), lang(30128))
|
||||||
|
return
|
||||||
|
playqueue.clear()
|
||||||
|
PL.get_playlist_details_from_xml(playqueue, xml)
|
||||||
|
stack = _prep_playlist_stack(xml)
|
||||||
|
force_playback = False
|
||||||
|
if (not getCondVisibility('Window.IsVisible(MyVideoNav.xml)') and
|
||||||
|
not getCondVisibility('Window.IsVisible(VideoFullScreen.xml)')):
|
||||||
|
LOG.info("Detected playback from widget")
|
||||||
|
force_playback = True
|
||||||
|
if force_playback is False:
|
||||||
|
# Return the listelement for setResolvedURL
|
||||||
|
result.listitem = listitem
|
||||||
|
pickle_me(result)
|
||||||
|
# Wait for the setResolvedUrl to have taken its course - ugly
|
||||||
|
sleep(50)
|
||||||
|
_process_stack(playqueue, stack)
|
||||||
|
else:
|
||||||
|
# Need to kickoff playback, not using setResolvedURL
|
||||||
|
pickle_me(result)
|
||||||
|
_process_stack(playqueue, stack)
|
||||||
|
# Need a separate thread because Player won't return in time
|
||||||
|
listitem.setProperty('StartOffset', str(resume))
|
||||||
|
thread = Thread(target=Player().play,
|
||||||
|
args=(playqueue.kodi_pl, ))
|
||||||
|
thread.setDaemon(True)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
|
||||||
def conclude_playback_startup(playqueue_no,
|
def _prep_playlist_stack(xml):
|
||||||
pos,
|
stack = []
|
||||||
plex_id=None,
|
for item in xml:
|
||||||
kodi_id=None,
|
api = API(item)
|
||||||
kodi_type=None,
|
with plexdb.Get_Plex_DB() as plex_db:
|
||||||
path=None):
|
plex_dbitem = plex_db.getItem_byId(api.getRatingKey())
|
||||||
|
try:
|
||||||
|
kodi_id = plex_dbitem[0]
|
||||||
|
kodi_type = plex_dbitem[4]
|
||||||
|
except TypeError:
|
||||||
|
kodi_id = None
|
||||||
|
kodi_type = None
|
||||||
|
for part_no, _ in enumerate(item[0]):
|
||||||
|
api.setPartNumber(part_no)
|
||||||
|
if kodi_id is not None:
|
||||||
|
# We don't need the URL, item is in the Kodi library
|
||||||
|
path = None
|
||||||
|
listitem = None
|
||||||
|
else:
|
||||||
|
# Need to redirect again to PKC to conclude playback
|
||||||
|
params = {
|
||||||
|
'mode': 'play',
|
||||||
|
'plex_id': api.getRatingKey(),
|
||||||
|
'plex_type': api.getType()
|
||||||
|
}
|
||||||
|
path = ('plugin://plugin.video.plexkodiconnect?%s'
|
||||||
|
% (urlencode(params)))
|
||||||
|
listitem = api.CreateListItemFromPlexItem()
|
||||||
|
api.set_listitem_artwork(listitem)
|
||||||
|
listitem.setPath(path)
|
||||||
|
stack.append({
|
||||||
|
'kodi_id': kodi_id,
|
||||||
|
'kodi_type': kodi_type,
|
||||||
|
'file': path,
|
||||||
|
'xml_video_element': item,
|
||||||
|
'listitem': listitem,
|
||||||
|
'part_no': part_no
|
||||||
|
})
|
||||||
|
return stack
|
||||||
|
|
||||||
|
|
||||||
|
def _process_stack(playqueue, stack):
|
||||||
|
"""
|
||||||
|
Takes our stack and adds the items to the PKC and Kodi playqueues.
|
||||||
|
This needs to be done AFTER setResolvedURL
|
||||||
|
"""
|
||||||
|
for i, item in enumerate(stack):
|
||||||
|
if item['kodi_id'] is not None:
|
||||||
|
# Use Kodi id & JSON so we get full artwork
|
||||||
|
playlist_item = PL.add_item_to_kodi_playlist(
|
||||||
|
playqueue,
|
||||||
|
i,
|
||||||
|
kodi_id=item['kodi_id'],
|
||||||
|
kodi_type=item['kodi_type'],
|
||||||
|
xml_video_element=item['xml_video_element'])
|
||||||
|
else:
|
||||||
|
playlist_item = PL.add_listitem_to_Kodi_playlist(
|
||||||
|
playqueue,
|
||||||
|
i,
|
||||||
|
item['listitem'],
|
||||||
|
file=item['file'],
|
||||||
|
xml_video_element=item['xml_video_element'])
|
||||||
|
playlist_item.part = item['part_no']
|
||||||
|
playlist_item.init_done = True
|
||||||
|
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
@ -63,17 +224,16 @@ def conclude_playback_startup(playqueue_no,
|
||||||
"""
|
"""
|
||||||
result = Playback_Successful()
|
result = Playback_Successful()
|
||||||
listitem = PKC_ListItem()
|
listitem = PKC_ListItem()
|
||||||
playqueue = PQ.PLAYQUEUES[playqueue_no]
|
|
||||||
item = playqueue.items[pos]
|
item = playqueue.items[pos]
|
||||||
api = API(item.xml)
|
if item.xml is not None:
|
||||||
api.setPartNumber(item.part)
|
# Got a Plex element
|
||||||
api.CreateListItemFromPlexItem(listitem)
|
api = API(item.xml)
|
||||||
if plex_id is not None:
|
api.setPartNumber(item.part)
|
||||||
|
api.CreateListItemFromPlexItem(listitem)
|
||||||
playutils = PlayUtils(api, item)
|
playutils = PlayUtils(api, item)
|
||||||
playurl = playutils.getPlayUrl()
|
playurl = playutils.getPlayUrl()
|
||||||
elif path is not None:
|
else:
|
||||||
playurl = path
|
playurl = item.file
|
||||||
item.playmethod = 'DirectStream'
|
|
||||||
listitem.setPath(playurl)
|
listitem.setPath(playurl)
|
||||||
if item.playmethod in ("DirectStream", "DirectPlay"):
|
if item.playmethod in ("DirectStream", "DirectPlay"):
|
||||||
listitem.setSubtitles(api.externalSubs())
|
listitem.setSubtitles(api.externalSubs())
|
||||||
|
@ -81,4 +241,4 @@ def conclude_playback_startup(playqueue_no,
|
||||||
playutils.audio_subtitle_prefs(listitem)
|
playutils.audio_subtitle_prefs(listitem)
|
||||||
listitem.setPath(playurl)
|
listitem.setPath(playurl)
|
||||||
result.listitem = listitem
|
result.listitem = listitem
|
||||||
return result
|
pickle_me(result)
|
||||||
|
|
|
@ -9,6 +9,7 @@ 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
|
||||||
|
import playback
|
||||||
from utils import window
|
from utils import window
|
||||||
from PlexFunctions import GetPlexMetadata
|
from PlexFunctions import GetPlexMetadata
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
|
@ -126,30 +127,23 @@ class Playback_Starter(Thread):
|
||||||
params = dict(parse_qsl(params))
|
params = dict(parse_qsl(params))
|
||||||
mode = params.get('mode')
|
mode = params.get('mode')
|
||||||
LOG.debug('Received mode: %s, params: %s', mode, params)
|
LOG.debug('Received mode: %s, params: %s', mode, params)
|
||||||
try:
|
if mode == 'play':
|
||||||
if mode == 'play':
|
result = playback.playback_triage(plex_id=params.get('plex_id'),
|
||||||
result = self.process_play(params.get('id'),
|
plex_type=params.get('plex_type'),
|
||||||
params.get('dbid'))
|
path=params.get('path'))
|
||||||
elif mode == 'companion':
|
elif mode == 'companion':
|
||||||
result = self.process_companion()
|
result = self.process_companion()
|
||||||
elif mode == 'plex_node':
|
elif mode == 'plex_node':
|
||||||
result = self.process_plex_node(
|
result = self.process_plex_node(
|
||||||
params.get('key'),
|
params.get('key'),
|
||||||
params.get('view_offset'),
|
params.get('view_offset'),
|
||||||
directplay=True if params.get('play_directly') else False,
|
directplay=True if params.get('play_directly') else False,
|
||||||
node=False if params.get('node') == 'false' else True)
|
node=False if params.get('node') == 'false' else True)
|
||||||
elif mode == 'context_menu':
|
elif mode == 'context_menu':
|
||||||
ContextMenu()
|
ContextMenu()
|
||||||
result = Playback_Successful()
|
result = Playback_Successful()
|
||||||
except:
|
# Let default.py know!
|
||||||
LOG.error('Error encountered for mode %s, params %s',
|
# pickle_me(result)
|
||||||
mode, params)
|
|
||||||
import traceback
|
|
||||||
LOG.error(traceback.format_exc())
|
|
||||||
# Let default.py know!
|
|
||||||
pickle_me(None)
|
|
||||||
else:
|
|
||||||
pickle_me(result)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
queue = state.COMMAND_PIPELINE_QUEUE
|
queue = state.COMMAND_PIPELINE_QUEUE
|
||||||
|
|
|
@ -190,6 +190,8 @@ class Playlist_Item(object):
|
||||||
guid = None [str] Weird Plex guid
|
guid = None [str] Weird Plex guid
|
||||||
xml = None [etree] XML from PMS, 1 lvl below <MediaContainer>
|
xml = None [etree] XML from PMS, 1 lvl below <MediaContainer>
|
||||||
playmethod = None [str] either 'DirectPlay', 'DirectStream', 'Transcode'
|
playmethod = None [str] either 'DirectPlay', 'DirectStream', 'Transcode'
|
||||||
|
part = 0 [int] part number if Plex video consists of mult. parts
|
||||||
|
init_done = False Set to True only if run through playback init
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.id = None
|
self.id = None
|
||||||
|
@ -203,8 +205,9 @@ class Playlist_Item(object):
|
||||||
self.guid = None
|
self.guid = None
|
||||||
self.xml = None
|
self.xml = None
|
||||||
self.playmethod = None
|
self.playmethod = None
|
||||||
# Yet to be implemented: handling of a movie with several parts
|
# If Plex video consists of several parts; part number
|
||||||
self.part = 0
|
self.part = 0
|
||||||
|
self.init_done = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""
|
"""
|
||||||
|
@ -550,11 +553,11 @@ def add_item_to_PMS_playlist(playlist, pos, plex_id=None, kodi_item=None):
|
||||||
|
|
||||||
|
|
||||||
def add_item_to_kodi_playlist(playlist, pos, kodi_id=None, kodi_type=None,
|
def add_item_to_kodi_playlist(playlist, pos, kodi_id=None, kodi_type=None,
|
||||||
file=None):
|
file=None, xml_video_element=None):
|
||||||
"""
|
"""
|
||||||
Adds an item to the KODI playlist only. WILL ALSO UPDATE OUR PLAYLISTS
|
Adds an item to the KODI playlist only. WILL ALSO UPDATE OUR PLAYLISTS
|
||||||
|
|
||||||
Returns False if unsuccessful
|
Returns the playlist item that was just added or None
|
||||||
|
|
||||||
file: str!
|
file: str!
|
||||||
"""
|
"""
|
||||||
|
@ -574,17 +577,20 @@ def add_item_to_kodi_playlist(playlist, pos, kodi_id=None, kodi_type=None,
|
||||||
if reply.get('error') is not None:
|
if reply.get('error') is not None:
|
||||||
LOG.error('Could not add item to playlist. Kodi reply. %s', reply)
|
LOG.error('Could not add item to playlist. Kodi reply. %s', reply)
|
||||||
playlist.is_kodi_onadd()
|
playlist.is_kodi_onadd()
|
||||||
return False
|
return
|
||||||
item = playlist_item_from_kodi(
|
if xml_video_element is not None:
|
||||||
{'id': kodi_id, 'type': kodi_type, 'file': file})
|
item = playlist_item_from_xml(playlist, xml_video_element)
|
||||||
if item.plex_id is not None:
|
item.kodi_id = kodi_id
|
||||||
xml = GetPlexMetadata(item.plex_id)
|
item.kodi_type = kodi_type
|
||||||
try:
|
item.file = file
|
||||||
|
elif kodi_id is not None:
|
||||||
|
item = playlist_item_from_kodi(
|
||||||
|
{'id': kodi_id, 'type': kodi_type, 'file': file})
|
||||||
|
if item.plex_id is not None:
|
||||||
|
xml = GetPlexMetadata(item.plex_id)
|
||||||
item.xml = xml[-1]
|
item.xml = xml[-1]
|
||||||
except (TypeError, IndexError):
|
|
||||||
LOG.error('Could not get metadata for playlist item %s', item)
|
|
||||||
playlist.items.insert(pos, item)
|
playlist.items.insert(pos, item)
|
||||||
return True
|
return item
|
||||||
|
|
||||||
|
|
||||||
def move_playlist_item(playlist, before_pos, after_pos):
|
def move_playlist_item(playlist, before_pos, after_pos):
|
||||||
|
@ -706,6 +712,7 @@ def add_listitem_to_Kodi_playlist(playlist, pos, listitem, file,
|
||||||
item.file = file
|
item.file = file
|
||||||
playlist.items.insert(pos, item)
|
playlist.items.insert(pos, item)
|
||||||
LOG.debug('Done inserting for %s', playlist)
|
LOG.debug('Done inserting for %s', playlist)
|
||||||
|
return item
|
||||||
|
|
||||||
|
|
||||||
def remove_from_kodi_playlist(playlist, pos):
|
def remove_from_kodi_playlist(playlist, pos):
|
||||||
|
|
|
@ -58,17 +58,18 @@ def init_playqueues():
|
||||||
LOG.debug('Initialized the Kodi playqueues: %s', PLAYQUEUES)
|
LOG.debug('Initialized the Kodi playqueues: %s', PLAYQUEUES)
|
||||||
|
|
||||||
|
|
||||||
def get_playqueue_from_type(typus):
|
def get_playqueue_from_type(kodi_playlist_type):
|
||||||
"""
|
"""
|
||||||
Returns the playqueue according to the typus ('video', 'audio',
|
Returns the playqueue according to the kodi_playlist_type ('video',
|
||||||
'picture') passed in
|
'audio', 'picture') passed in
|
||||||
"""
|
"""
|
||||||
with LOCK:
|
with LOCK:
|
||||||
for playqueue in PLAYQUEUES:
|
for playqueue in PLAYQUEUES:
|
||||||
if playqueue.type == typus:
|
if playqueue.type == kodi_playlist_type:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ValueError('Wrong playlist type passed in: %s' % typus)
|
raise ValueError('Wrong playlist type passed in: %s',
|
||||||
|
kodi_playlist_type)
|
||||||
return playqueue
|
return playqueue
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue