Rewire Plex Companion startup

This commit is contained in:
tomkat83 2017-01-09 19:56:57 +01:00
parent 5230f73656
commit aac892fed8
4 changed files with 116 additions and 180 deletions

View file

@ -23,6 +23,7 @@ import playbackutils as pbutils
import PlexFunctions import PlexFunctions
import PlexAPI import PlexAPI
from PKC_listitem import convert_PKC_to_listitem from PKC_listitem import convert_PKC_to_listitem
from playqueue import Playqueue
############################################################################### ###############################################################################
@ -121,7 +122,8 @@ def Plex_Node(url, viewOffset, plex_type, playdirectly=False):
window('plex_customplaylist.seektime', value=str(viewOffset)) window('plex_customplaylist.seektime', value=str(viewOffset))
log.info('Set resume point to %s' % str(viewOffset)) log.info('Set resume point to %s' % str(viewOffset))
typus = PlexFunctions.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type] typus = PlexFunctions.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type]
result = pbutils.PlaybackUtils(xml[0],playlist_type=typus).play( playqueue = Playqueue().get_playqueue_from_type(typus)
result = pbutils.PlaybackUtils(xml, playqueue).play(
None, None,
kodi_id='plexnode', kodi_id='plexnode',
plex_lib_UUID=xml.attrib.get('librarySectionUUID')) plex_lib_UUID=xml.attrib.get('librarySectionUUID'))
@ -383,99 +385,6 @@ def BrowseContent(viewname, browse_type="", folderid=""):
xbmcplugin.endOfDirectory(handle=int(sys.argv[1])) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
##### CREATE LISTITEM FROM EMBY METADATA #####
# def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.DownloadUtils()):
def createListItemFromEmbyItem(item,art=None,doUtils=downloadutils.DownloadUtils()):
API = PlexAPI.API(item)
itemid = item['Id']
title = item.get('Name')
li = xbmcgui.ListItem(title)
premieredate = item.get('PremiereDate',"")
if not premieredate: premieredate = item.get('DateCreated',"")
if premieredate:
premieredatelst = premieredate.split('T')[0].split("-")
premieredate = "%s.%s.%s" %(premieredatelst[2],premieredatelst[1],premieredatelst[0])
li.setProperty("plexid",itemid)
allart = art.getAllArtwork(item)
if item["Type"] == "Photo":
#listitem setup for pictures...
img_path = allart.get('Primary')
li.setProperty("path",img_path)
picture = doUtils.downloadUrl("{server}/Items/%s/Images" %itemid)
if picture:
picture = picture[0]
if picture.get("Width") > picture.get("Height"):
li.setArt( {"fanart": img_path}) #add image as fanart for use with skinhelper auto thumb/backgrund creation
li.setInfo('pictures', infoLabels={ "picturepath": img_path, "date": premieredate, "size": picture.get("Size"), "exif:width": str(picture.get("Width")), "exif:height": str(picture.get("Height")), "title": title})
li.setThumbnailImage(img_path)
li.setProperty("plot",API.getOverview())
li.setArt({'icon': 'DefaultPicture.png'})
else:
#normal video items
li.setProperty('IsPlayable', 'true')
path = "%s?id=%s&mode=play" % (sys.argv[0], item.get("Id"))
li.setProperty("path",path)
genre = API.getGenres()
overlay = 0
userdata = API.getUserData()
runtime = item.get("RunTimeTicks",0)/ 10000000.0
seektime = userdata['Resume']
if seektime:
li.setProperty("resumetime", str(seektime))
li.setProperty("totaltime", str(runtime))
played = userdata['Played']
if played: overlay = 7
else: overlay = 6
playcount = userdata['PlayCount']
if playcount is None:
playcount = 0
rating = item.get('CommunityRating')
if not rating: rating = userdata['UserRating']
# Populate the extradata list and artwork
extradata = {
'id': itemid,
'rating': rating,
'year': item.get('ProductionYear'),
'genre': genre,
'playcount': str(playcount),
'title': title,
'plot': API.getOverview(),
'Overlay': str(overlay),
'duration': runtime
}
if premieredate:
extradata["premieredate"] = premieredate
extradata["date"] = premieredate
li.setInfo('video', infoLabels=extradata)
if allart.get('Primary'):
li.setThumbnailImage(allart.get('Primary'))
else: li.setThumbnailImage('DefaultTVShows.png')
li.setArt({'icon': 'DefaultTVShows.png'})
if not allart.get('Background'): #add image as fanart for use with skinhelper auto thumb/backgrund creation
li.setArt( {"fanart": allart.get('Primary') } )
else:
pbutils.PlaybackUtils(item).setArtwork(li)
mediastreams = API.getMediaStreams()
videostreamFound = False
if mediastreams:
for key, value in mediastreams.iteritems():
if key == "video" and value: videostreamFound = True
if value: li.addStreamInfo(key, value[0])
if not videostreamFound:
#just set empty streamdetails to prevent errors in the logs
li.addStreamInfo("video", {'duration': runtime})
return li
##### BROWSE EMBY CHANNELS ##### ##### BROWSE EMBY CHANNELS #####
def BrowseChannels(itemid, folderid=None): def BrowseChannels(itemid, folderid=None):

