fix for the merge that didn't follow

Media path fix, and clean up of writeKodiVideoDB. Fix for library sync
for deletes.
This commit is contained in:
angelblue05 2015-07-18 03:08:05 -05:00
parent 3589c4b05d
commit 0c54257de6
4 changed files with 1281 additions and 1300 deletions

View file

@ -1,3 +1,4 @@
# -- coding: utf-8 --
# API.py
# This class helps translate more complex cases from the MediaBrowser API to the XBMC API
@ -11,143 +12,158 @@ class API():
def getPeople(self, item):
# Process People
director=[]
writer=[]
cast=[]
people = item.get("People")
if(people != None):
director = []
writer = []
cast = []
try:
people = item['People']
except: pass
else:
for person in people:
if(person.get("Type") == "Director"):
director.append(person.get("Name"))
if(person.get("Type") == "Writing"):
writer.append(person.get("Name"))
if(person.get("Type") == "Writer"):
writer.append(person.get("Name"))
if(person.get("Type") == "Actor"):
Name = person.get("Name")
Role = person.get("Role")
if Role == None:
Role = ''
type = person['Type']
Name = person['Name']
if "Director" in type:
director.append(Name)
elif "Writing" in type:
writer.append(Name)
elif "Writer" in type:
writer.append(Name)
elif "Actor" in type:
cast.append(Name)
return {'Director' : director,
'Writer' : writer,
'Cast' : cast
return {
'Director': director,
'Writer': writer,
'Cast': cast
}
def getTimeInfo(self, item):
resumeTime = ''
userData = item.get("UserData")
PlaybackPositionTicks = '100'
if userData.get("PlaybackPositionTicks") != None:
PlaybackPositionTicks = str(userData.get("PlaybackPositionTicks"))
reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000
resumeTime = reasonableTicks / 10000
# Runtime and Resume point
tempRuntime = 0
runtime = 0
resume = 0
try:
tempDuration = str(int(item.get("RunTimeTicks", "0"))/(10000000*60))
except TypeError:
try:
tempDuration = str(int(item.get("CumulativeRunTimeTicks"))/(10000000*60))
except TypeError:
tempDuration = "0"
cappedPercentage = None
resume=0
percentage=0
if (resumeTime != "" and int(resumeTime) > 0):
duration = float(tempDuration)
if(duration > 0):
resume = float(resumeTime) / 60
percentage = int((resume / duration) * 100.0)
return {'Duration' : tempDuration,
'TotalTime' : tempDuration,
'Percent' : str(percentage),
'ResumeTime' : str(resume)
try: # Get resume point
userdata = item['UserData']
playbackPosition = userdata['PlaybackPositionTicks']
resume = playbackPosition / 10000000.0
except: pass
try: # Get total runtime
tempRuntime = item['RunTimeTicks']
except:
try: tempRuntime = item['CumulativeRunTimeTicks']
except: pass
finally:
runtime = tempRuntime / 10000000.0
return {
'ResumeTime': resume,
'TotalTime': runtime
}
def getStudios(self, item):
# Process Studio
studios = []
if item.get("SeriesStudio") != None and item.get("SeriesStudio") != '':
studios.append(item.get("SeriesStudio"))
else:
if(item.get("Studios") != []):
for studio_string in item.get("Studios"):
temp=studio_string.get("Name")
studios.append(temp)
try:
studio = item['SeriesStudio']
studios.append(studio)
except:
try:
studioArray = item['Studios']
for studio in studioArray:
studios.append(studio['Name'])
except: pass
return studios
def getMediaStreams(self, item, mediaSources=False):
# Process MediaStreams
channels = ''
videocodec = ''
audiocodec = ''
audiolanguage = ''
subtitlelanguage = ''
height = ''
width = ''
aspectratio = '1:1'
aspectfloat = 1.85
Video3DFormat = ''
if mediaSources == True:
mediaSources = item.get("MediaSources")
if(mediaSources != None):
MediaStreams = mediaSources[0].get("MediaStreams")
def getGenre(self,item):
genre = ""
genres = item.get("Genres")
if genres != None and genres != []:
for genre_string in genres:
if genre == "": #Just take the first genre
genre = genre_string
else:
genre = genre + " / " + genre_string
elif item.get("SeriesGenres") != None and item.get("SeriesGenres") != '':
genres = item.get("SeriesGenres")
if genres != None and genres != []:
for genre_string in genres:
if genre == "": #Just take the first genre
genre = genre_string
else:
genre = genre + " / " + genre_string
return genre
def getMediaStreams(self, item, mediaSources = False):
videotracks = [] # Height, Width, Codec, AspectRatio, AspectFloat, 3D
audiotracks = [] # Codec, Channels, language
subtitlelanguages = [] # Language
if mediaSources:
try:
MediaStreams = item['MediaSources'][0]['MediaStreams']
except:
MediaStreams = None
else:
MediaStreams = item.get("MediaStreams")
if(MediaStreams != None):
#mediaStreams = MediaStreams[0].get("MediaStreams")
if(MediaStreams != None):
MediaStreams = item.get('MediaStreams')
if MediaStreams:
# Sort through the Video, Audio, Subtitle tracks
for mediaStream in MediaStreams:
if(mediaStream.get("Type") == "Video"):
videocodec = mediaStream.get("Codec")
if mediaStream.get("Height"):
height = int(mediaStream.get("Height"))
if mediaStream.get("Width"):
width = int(mediaStream.get("Width"))
aspectratio = mediaStream.get("AspectRatio")
Video3DFormat = item.get("Video3DFormat")
if aspectratio != None and len(aspectratio) >= 3:
type = mediaStream.get("Type", "")
if "Video" in type:
videotrack = {}
videotrack['videocodec'] = mediaStream.get('Codec')
videotrack['height'] = mediaStream.get('Height')
videotrack['width'] = mediaStream.get('Width')
videotrack['aspectratio'] = mediaStream.get('AspectRatio')
videotrack['Video3DFormat'] = item.get('Video3DFormat')
if len(videotrack['aspectratio']) >= 3:
try:
aspectwidth,aspectheight = aspectratio.split(':')
aspectfloat = float(aspectwidth) / float(aspectheight)
aspectwidth, aspectheight = aspectratio.split(':')
videotrack['aspectfloat'] = float(aspectwidth) / float(aspectheight)
except:
aspectfloat = 1.85
if(mediaStream.get("Type") == "Audio"):
isdefault = mediaStream.get("IsDefault") == "true"
if audiocodec == '':
audiocodec = mediaStream.get("Codec")
if channels == '':
channels = mediaStream.get("Channels")
if audiolanguage == '':
audiolanguage = mediaStream.get("Language")
# only overwrite if default
if isdefault:
audiocodec = mediaStream.get("Codec")
channels = mediaStream.get("Channels")
audiolanguage = mediaStream.get("Language")
if(mediaStream.get("Type") == "Subtitle"):
isdefault = mediaStream.get("IsDefault") == "true"
if subtitlelanguage == '':
subtitlelanguage = mediaStream.get("Language")
# only overwrite if default
if isdefault:
subtitlelanguage = mediaStream.get("Language")
videotrack['aspectfloat'] = 1.85
videotracks.append(videotrack)
elif "Audio" in type:
audiotrack = {}
audiotrack['audiocodec'] = mediaStream.get('Codec')
audiotrack['channels'] = mediaStream.get('Channels')
audiotrack['audiolanguage'] = mediaStream.get('Language')
audiotracks.append(audiotrack)
return {'channels' : str(channels),
'videocodec' : videocodec,
'audiocodec' : audiocodec,
'audiolanguage' : audiolanguage,
'subtitlelanguage' : subtitlelanguage,
'height' : height,
'width' : width,
'aspectratio' : aspectfloat,
'3dformat' : Video3DFormat
elif "Subtitle" in type:
try:
subtitlelanguages.append(mediaStream['Language'])
except:
subtitlelanguages.append("Unknown")
return {
'videocodec' : videotracks,
'audiocodec' : audiotracks,
'subtitlelanguage' : subtitlelanguages
}
def getChecksum(self, item):
# use the etags checksum for this if available
# AND the userdata
@ -169,75 +185,43 @@ class API():
return checksum
def getUserData(self, item):
userData = item.get("UserData")
resumeTime = 0
if(userData != None):
if userData.get("Played") != True:
watched="True"
# Default
favorite = False
playcount = None
lastPlayedDate = None
userKey = ""
try:
userdata = item['UserData']
except: # No userdata found.
pass
else:
watched="False"
if userData.get("IsFavorite") == True:
favorite=True
else:
favorite=False
if(userData.get("Played") == True):
# Cover the Emby scenario where item is played but playcount is 0.
playcount = userData.get('PlayCount')
favorite = userdata['IsFavorite']
userKey = userdata.get('Key', "")
watched = userdata['Played']
if watched:
# Playcount is tied to the watch status
playcount = userdata['PlayCount']
if playcount == 0:
playcount = 1
else:
playcount="0"
if userData.get('UnplayedItemCount') != None:
UnplayedItemCount = userData.get('UnplayedItemCount')
else:
UnplayedItemCount = "0"
if userData.get('LastPlayedDate') != None:
#TODO--> is there some other way to do this ?
datestring = userData.get('LastPlayedDate').split('T')[0]
timestring = userData.get('LastPlayedDate').split('T')[1]
timestring = timestring.split('.')[0]
LastPlayedDate = datestring + " " + timestring
else:
LastPlayedDate = None
if userData.get('PlaybackPositionTicks') != None:
PlaybackPositionTicks = userData.get('PlaybackPositionTicks')
else:
PlaybackPositionTicks = ''
userKey = userData.get("Key", "")
return {'Watched' : watched,
'Favorite' : favorite,
playcount = None
lastPlayedDate = userdata.get('LastPlayedDate', None)
if lastPlayedDate:
lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ")
return {
'Favorite': favorite,
'PlayCount': playcount,
'LastPlayedDate': LastPlayedDate,
'UnplayedItemCount' : UnplayedItemCount,
'PlaybackPositionTicks' : str(PlaybackPositionTicks),
'Key' : userKey
'LastPlayedDate': lastPlayedDate,
'Key': userKey
}
def getGenre(self,item):
genre = ""
genres = item.get("Genres")
if genres != None and genres != []:
for genre_string in genres:
if genre == "": #Just take the first genre
genre = genre_string
else:
genre = genre + " / " + genre_string
elif item.get("SeriesGenres") != None and item.get("SeriesGenres") != '':
genres = item.get("SeriesGenres")
if genres != None and genres != []:
for genre_string in genres:
if genre == "": #Just take the first genre
genre = genre_string
else:
genre = genre + " / " + genre_string
return genre
def getName(self, item):
Temp = item.get("Name")
if Temp == None:
Temp = ""
Name=Temp.encode('utf-8')
return Name
def getRecursiveItemCount(self, item):
if item.get("RecursiveItemCount") != None:
@ -245,33 +229,18 @@ class API():
else:
return "0"
def getSeriesName(self, item):
Temp = item.get("SeriesName")
if Temp == None:
Temp = ""
Name=Temp.encode('utf-8')
return Name
def getOverview(self, item):
Temp = item.get("Overview")
if Temp == None:
Temp=''
Overview1=Temp.encode('utf-8')
Overview=str(Overview1)
Overview=Overview.replace("\"", "\'")
Overview=Overview.replace("\n", " ")
Overview=Overview.replace("\r", " ")
return Overview
def getPremiereDate(self, item):
if(item.get("PremiereDate") != None):
premieredatelist = (item.get("PremiereDate")).split("T")
premieredate = premieredatelist[0]
else:
premieredate = ""
Temp = premieredate
premieredate = Temp.encode('utf-8')
return premieredate
overview = ""
try:
overview = item['Overview']
overview = overview.replace("\"", "\'")
overview = overview.replace("\n", " ")
overview = overview.replace("\r", " ")
except: pass
return overview
def getTVInfo(self, item, userData):
TotalSeasons = 0 if item.get("ChildCount")==None else item.get("ChildCount")
@ -306,15 +275,105 @@ class API():
'Episode' : tempEpisode,
'SeriesName' : SeriesName
}
def getDateCreated(self, item):
tempDate = item.get("DateCreated")
if tempDate != None:
tempDate = tempDate.split("T")[0]
date = tempDate.split("-")
tempDate = date[2] + "." + date[1] + "." +date[0]
else:
tempDate = "01.01.2000"
return tempDate
dateadded = None
try:
dateadded = item['DateCreated']
dateadded = dateadded.split('.')[0].replace('T', " ")
except: pass
return dateadded
def getPremiereDate(self, item):
premiere = None
try:
premiere = item['PremiereDate']
premiere = premiere.split('.')[0].replace('T', " ")
except: pass
return premiere
def getTagline(self, item):
tagline = None
try:
tagline = item['Taglines'][0]
except: pass
return tagline
def getProvider(self, item, providername):
# Provider Name: imdb or tvdb
provider = None
try:
if "imdb" in providername:
provider = item['ProviderIds']['Imdb']
elif "tvdb" in providername:
provider = item['ProviderIds']['Tvdb']
except: pass
return provider
def getCountry(self, item):
country = None
try:
country = item['ProductionLocations'][0]
except: pass
return country
def getArtworks(self, data, type, mediaType = "", index = "0", getAll = False):
"""
Get all artwork, it will return an empty string
for the artwork type not found.
Index only matters when getAll is False.
mediaType: movie, boxset, tvshow, episode, season
Artwork type: Primary, Banner, Logo, Art, Thumb,
Disc Backdrop
"""
id = data['Id']
maxHeight = 10000
maxWidth = 10000
imageTag = "e3ab56fe27d389446754d0fb04910a34" # Place holder tag
if getAll:
allartworks = {
'Primary': "",
'Banner': "",
'Logo': "",
'Art': "",
'Thumb': "",
'Disc': "",
'Backdrop': ""
}
for keytype in allartworks:
type = keytype
url = ""
allartworks[keytype] = url
return allartworks
else: pass
def getArtwork(self, data, type, mediaType = "", index = "0", userParentInfo = False):
@ -417,6 +476,14 @@ class API():
return artwork
def imageUrl(self, id, type, index, width, height):
WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser')
server = WINDOW.getProperty('server%s' % username)
# For people image - actors, directors, writers
return "%s/mediabrowser/Items/%s/Images/%s?MaxWidth=%s&MaxHeight=%s&Index=%s" % (server, id, type, width, height, index)
def getUserArtwork(self, data, type, index = "0"):
# Load user information set by UserClient

View file

@ -659,61 +659,67 @@ class LibrarySync(threading.Thread):
# Delete from Kodi before Emby
# To be able to get mediaType
doUtils = DownloadUtils()
video = []
video = {}
music = []
itemIds = ','.join(itemList)
url = "{server}/mediabrowser/Users/{UserId}/Items?Ids=%s&format=json" % itemIds
result = doUtils.downloadUrl(url)
# Database connection to myVideosXX.db
connectionvideo = utils.KodiSQL()
cursorvideo = connectionvideo.cursor()
# Database connection to myMusicXX.db
connectionmusic = utils.KodiSQL("music")
cursormusic = connectionmusic.cursor()
if result is "":
# Websocket feedback
self.logMsg("Item %s is removed." % itemIds)
return
for item in result[u'Items']:
for item in itemList:
# Sort by type for database deletion
itemId = item["Id"]
mediaType = item["MediaType"]
if "Video" in mediaType:
video.append(itemId)
elif "Audio" in mediaType:
music.append(itemId)
try: # Search video database
self.logMsg("Check video database.", 1)
cursorvideo.execute("SELECT media_type FROM emby WHERE emby_id = ?", (item,))
mediatype = cursorvideo.fetchone()[0]
video[item] = mediatype
#video.append(itemtype)
except:
self.logMsg("Check music database.", 1)
try: # Search music database
cursormusic.execute("SELECT media_type FROM emby WHERE emby_id = ?", (item,))
cursormusic.fetchone()[0]
music.append(item)
except: self.logMsg("Item %s is not found in Kodi database." % item, 1)
if len(video) > 0:
#Process video library
connection = utils.KodiSQL("video")
cursor = connection.cursor()
connection = connectionvideo
cursor = cursorvideo
# Process video library
for item in video:
type = ReadKodiDB().getTypeByEmbyId(item, connection, cursor)
self.logMsg("Type: %s" % type)
self.logMsg("Message: Doing LibraryChanged: Items Removed: Calling deleteItemFromKodiLibrary: %s" % item, 0)
type = video[item]
self.logMsg("Doing LibraryChanged: Items Removed: Calling deleteItemFromKodiLibrary: %s" % item, 1)
if "episode" in type:
# Get the TV Show Id for reference later
showId = ReadKodiDB().getShowIdByEmbyId(item, connection, cursor)
self.logMsg("ShowId: %s" % showId, 0)
self.logMsg("ShowId: %s" % showId, 1)
WriteKodiVideoDB().deleteItemFromKodiLibrary(item, connection, cursor)
# Verification
if "episode" in type:
showTotalCount = ReadKodiDB().getShowTotalCount(showId, connection, cursor)
self.logMsg("ShowTotalCount: %s" % showTotalCount, 0)
self.logMsg("ShowTotalCount: %s" % showTotalCount, 1)
# If there are no episodes left
if showTotalCount == 0 or showTotalCount == None:
# Delete show
embyId = ReadKodiDB().getEmbyIdByKodiId(showId, "tvshow", connection, cursor)
self.logMsg("Message: Doing LibraryChanged: Deleting show: %s" % embyId, 0)
self.logMsg("Message: Doing LibraryChanged: Deleting show: %s" % embyId, 1)
WriteKodiVideoDB().deleteItemFromKodiLibrary(embyId, connection, cursor)
connection.commit()
cursor.close()
# Close connection
cursorvideo.close()
if len(music) > 0:
connection = connectionmusic
cursor = cursormusic
#Process music library
addon = xbmcaddon.Addon(id='plugin.video.emby')
if addon.getSetting("enableMusicSync") is "true":
addon = xbmcaddon.Addon()
if addon.getSetting('enableMusicSync') == "true":
connection = utils.KodiSQL("music")
cursor = connection.cursor()
@ -722,35 +728,34 @@ class LibrarySync(threading.Thread):
WriteKodiMusicDB().deleteItemFromKodiLibrary(item, connection, cursor)
connection.commit()
cursor.close()
# Close connection
cursormusic.close()
if deleteEmbyItem:
for item in itemList:
url = "{server}/mediabrowser/Items/%s" % item
self.logMsg('Deleting via URL: %s' % url)
doUtils.downloadUrl(url, type="DELETE")
doUtils.downloadUrl(url, type = "DELETE")
xbmc.executebuiltin("Container.Refresh")
def remove_items(self, itemsRemoved):
# websocket client
self.removeItems.extend(itemsRemoved)
def update_items(self, itemsToUpdate):
# doing adds and updates
# websocket client
if(len(itemsToUpdate) > 0):
self.logMsg("Message : Doing LibraryChanged : Processing Added and Updated : " + str(itemsToUpdate), 0)
self.logMsg("Doing LibraryChanged : Processing Added and Updated : " + str(itemsToUpdate), 0)
self.updateItems.extend(itemsToUpdate)
self.doIncrementalSync = True
def user_data_update(self, userDataList):
# do full playcount update for now
# websocket client
for userData in userDataList:
itemId = userData.get("ItemId")
if(itemId != None):
self.updateItems.append(itemId)
if(len(self.updateItems) > 0):
self.logMsg("Message : Doing UserDataChanged : Processing Updated : " + str(self.updateItems), 0)
self.doIncrementalSync = True
self.logMsg("Doing UserDataChanged : Processing Updated : " + str(self.updateItems), 0)
def ShouldStop(self):
@ -770,32 +775,44 @@ class LibrarySync(threading.Thread):
while not self.KodiMonitor.abortRequested():
# In the event the server goes offline after
# the thread has already been started.
while self.suspendClient == True:
# The service.py will change self.suspendClient to False
if self.KodiMonitor.waitForAbort(5):
# Abort was requested while waiting. We should exit
break
# Library sync
if not startupComplete:
# Run full sync
self.logMsg("Doing_Db_Sync: syncDatabase (Started)", 1)
startTime = datetime.now()
libSync = self.FullLibrarySync()
self.logMsg("Doing_Db_Sync: syncDatabase (Finished) %s" % libSync, 1)
elapsedTime = datetime.now() - startTime
self.logMsg("Doing_Db_Sync: syncDatabase (Finished in: %s) %s" % (str(elapsedTime).split('.')[0], libSync), 1)
if libSync:
startupComplete = True
if WINDOW.getProperty("OnWakeSync") == "true":
# Set via Kodi Monitor event
if WINDOW.getProperty("OnWakeSync") == "true" and WINDOW.getProperty('Server_online') == "true":
WINDOW.clearProperty("OnWakeSync")
if WINDOW.getProperty("SyncDatabaseRunning") != "true":
utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Started)",0)
self.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Started)", 0)
libSync = self.FullLibrarySync()
utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str(libSync),0)
self.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str(libSync), 0)
if self.doIncrementalSync:
# Add or update item to Kodi library
if len(self.updateItems) > 0:
# Add or update items
self.logMsg("Processing items: %s" % (str(self.updateItems)), 1)
listItems = self.updateItems
self.updateItems = []
self.doIncrementalSync = False
self.IncrementalSync(listItems)
if len(self.removeItems) > 0:
# Remove item from Kodi library
self.logMsg("Removing items: %s" % self.removeItems, 1)
listItems = self.removeItems
self.removeItems = []
self.removefromDB(listItems)
@ -805,3 +822,11 @@ class LibrarySync(threading.Thread):
break
self.logMsg("--- Library Sync Thread stopped ---", 0)
def suspendClient(self):
self.suspendClient = True
self.logMsg("--- Library Sync Thread paused ---", 0)
def resumeClient(self):
self.suspendClient = False
self.logMsg("--- Library Sync Thread resumed ---", 0)

