mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-25 10:16:11 +00:00
simplify channel browse code
add experimental support for live tv channels and recordings (without pvr)
This commit is contained in:
parent
ad6a4b2dd5
commit
7cf615f671
4 changed files with 73 additions and 81 deletions
|
@ -506,7 +506,7 @@ class Artwork():
|
||||||
|
|
||||||
id = item['Id']
|
id = item['Id']
|
||||||
artworks = item['ImageTags']
|
artworks = item['ImageTags']
|
||||||
backdrops = item['BackdropImageTags']
|
backdrops = item.get('BackdropImageTags',[])
|
||||||
|
|
||||||
maxHeight = 10000
|
maxHeight = 10000
|
||||||
maxWidth = 10000
|
maxWidth = 10000
|
||||||
|
|
|
@ -76,7 +76,11 @@ def doMainListing():
|
||||||
addDirectoryItem(label, path)
|
addDirectoryItem(label, path)
|
||||||
elif path and not xbmc.getCondVisibility("Window.IsActive(VideoLibrary) | Window.IsActive(Pictures) | Window.IsActive(MusicLibrary)"):
|
elif path and not xbmc.getCondVisibility("Window.IsActive(VideoLibrary) | Window.IsActive(Pictures) | Window.IsActive(MusicLibrary)"):
|
||||||
addDirectoryItem(label, path)
|
addDirectoryItem(label, path)
|
||||||
|
|
||||||
|
#experimental live tv nodes
|
||||||
|
addDirectoryItem("Live Tv Channels (experimental)", "plugin://plugin.video.emby/?mode=browsecontent&type=tvchannels&folderid=root")
|
||||||
|
addDirectoryItem("Live Tv Recordings (experimental)", "plugin://plugin.video.emby/?mode=browsecontent&type=recordings&folderid=root")
|
||||||
|
|
||||||
# some extra entries for settings and stuff. TODO --> localize the labels
|
# some extra entries for settings and stuff. TODO --> localize the labels
|
||||||
addDirectoryItem("Network credentials", "plugin://plugin.video.emby/?mode=passwords")
|
addDirectoryItem("Network credentials", "plugin://plugin.video.emby/?mode=passwords")
|
||||||
addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
|
addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
|
||||||
|
@ -395,10 +399,12 @@ def refreshPlaylist():
|
||||||
time=1000,
|
time=1000,
|
||||||
sound=False)
|
sound=False)
|
||||||
|
|
||||||
##### BROWSE EMBY HOMEVIDEOS AND PICTURES #####
|
##### BROWSE EMBY NODES DIRECTLY #####
|
||||||
def BrowseContent(viewname, type="", folderid=None, filter=""):
|
def BrowseContent(viewname, type="", folderid=None, filter=""):
|
||||||
|
|
||||||
emby = embyserver.Read_EmbyServer()
|
emby = embyserver.Read_EmbyServer()
|
||||||
|
art = artwork.Artwork()
|
||||||
|
doUtils = downloadutils.DownloadUtils()
|
||||||
utils.logMsg("BrowseHomeVideos","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname, type, folderid, filter))
|
utils.logMsg("BrowseHomeVideos","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname, type, folderid, filter))
|
||||||
xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname)
|
xbmcplugin.setPluginCategory(int(sys.argv[1]), viewname)
|
||||||
#get views for root level
|
#get views for root level
|
||||||
|
@ -421,7 +427,11 @@ def BrowseContent(viewname, type="", folderid=None, filter=""):
|
||||||
itemtype = ""
|
itemtype = ""
|
||||||
|
|
||||||
#get the actual listing
|
#get the actual listing
|
||||||
if filter == "recent":
|
if type == "recordings":
|
||||||
|
listing = emby.getTvRecordings(folderid)
|
||||||
|
elif type == "tvchannels":
|
||||||
|
listing = emby.getTvChannels()
|
||||||
|
elif filter == "recent":
|
||||||
listing = emby.getFilteredSection("", itemtype=itemtype.split(",")[0], sortby="DateCreated", recursive=True, limit=25, sortorder="Descending")
|
listing = emby.getFilteredSection("", itemtype=itemtype.split(",")[0], sortby="DateCreated", recursive=True, limit=25, sortorder="Descending")
|
||||||
elif filter == "random":
|
elif filter == "random":
|
||||||
listing = emby.getFilteredSection("", itemtype=itemtype.split(",")[0], sortby="Random", recursive=True, limit=150, sortorder="Descending")
|
listing = emby.getFilteredSection("", itemtype=itemtype.split(",")[0], sortby="Random", recursive=True, limit=150, sortorder="Descending")
|
||||||
|
@ -435,7 +445,7 @@ def BrowseContent(viewname, type="", folderid=None, filter=""):
|
||||||
#process the listing
|
#process the listing
|
||||||
if listing:
|
if listing:
|
||||||
for item in listing.get("Items"):
|
for item in listing.get("Items"):
|
||||||
li = createListItemFromEmbyItem(item)
|
li = createListItemFromEmbyItem(item,art,doUtils)
|
||||||
if item.get("IsFolder") == True:
|
if item.get("IsFolder") == True:
|
||||||
#for folders we add an additional browse request, passing the folderId
|
#for folders we add an additional browse request, passing the folderId
|
||||||
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0], viewname, type, item.get("Id"))
|
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0], viewname, type, item.get("Id"))
|
||||||
|
@ -455,10 +465,8 @@ def BrowseContent(viewname, type="", folderid=None, filter=""):
|
||||||
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)
|
xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_VIDEO_RUNTIME)
|
||||||
|
|
||||||
##### CREATE LISTITEM FROM EMBY METADATA #####
|
##### CREATE LISTITEM FROM EMBY METADATA #####
|
||||||
def createListItemFromEmbyItem(item):
|
def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.DownloadUtils()):
|
||||||
API = api.API(item)
|
API = api.API(item)
|
||||||
art = artwork.Artwork()
|
|
||||||
doUtils = downloadutils.DownloadUtils()
|
|
||||||
itemid = item['Id']
|
itemid = item['Id']
|
||||||
|
|
||||||
title = item.get('Name')
|
title = item.get('Name')
|
||||||
|
@ -495,10 +503,11 @@ def createListItemFromEmbyItem(item):
|
||||||
genre = API.getGenres()
|
genre = API.getGenres()
|
||||||
overlay = 0
|
overlay = 0
|
||||||
userdata = API.getUserData()
|
userdata = API.getUserData()
|
||||||
|
runtime = item.get("RunTimeTicks",0)/ 10000000.0
|
||||||
seektime = userdata['Resume']
|
seektime = userdata['Resume']
|
||||||
if seektime:
|
if seektime:
|
||||||
li.setProperty("resumetime", seektime)
|
li.setProperty("resumetime", seektime)
|
||||||
li.setProperty("totaltime", item.get("RunTimeTicks")/ 10000000.0)
|
li.setProperty("totaltime", str(runtime))
|
||||||
|
|
||||||
played = userdata['Played']
|
played = userdata['Played']
|
||||||
if played: overlay = 7
|
if played: overlay = 7
|
||||||
|
@ -515,26 +524,35 @@ def createListItemFromEmbyItem(item):
|
||||||
'id': itemid,
|
'id': itemid,
|
||||||
'rating': rating,
|
'rating': rating,
|
||||||
'year': item.get('ProductionYear'),
|
'year': item.get('ProductionYear'),
|
||||||
'premieredate': premieredate,
|
|
||||||
'date': premieredate,
|
|
||||||
'genre': genre,
|
'genre': genre,
|
||||||
'playcount': str(playcount),
|
'playcount': str(playcount),
|
||||||
'title': title,
|
'title': title,
|
||||||
'plot': API.getOverview(),
|
'plot': API.getOverview(),
|
||||||
'Overlay': str(overlay),
|
'Overlay': str(overlay),
|
||||||
|
'duration': runtime
|
||||||
}
|
}
|
||||||
|
if premieredate:
|
||||||
|
extradata["premieredate"] = premieredate
|
||||||
|
extradata["date"] = premieredate
|
||||||
li.setInfo('video', infoLabels=extradata)
|
li.setInfo('video', infoLabels=extradata)
|
||||||
li.setThumbnailImage(allart.get('Primary'))
|
if allart.get('Primary'):
|
||||||
|
li.setThumbnailImage(allart.get('Primary'))
|
||||||
|
else: li.setThumbnailImage('DefaultTVShows.png')
|
||||||
li.setIconImage('DefaultTVShows.png')
|
li.setIconImage('DefaultTVShows.png')
|
||||||
if not allart.get('Background'): #add image as fanart for use with skinhelper auto thumb/backgrund creation
|
if not allart.get('Background'): #add image as fanart for use with skinhelper auto thumb/backgrund creation
|
||||||
li.setArt( {"fanart": allart.get('Primary') } )
|
li.setArt( {"fanart": allart.get('Primary') } )
|
||||||
else:
|
else:
|
||||||
pbutils.PlaybackUtils(item).setArtwork(li)
|
pbutils.PlaybackUtils(item).setArtwork(li)
|
||||||
|
|
||||||
mediastreams = API.getMediaStreams()
|
mediastreams = API.getMediaStreams()
|
||||||
|
videostreamFound = False
|
||||||
if mediastreams:
|
if mediastreams:
|
||||||
for key, value in mediastreams.iteritems():
|
for key, value in mediastreams.iteritems():
|
||||||
|
if key == "video" and value: videostreamFound = True
|
||||||
if value: li.addStreamInfo(key, value[0])
|
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
|
return li
|
||||||
|
|
||||||
|
@ -558,84 +576,20 @@ def BrowseChannels(itemid, folderid=None):
|
||||||
url = "{server}/emby/Channels/%s/Items?UserId={UserId}&format=json" % itemid
|
url = "{server}/emby/Channels/%s/Items?UserId={UserId}&format=json" % itemid
|
||||||
|
|
||||||
result = doUtils.downloadUrl(url)
|
result = doUtils.downloadUrl(url)
|
||||||
try:
|
if result and result.get("Items"):
|
||||||
channels = result['Items']
|
for item in result.get("Items"):
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
for item in channels:
|
|
||||||
|
|
||||||
API = api.API(item)
|
|
||||||
itemid = item['Id']
|
itemid = item['Id']
|
||||||
itemtype = item['Type']
|
itemtype = item['Type']
|
||||||
title = item.get('Name', "Missing Title")
|
li = createListItemFromEmbyItem(item,art,doUtils)
|
||||||
li = xbmcgui.ListItem(title)
|
|
||||||
|
|
||||||
if itemtype == "ChannelFolderItem":
|
if itemtype == "ChannelFolderItem":
|
||||||
isFolder = True
|
isFolder = True
|
||||||
else:
|
else:
|
||||||
isFolder = False
|
isFolder = False
|
||||||
|
|
||||||
channelId = item.get('ChannelId', "")
|
channelId = item.get('ChannelId', "")
|
||||||
channelName = item.get('ChannelName', "")
|
channelName = item.get('ChannelName', "")
|
||||||
|
|
||||||
premieredate = API.getPremiereDate()
|
|
||||||
# Process Genres
|
|
||||||
genre = API.getGenres()
|
|
||||||
# Process UserData
|
|
||||||
overlay = 0
|
|
||||||
|
|
||||||
userdata = API.getUserData()
|
|
||||||
seektime = userdata['Resume']
|
|
||||||
played = userdata['Played']
|
|
||||||
if played:
|
|
||||||
overlay = 7
|
|
||||||
else:
|
|
||||||
overlay = 6
|
|
||||||
|
|
||||||
favorite = userdata['Favorite']
|
|
||||||
if favorite:
|
|
||||||
overlay = 5
|
|
||||||
|
|
||||||
playcount = userdata['PlayCount']
|
|
||||||
if playcount is None:
|
|
||||||
playcount = 0
|
|
||||||
|
|
||||||
# Populate the details list
|
|
||||||
details = {
|
|
||||||
|
|
||||||
'title': title,
|
|
||||||
'channelname': channelName,
|
|
||||||
'plot': API.getOverview(),
|
|
||||||
'Overlay': str(overlay),
|
|
||||||
'playcount': str(playcount)
|
|
||||||
}
|
|
||||||
|
|
||||||
if itemtype == "ChannelVideoItem":
|
|
||||||
xbmcplugin.setContent(_addon_id, 'movies')
|
|
||||||
elif itemtype == "ChannelAudioItem":
|
|
||||||
xbmcplugin.setContent(_addon_id, 'songs')
|
|
||||||
|
|
||||||
# Populate the extradata list and artwork
|
|
||||||
pbutils.PlaybackUtils(item).setArtwork(li)
|
|
||||||
extradata = {
|
|
||||||
|
|
||||||
'id': itemid,
|
|
||||||
'rating': item.get('CommunityRating'),
|
|
||||||
'year': item.get('ProductionYear'),
|
|
||||||
'premieredate': premieredate,
|
|
||||||
'genre': genre,
|
|
||||||
'playcount': str(playcount),
|
|
||||||
'itemtype': itemtype
|
|
||||||
}
|
|
||||||
li.setInfo('video', infoLabels=extradata)
|
|
||||||
li.setThumbnailImage(art.getAllArtwork(item)['Primary'])
|
|
||||||
li.setIconImage('DefaultTVShows.png')
|
|
||||||
|
|
||||||
if itemtype == "Channel":
|
if itemtype == "Channel":
|
||||||
path = "%s?id=%s&mode=channels" % (_addon_url, itemid)
|
path = "%s?id=%s&mode=channels" % (_addon_url, itemid)
|
||||||
xbmcplugin.addDirectoryItem(handle=_addon_id, url=path, listitem=li, isFolder=True)
|
xbmcplugin.addDirectoryItem(handle=_addon_id, url=path, listitem=li, isFolder=True)
|
||||||
|
|
||||||
elif isFolder:
|
elif isFolder:
|
||||||
path = "%s?id=%s&mode=channelsfolder&folderid=%s" % (_addon_url, channelId, itemid)
|
path = "%s?id=%s&mode=channelsfolder&folderid=%s" % (_addon_url, channelId, itemid)
|
||||||
xbmcplugin.addDirectoryItem(handle=_addon_id, url=path, listitem=li, isFolder=True)
|
xbmcplugin.addDirectoryItem(handle=_addon_id, url=path, listitem=li, isFolder=True)
|
||||||
|
|
|
@ -34,9 +34,17 @@ class PlayUtils():
|
||||||
def getPlayUrl(self):
|
def getPlayUrl(self):
|
||||||
|
|
||||||
item = self.item
|
item = self.item
|
||||||
|
print "playutilks"
|
||||||
|
print item
|
||||||
playurl = None
|
playurl = None
|
||||||
|
|
||||||
|
if item.get('Type') in ["Recording","TvChannel"] and item.get('MediaSources') and item['MediaSources'][0]['Protocol'] == "Http":
|
||||||
|
#Is this the right way to play a Live TV or recordings ?
|
||||||
|
self.logMsg("File protocol is http (livetv).", 1)
|
||||||
|
playurl = "%s/emby/Videos/%s/live.m3u8?static=true" % (self.server, item['Id'])
|
||||||
|
utils.window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
||||||
|
|
||||||
if item.get('MediaSources') and item['MediaSources'][0]['Protocol'] == "Http":
|
elif item.get('MediaSources') and item['MediaSources'][0]['Protocol'] == "Http":
|
||||||
# Only play as http
|
# Only play as http
|
||||||
self.logMsg("File protocol is http.", 1)
|
self.logMsg("File protocol is http.", 1)
|
||||||
playurl = self.httpPlay()
|
playurl = self.httpPlay()
|
||||||
|
|
|
@ -149,6 +149,36 @@ class Read_EmbyServer():
|
||||||
}
|
}
|
||||||
return doUtils.downloadUrl(url, parameters=params)
|
return doUtils.downloadUrl(url, parameters=params)
|
||||||
|
|
||||||
|
def getTvChannels(self):
|
||||||
|
doUtils = self.doUtils
|
||||||
|
url = "{server}/emby/LiveTv/Channels/?userid={UserId}&format=json"
|
||||||
|
params = {
|
||||||
|
|
||||||
|
'EnableImages': True,
|
||||||
|
'Fields': ( "Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,"
|
||||||
|
"CommunityRating,OfficialRating,CumulativeRunTimeTicks,"
|
||||||
|
"Metascore,AirTime,DateCreated,MediaStreams,People,Overview,"
|
||||||
|
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
|
||||||
|
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers")
|
||||||
|
}
|
||||||
|
return doUtils.downloadUrl(url, parameters=params)
|
||||||
|
|
||||||
|
def getTvRecordings(self, groupid):
|
||||||
|
doUtils = self.doUtils
|
||||||
|
url = "{server}/emby/LiveTv/Recordings/?userid={UserId}&format=json"
|
||||||
|
if groupid == "root": groupid = ""
|
||||||
|
params = {
|
||||||
|
|
||||||
|
'GroupId': groupid,
|
||||||
|
'EnableImages': True,
|
||||||
|
'Fields': ( "Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,"
|
||||||
|
"CommunityRating,OfficialRating,CumulativeRunTimeTicks,"
|
||||||
|
"Metascore,AirTime,DateCreated,MediaStreams,People,Overview,"
|
||||||
|
"CriticRating,CriticRatingSummary,Etag,ShortOverview,ProductionLocations,"
|
||||||
|
"Tags,ProviderIds,ParentId,RemoteTrailers,SpecialEpisodeNumbers")
|
||||||
|
}
|
||||||
|
return doUtils.downloadUrl(url, parameters=params)
|
||||||
|
|
||||||
def getSection(self, parentid, itemtype=None, sortby="SortName", basic=False, dialog=None):
|
def getSection(self, parentid, itemtype=None, sortby="SortName", basic=False, dialog=None):
|
||||||
|
|
||||||
doUtils = self.doUtils
|
doUtils = self.doUtils
|
||||||
|
|
Loading…
Reference in a new issue