View file

@ -8,7 +8,8 @@ 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
from utils import window from utils import window
from PlexFunctions import GetPlexMetadata, PLEX_TYPE_PHOTO from PlexFunctions import GetPlexMetadata, PLEX_TYPE_PHOTO, \
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE
from PlexAPI import API from PlexAPI import API
from playqueue import lock from playqueue import lock
@ -54,8 +55,10 @@ class Playback_Starter(Thread):
result.listitem = listitem result.listitem = listitem
else: else:
# Video and Music # Video and Music
playqueue = self.playqueue.get_playqueue_from_type(
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
with lock: with lock:
result = PlaybackUtils(xml[0], self.mgr).play( result = PlaybackUtils(xml, playqueue).play(
plex_id, plex_id,
kodi_id, kodi_id,
xml.attrib.get('librarySectionUUID')) xml.attrib.get('librarySectionUUID'))

View file

@ -14,14 +14,14 @@ from utils import window, settings, tryEncode, tryDecode
import downloadutils import downloadutils
from PlexAPI import API from PlexAPI import API
from PlexFunctions import GetPlexPlaylist, KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE, \ from PlexFunctions import GetPlexPlaylist, KODITYPE_FROM_PLEXTYPE, \
KODITYPE_FROM_PLEXTYPE, PLEX_TYPE_MOVIE PLEX_TYPE_CLIP, PLEX_TYPE_MOVIE
from PKC_listitem import PKC_ListItem as ListItem from PKC_listitem import PKC_ListItem as ListItem
from playlist_func import add_item_to_kodi_playlist, \ from playlist_func import add_item_to_kodi_playlist, \
get_playlist_details_from_xml, add_listitem_to_Kodi_playlist, \ get_playlist_details_from_xml, add_listitem_to_Kodi_playlist, \
add_listitem_to_playlist, remove_from_Kodi_playlist add_listitem_to_playlist, remove_from_Kodi_playlist
from playqueue import lock, Playqueue
from pickler import Playback_Successful from pickler import Playback_Successful
from plexdb_functions import Get_Plex_DB
############################################################################### ###############################################################################
@ -34,17 +34,9 @@ addonName = "PlexKodiConnect"
class PlaybackUtils(): class PlaybackUtils():
def __init__(self, item, callback=None, playlist_type=None): def __init__(self, xml, playqueue):
self.item = item self.xml = xml
self.api = API(item) self.playqueue = playqueue
playlist_type = playlist_type if playlist_type else \
KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[self.api.getType()]
if callback:
self.mgr = callback
self.playqueue = self.mgr.playqueue.get_playqueue_from_type(
playlist_type)
else:
self.playqueue = Playqueue().get_playqueue_from_type(playlist_type)
def play(self, plex_id, kodi_id=None, plex_lib_UUID=None): def play(self, plex_id, kodi_id=None, plex_lib_UUID=None):
""" """
@ -52,8 +44,8 @@ class PlaybackUtils():
to the PMS to the PMS
""" """
log.info("Playbackutils called") log.info("Playbackutils called")
item = self.item item = self.xml[0]
api = self.api api = API(item)
playqueue = self.playqueue playqueue = self.playqueue
xml = None xml = None
result = Playback_Successful() result = Playback_Successful()
@ -179,7 +171,12 @@ class PlaybackUtils():
# -- ADD TRAILERS ################ # -- ADD TRAILERS ################
if trailers: if trailers:
introsPlaylist = self.AddTrailers(xml) for i, item in enumerate(xml):
if i == len(xml) - 1:
# Don't add the main movie itself
break
self.add_trailer(item)
introsPlaylist = True
# -- ADD MAIN ITEM ONLY FOR HOMESCREEN ############## # -- ADD MAIN ITEM ONLY FOR HOMESCREEN ##############
if homeScreen and not seektime and not sizePlaylist: if homeScreen and not seektime and not sizePlaylist:
@ -223,40 +220,14 @@ class PlaybackUtils():
# -- CHECK FOR ADDITIONAL PARTS ################ # -- CHECK FOR ADDITIONAL PARTS ################
if len(item[0]) > 1: if len(item[0]) > 1:
# Only add to the playlist after intros have played self.add_part(item, api, kodi_id, kodi_type)
for counter, part in enumerate(item[0]):
# Never add first part
if counter == 0:
continue
# Set listitem and properties for each additional parts
api.setPartNumber(counter)
additionalListItem = xbmcgui.ListItem()
additionalPlayurl = playutils.getPlayUrl(
partNumber=counter)
log.debug("Adding additional part: %s, url: %s"
% (counter, additionalPlayurl))
api.CreateListItemFromPlexItem(additionalListItem)
api.set_playback_win_props(additionalPlayurl,
additionalListItem)
api.set_listitem_artwork(additionalListItem)
add_listitem_to_playlist(
playqueue,
self.currentPosition,
additionalListItem,
kodi_id=kodi_id,
kodi_type=kodi_type,
plex_id=plex_id,
file=additionalPlayurl)
self.currentPosition += 1
api.setPartNumber(0)
if dummyPlaylist: if dummyPlaylist:
# Added a dummy file to the playlist, # Added a dummy file to the playlist,
# because the first item is going to fail automatically. # because the first item is going to fail automatically.
log.info("Processed as a playlist. First item is skipped.") log.info("Processed as a playlist. First item is skipped.")
# Delete the item that's gonna fail! # Delete the item that's gonna fail!
with lock: del playqueue.items[startPos]
del playqueue.items[startPos]
# Don't attach listitem # Don't attach listitem
return result return result
@ -304,38 +275,89 @@ class PlaybackUtils():
result.listitem = listitem result.listitem = listitem
return result return result
def AddTrailers(self, xml): def play_all(self):
""" """
Adds trailers to a movie, if applicable. Returns True if trailers were Play all items contained in the xml passed in. Called by Plex Companion
added
""" """
# Failure when getting trailers, e.g. when no plex pass log.info("Playbackutils play_all called")
if xml.attrib.get('size') == '1': window('plex_playbackProps', value="true")
return False self.currentPosition = 0
for item in self.xml:
log.debug('item.attrib: %s' % item.attrib)
api = API(item)
if api.getType() == PLEX_TYPE_CLIP:
self.add_trailer(item)
continue
with Get_Plex_DB() as plex_db:
db_item = plex_db.getItem_byId(api.getRatingKey())
try:
add_item_to_kodi_playlist(self.playqueue,
self.currentPosition,
kodi_id=db_item[0],
kodi_type=db_item[4])
self.currentPosition += 1
if len(item[0]) > 1:
self.add_part(item,
api,
db_item[0],
db_item[4])
except TypeError:
# Item not in Kodi DB
self.add_trailer(item)
continue
def add_trailer(self, item):
# Playurl needs to point back so we can get metadata! # Playurl needs to point back so we can get metadata!
path = "plugin://plugin.video.plexkodiconnect/movies/" path = "plugin://plugin.video.plexkodiconnect/movies/"
params = { params = {
'mode': "play", 'mode': "play",
'dbid': 'plextrailer' 'dbid': 'plextrailer'
} }
for counter, intro in enumerate(xml): introAPI = API(item)
# Don't process the last item - it's the original movie listitem = introAPI.CreateListItemFromPlexItem()
if counter == len(xml)-1: params['id'] = introAPI.getRatingKey()
break params['filename'] = introAPI.getKey()
introAPI = API(intro) introPlayurl = path + '?' + urlencode(params)
listitem = introAPI.CreateListItemFromPlexItem() introAPI.set_listitem_artwork(listitem)
params['id'] = introAPI.getRatingKey() # Overwrite the Plex url
params['filename'] = introAPI.getKey() listitem.setPath(introPlayurl)
introPlayurl = path + '?' + urlencode(params) log.info("Adding Plex trailer: %s" % introPlayurl)
introAPI.set_listitem_artwork(listitem) add_listitem_to_Kodi_playlist(
# Overwrite the Plex url self.playqueue,
listitem.setPath(introPlayurl) self.currentPosition,
log.info("Adding Intro: %s" % introPlayurl) listitem,
add_listitem_to_Kodi_playlist( introPlayurl,
xml_video_element=item)
self.currentPosition += 1
def add_part(self, item, api, kodi_id, kodi_type):
"""
Adds an additional part to the playlist
"""
# Only add to the playlist after intros have played
for counter, part in enumerate(item[0]):
# Never add first part
if counter == 0:
continue
# Set listitem and properties for each additional parts
api.setPartNumber(counter)
additionalListItem = xbmcgui.ListItem()
playutils = putils.PlayUtils(item)
additionalPlayurl = playutils.getPlayUrl(
partNumber=counter)
log.debug("Adding additional part: %s, url: %s"
% (counter, additionalPlayurl))
api.CreateListItemFromPlexItem(additionalListItem)
api.set_playback_win_props(additionalPlayurl,
additionalListItem)
api.set_listitem_artwork(additionalListItem)
add_listitem_to_playlist(
self.playqueue, self.playqueue,
self.currentPosition, self.currentPosition,
listitem, additionalListItem,
introPlayurl, kodi_id=kodi_id,
intro) kodi_type=kodi_type,
plex_id=api.getRatingKey(),
file=additionalPlayurl)
self.currentPosition += 1 self.currentPosition += 1
return True api.setPartNumber(0)

View file

@ -8,6 +8,7 @@ from xbmc import sleep, Player, PlayList, PLAYLIST_MUSIC, PLAYLIST_VIDEO
from utils import window, ThreadMethods, ThreadMethodsAdditionalSuspend from utils import window, ThreadMethods, ThreadMethodsAdditionalSuspend
import playlist_func as PL import playlist_func as PL
from PlexFunctions import ConvertPlexToKodiTime from PlexFunctions import ConvertPlexToKodiTime
from playbackutils import PlaybackUtils
############################################################################### ###############################################################################
log = logging.getLogger("PLEX."+__name__) log = logging.getLogger("PLEX."+__name__)
@ -86,7 +87,12 @@ class Playqueue(Thread):
if playqueue_id != playqueue.ID: if playqueue_id != playqueue.ID:
log.debug('Need to fetch new playQueue from the PMS') log.debug('Need to fetch new playQueue from the PMS')
xml = PL.get_PMS_playlist(playqueue, playqueue_id) xml = PL.get_PMS_playlist(playqueue, playqueue_id)
PL.update_playlist_from_PMS(playqueue, playqueue_id, xml=xml) if xml is None:
log.error('Could not get playqueue ID %s' % playqueue_id)
return
playqueue.clear()
PL.get_playlist_details_from_xml(playqueue, xml)
PlaybackUtils(xml, playqueue).play_all()
else: else:
log.debug('Restarting existing playQueue') log.debug('Restarting existing playQueue')
PL.refresh_playlist_from_PMS(playqueue) PL.refresh_playlist_from_PMS(playqueue)
@ -99,21 +105,17 @@ class Playqueue(Thread):
if item.ID == playqueue.selectedItemID: if item.ID == playqueue.selectedItemID:
break break
else: else:
startpos = None startpos = 0
# Start playback. Player does not return in time # Start playback. Player does not return in time
if startpos: log.debug('Playqueues after Plex Companion update are now: %s'
log.debug('Start position Plex Companion playback: %s' % self.playqueues)
% startpos) log.debug('Start position Plex Companion playback: %s'
thread = Thread(target=Player().play, % startpos)
args=(playqueue.kodi_pl, thread = Thread(target=Player().play,
None, args=(playqueue.kodi_pl,
False, None,
startpos)) False,
else: startpos))
log.debug('Start Plex Companion playback from beginning')
thread = Thread(target=Player().play,
args=(playqueue.kodi_pl,))
log.debug('Playqueues are: %s' % self.playqueues)
thread.setDaemon(True) thread.setDaemon(True)
thread.start() thread.start()