View file

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
#################################################################################################
# utils class
#################################################################################################
@ -19,8 +21,7 @@ class PlayUtils():
clientInfo = ClientInformation()
addonName = clientInfo.getAddonName()
addonId = clientInfo.getAddonId()
addon = xbmcaddon.Addon(id=addonId)
addon = xbmcaddon.Addon()
audioPref = addon.getSetting('Audiopref')
subsPref = addon.getSetting('Subspref')
@ -35,76 +36,36 @@ class PlayUtils():
def getPlayUrl(self, server, id, result):
addon = self.addon
WINDOW = xbmcgui.Window(10000)
username = WINDOW.getProperty('currUser')
server = WINDOW.getProperty('server%s' % username)
if self.isDirectPlay(result):
try:
if self.isDirectPlay(result,True):
# Try direct play
playurl = self.directPlay(result)
if not playurl:
# Let user know that direct play failed
resp = xbmcgui.Dialog().select('Warning: Unable to direct play.', ['Play from HTTP', 'Play from HTTP and remember next time.'])
if resp > -1:
# Play from HTTP
playurl = self.directStream(result, server, id)
if resp == 1:
# Remember next time
addon.setSetting('playFromStream', "true")
if not playurl:
# Try transcoding
playurl = self.transcoding(result, server, id)
WINDOW.setProperty("transcoding%s" % id, "true")
self.logMsg("File is transcoding.", 1)
WINDOW.setProperty("%splaymethod" % playurl, "Transcode")
else:
self.logMsg("File is direct streaming.", 1)
WINDOW.setProperty("%splaymethod" % playurl, "DirectStream")
else:
# User decided not to proceed.
self.logMsg("Unable to direct play. Verify the following path is accessible by the device: %s. You might also need to add SMB credentials in the addon settings." % result[u'MediaSources'][0][u'Path'])
return False
else:
if playurl:
self.logMsg("File is direct playing.", 1)
WINDOW.setProperty("%splaymethod" % playurl.encode('utf-8'), "DirectPlay")
except:
return False
elif self.isDirectStream(result):
try:
# Try direct stream
playurl = self.directStream(result, server, id)
if not playurl:
# Try transcoding
playurl = self.transcoding(result, server, id)
WINDOW.setProperty("transcoding%s" % id, "true")
self.logMsg("File is transcoding.", 1)
WINDOW.setProperty("%splaymethod" % playurl, "Transcode")
else:
if playurl:
self.logMsg("File is direct streaming.", 1)
WINDOW.setProperty("%splaymethod" % playurl, "DirectStream")
except:
return False
elif self.isTranscoding(result):
try:
# Try transcoding
else:# Try transcoding
playurl = self.transcoding(result, server, id)
WINDOW.setProperty("transcoding%s" % id, "true")
if playurl:
self.logMsg("File is transcoding.", 1)
WINDOW.setProperty("%splaymethod" % playurl, "Transcode")
except:
return False
return playurl.encode('utf-8')
def isDirectPlay(self, result):
def isDirectPlay(self, result, dialog=False):
# Requirements for Direct play:
# FileSystem, Accessible path
self.addon = xbmcaddon.Addon(id=self.addonId)
self.addon = xbmcaddon.Addon()
playhttp = self.addon.getSetting('playFromStream')
# User forcing to play via HTTP instead of SMB
@ -126,17 +87,30 @@ class PlayUtils():
return True
else:
self.logMsg("Can't direct play: Unable to locate the content.", 1)
if dialog:
# Let user know that direct play failed
resp = xbmcgui.Dialog().select('Warning: Unable to direct play.', ['Play from HTTP', 'Play from HTTP and remember next time.'])
if resp == 1:
# Remember next time
addon.setSetting('playFromStream', "true")
else:
# User decided not to proceed.
self.logMsg("Unable to direct play. Verify the following path is accessible by the device: %s. You might also need to add SMB credentials in the addon settings." % result[u'MediaSources'][0][u'Path'])
return False
def directPlay(self, result):
addon = self.addon
try:
# Item can be played directly
try:
playurl = result[u'MediaSources'][0][u'Path']
except:
playurl = result[u'Path']
except:
self.logMsg("Direct play failed. Trying Direct stream.", 1)
return False
else:
if u'VideoType' in result:
# Specific format modification
if u'Dvd' in result[u'VideoType']:
@ -156,19 +130,15 @@ class PlayUtils():
playurl = playurl.replace("\\", "/")
if "apple.com" in playurl:
USER_AGENT = 'QuickTime/7.7.4'
USER_AGENT = "QuickTime/7.7.4"
playurl += "?|User-Agent=%s" % USER_AGENT
if ":" not in playurl:
self.logMsg("Path seems invalid: %s" % playurl)
self.logMsg("Path seems invalid: %s" % playurl, 1)
return False
return playurl
except:
self.logMsg("Direct play failed. Trying Direct stream.", 1)
return False
def isDirectStream(self, result):
# Requirements for Direct stream:
# FileSystem or Remote, BitRate, supported encoding
@ -188,23 +158,24 @@ class PlayUtils():
return True
def directStream(self, result, server, id, type="Video"):
def directStream(self, result, server, id, type = "Video"):
try:
if type == "Video":
# Play with Direct Stream
playurl = "%s/mediabrowser/Videos/%s/stream?static=true" % (server, id)
elif type == "Audio":
playurl = "%s/mediabrowser/Audio/%s/stream.mp3" % (server, id)
return playurl
if "ThemeVideo" in type:
playurl ="%s/mediabrowser/Videos/%s/stream?static=true" % (server, id)
elif "Video" in type:
playurl = "%s/mediabrowser/Videos/%s/stream?static=true" % (server, id)
# Verify audio and subtitles
mediaSources = result[u'MediaSources']
if mediaSources[0].get('DefaultAudioStreamIndex') != None:
playurl = "%s&AudioStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultAudioStreamIndex'))
if mediaSources[0].get('DefaultSubtitleStreamIndex') != None:
playurl = "%s&SubtitleStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultSubtitleStreamIndex'))
self.logMsg("Playurl: %s" % playurl)
elif "Audio" in type:
playurl = "%s/mediabrowser/Audio/%s/stream.mp3" % (server, id)
return playurl
except:
@ -329,7 +300,7 @@ class PlayUtils():
# Local or Network path
self.logMsg("Path exists.", 2)
return True
elif ":\\" not in path:
elif "nfs:" in path.lower():
# Give benefit of the doubt.
self.logMsg("Can't verify path. Still try direct play.", 2)
return True

File diff suppressed because it is too large Load diff