Centralize Direct Play and Direct Paths
This commit is contained in:
parent
e4aefaaa5e
commit
9d06225228
6 changed files with 180 additions and 147 deletions
|
@ -2,7 +2,7 @@
|
||||||
<strings>
|
<strings>
|
||||||
<!-- Add-on settings -->
|
<!-- Add-on settings -->
|
||||||
<string id="30000">Server Address (IP)</string><!-- Verified -->
|
<string id="30000">Server Address (IP)</string><!-- Verified -->
|
||||||
<string id="30002">Deactivate Direct Play and enforce Transcoding</string><!-- Verified -->
|
<string id="30002">Prefered playback method</string><!-- Verified -->
|
||||||
<string id="30004">Log level</string><!-- Verified -->
|
<string id="30004">Log level</string><!-- Verified -->
|
||||||
<string id="30005">Username: </string>
|
<string id="30005">Username: </string>
|
||||||
<string id="30006">Password: </string>
|
<string id="30006">Password: </string>
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
<string id="30157">Enable Enhanced Images (eg CoverArt)</string><!-- Verified -->
|
<string id="30157">Enable Enhanced Images (eg CoverArt)</string><!-- Verified -->
|
||||||
<string id="30158">Metadata</string>
|
<string id="30158">Metadata</string>
|
||||||
<string id="30159">Artwork</string>
|
<string id="30159">Artwork</string>
|
||||||
<string id="30160">Video Quality</string><!-- Verified -->
|
<string id="30160">Video Quality for Transcoding</string><!-- Verified -->
|
||||||
|
|
||||||
<string id="30161">Enable Suggested Loader (Requires Restart)</string>
|
<string id="30161">Enable Suggested Loader (Requires Restart)</string>
|
||||||
<string id="30162">Add Season Number</string>
|
<string id="30162">Add Season Number</string>
|
||||||
|
@ -298,7 +298,7 @@
|
||||||
<string id="30533">Duration of the music library pop up (in seconds)</string>
|
<string id="30533">Duration of the music library pop up (in seconds)</string>
|
||||||
<string id="30534">Server messages</string>
|
<string id="30534">Server messages</string>
|
||||||
<string id="30535">[COLOR yellow]Generate a new unique device Id (e.g. when cloning Kodi)[/COLOR]</string>
|
<string id="30535">[COLOR yellow]Generate a new unique device Id (e.g. when cloning Kodi)[/COLOR]</string>
|
||||||
<string id="30536">Users must log in every time when Kodi restarts</string>
|
<string id="30536">Users must log in every time Kodi restarts</string>
|
||||||
<string id="30537">RESTART KODI IF YOU MAKE ANY CHANGES</string>
|
<string id="30537">RESTART KODI IF YOU MAKE ANY CHANGES</string>
|
||||||
<string id="30538">Complete Re-Sync necessary</string>
|
<string id="30538">Complete Re-Sync necessary</string>
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@
|
||||||
<string id="39040">Replace Plex TV SHOWS with:</string>
|
<string id="39040">Replace Plex TV SHOWS with:</string>
|
||||||
<string id="39041">Original Plex MUSIC path to replace:</string>
|
<string id="39041">Original Plex MUSIC path to replace:</string>
|
||||||
<string id="39042">Replace Plex MUSIC with:</string>
|
<string id="39042">Replace Plex MUSIC with:</string>
|
||||||
<string id="39043">Go a step further and complete replace all original Plex library paths (/volume1/media) with custom SMB paths (smb://NAS/MyStuff)?</string>
|
<string id="39043">Go a step further and completely replace all original Plex library paths (/volume1/media) with custom SMB paths (smb://NAS/MyStuff)?</string>
|
||||||
<string id="39044">Please enter your custom smb paths in the settings under "Sync Options" and then restart Kodi</string>
|
<string id="39044">Please enter your custom smb paths in the settings under "Sync Options" and then restart Kodi</string>
|
||||||
|
|
||||||
<string id="39045">Appearance Tweaks</string>
|
<string id="39045">Appearance Tweaks</string>
|
||||||
|
@ -398,8 +398,8 @@
|
||||||
<string id="39053">Do a full library sync every x minutes</string>
|
<string id="39053">Do a full library sync every x minutes</string>
|
||||||
<string id="39054">remote</string>
|
<string id="39054">remote</string>
|
||||||
<string id="39055">Searching for Plex Server</string>
|
<string id="39055">Searching for Plex Server</string>
|
||||||
|
<string id="39056">Used by Sync and when attempting to Direct Play</string>
|
||||||
|
<string id="39057">Customize Paths</string>
|
||||||
|
|
||||||
<!-- Plex Entrypoint.py -->
|
<!-- Plex Entrypoint.py -->
|
||||||
<string id="39200">Log-out Plex Home User </string>
|
<string id="39200">Log-out Plex Home User </string>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<strings>
|
<strings>
|
||||||
<string id="30000">IP-Adresse des Servers</string>
|
<string id="30000">IP-Adresse des Servers</string>
|
||||||
<string id="30001">Automatisches Öffnen von Ordnern mit einem Eintrag</string>
|
<string id="30001">Automatisches Öffnen von Ordnern mit einem Eintrag</string>
|
||||||
<string id="30002">Direct Play deaktivieren and Transkodieren erzwingen</string>
|
<string id="30002">Gewünschte Wiedergabe-Methode</string>
|
||||||
<string id="30004">Log Level:</string>
|
<string id="30004">Log Level:</string>
|
||||||
<string id="30005">Benutzername: </string>
|
<string id="30005">Benutzername: </string>
|
||||||
<string id="30006">Passwort: </string>
|
<string id="30006">Passwort: </string>
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
<string id="30157">Deaktiviere erweiterte Bilder (z.B. CoverArt)</string>
|
<string id="30157">Deaktiviere erweiterte Bilder (z.B. CoverArt)</string>
|
||||||
<string id="30158">Metadaten</string>
|
<string id="30158">Metadaten</string>
|
||||||
<string id="30159">Grafiken</string>
|
<string id="30159">Grafiken</string>
|
||||||
<string id="30160">Videoqualität</string>
|
<string id="30160">Videoqualität für Transkodierung</string>
|
||||||
|
|
||||||
<string id="30161">'Empfohlen'-Loader aktivieren (Erfordert Neustart)</string>
|
<string id="30161">'Empfohlen'-Loader aktivieren (Erfordert Neustart)</string>
|
||||||
<string id="30162">Staffelnummer hinzufügen</string>
|
<string id="30162">Staffelnummer hinzufügen</string>
|
||||||
|
@ -336,6 +336,9 @@
|
||||||
<string id="39053">Kompletten Scan aller Bibliotheken alle x Minuten durchführen</string>
|
<string id="39053">Kompletten Scan aller Bibliotheken alle x Minuten durchführen</string>
|
||||||
<string id="39054">remote</string>
|
<string id="39054">remote</string>
|
||||||
<string id="39055">Suche Plex Server</string>
|
<string id="39055">Suche Plex Server</string>
|
||||||
|
<string id="39056">Verwendet für Synchronisierung sowie beim Versuch, Direct Play zu nutzen</string>
|
||||||
|
<string id="39057">Pfade ändern</string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Plex Entrypoint.py -->
|
<!-- Plex Entrypoint.py -->
|
||||||
|
|
|
@ -394,7 +394,7 @@ class PlexAPI():
|
||||||
name, scheme, ip, port, type, owned, token
|
name, scheme, ip, port, type, owned, token
|
||||||
"""
|
"""
|
||||||
address = ip + ':' + port
|
address = ip + ':' + port
|
||||||
baseURL = scheme+'://'+ip+':'+port
|
baseURL = scheme + '://' + ip + ':' + port
|
||||||
self.g_PMS[uuid] = {
|
self.g_PMS[uuid] = {
|
||||||
'name': name,
|
'name': name,
|
||||||
'scheme': scheme,
|
'scheme': scheme,
|
||||||
|
@ -485,7 +485,8 @@ class PlexAPI():
|
||||||
elif "Resource-Identifier:" in each:
|
elif "Resource-Identifier:" in each:
|
||||||
update['uuid'] = each.split(':')[1].strip()
|
update['uuid'] = each.split(':')[1].strip()
|
||||||
elif "Name:" in each:
|
elif "Name:" in each:
|
||||||
update['serverName'] = each.split(':')[1].strip().decode('utf-8', 'replace')
|
update['serverName'] = each.split(
|
||||||
|
':')[1].strip().decode('utf-8', 'replace')
|
||||||
elif "Port:" in each:
|
elif "Port:" in each:
|
||||||
update['port'] = each.split(':')[1].strip()
|
update['port'] = each.split(':')[1].strip()
|
||||||
elif "Updated-At:" in each:
|
elif "Updated-At:" in each:
|
||||||
|
@ -582,8 +583,8 @@ class PlexAPI():
|
||||||
PMS = {}
|
PMS = {}
|
||||||
PMS['name'] = Dir.get('name')
|
PMS['name'] = Dir.get('name')
|
||||||
infoAge = time.time() - int(Dir.get('lastSeenAt'))
|
infoAge = time.time() - int(Dir.get('lastSeenAt'))
|
||||||
oneDayInSec = 60*60*24
|
oneDayInSec = 60 * 60 * 24
|
||||||
if infoAge > 2*oneDayInSec:
|
if infoAge > 2 * oneDayInSec:
|
||||||
self.logMsg("Server %s not seen for 2 days - "
|
self.logMsg("Server %s not seen for 2 days - "
|
||||||
"skipping." % PMS['name'], 0)
|
"skipping." % PMS['name'], 0)
|
||||||
continue
|
continue
|
||||||
|
@ -708,9 +709,10 @@ class PlexAPI():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# provide credentials
|
# provide credentials
|
||||||
### optional... when 'realm' is unknown
|
# optional... when 'realm' is unknown
|
||||||
##passmanager = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
##passmanager = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||||
##passmanager.add_password(None, address, username, password) # None: default "realm"
|
# passmanager.add_password(None, address, username, password) # None:
|
||||||
|
# default "realm"
|
||||||
passmanager = urllib2.HTTPPasswordMgr()
|
passmanager = urllib2.HTTPPasswordMgr()
|
||||||
passmanager.add_password(MyPlexHost, MyPlexURL, username, password)
|
passmanager.add_password(MyPlexHost, MyPlexURL, username, password)
|
||||||
authhandler = urllib2.HTTPBasicAuthHandler(passmanager)
|
authhandler = urllib2.HTTPBasicAuthHandler(passmanager)
|
||||||
|
@ -746,9 +748,11 @@ class PlexAPI():
|
||||||
MyPlexURL = 'http://' + MyPlexHost + MyPlexSignOutPath
|
MyPlexURL = 'http://' + MyPlexHost + MyPlexSignOutPath
|
||||||
|
|
||||||
# create POST request
|
# create POST request
|
||||||
xargs = { 'X-Plex-Token': authtoken }
|
xargs = {'X-Plex-Token': authtoken}
|
||||||
request = urllib2.Request(MyPlexURL, None, xargs)
|
request = urllib2.Request(MyPlexURL, None, xargs)
|
||||||
request.get_method = lambda: 'POST' # turn into 'POST' - done automatically with data!=None. But we don't have data.
|
# turn into 'POST' - done automatically with data!=None. But we don't
|
||||||
|
# have data.
|
||||||
|
request.get_method = lambda: 'POST'
|
||||||
|
|
||||||
response = urllib2.urlopen(request).read()
|
response = urllib2.urlopen(request).read()
|
||||||
|
|
||||||
|
@ -1005,12 +1009,12 @@ class PlexAPI():
|
||||||
if key.startswith('http://') or key.startswith('https://'): # external address - keep
|
if key.startswith('http://') or key.startswith('https://'): # external address - keep
|
||||||
path = key
|
path = key
|
||||||
else:
|
else:
|
||||||
if AuthToken=='':
|
if AuthToken == '':
|
||||||
path = key
|
path = key
|
||||||
else:
|
else:
|
||||||
xargs = dict()
|
xargs = dict()
|
||||||
xargs['X-Plex-Token'] = AuthToken
|
xargs['X-Plex-Token'] = AuthToken
|
||||||
if key.find('?')==-1:
|
if key.find('?') == -1:
|
||||||
path = key + '?' + urlencode(xargs)
|
path = key + '?' + urlencode(xargs)
|
||||||
else:
|
else:
|
||||||
path = key + '&' + urlencode(xargs)
|
path = key + '&' + urlencode(xargs)
|
||||||
|
@ -1040,14 +1044,15 @@ class PlexAPI():
|
||||||
|
|
||||||
# This is bogus (note the extra path component) but ATV is stupid when it comes to caching images, it doesn't use querystrings.
|
# This is bogus (note the extra path component) but ATV is stupid when it comes to caching images, it doesn't use querystrings.
|
||||||
# Fortunately PMS is lenient...
|
# Fortunately PMS is lenient...
|
||||||
transcodePath = '/photo/:/transcode/' +str(width)+'x'+str(height)+ '/' + quote_plus(path)
|
transcodePath = '/photo/:/transcode/' + \
|
||||||
|
str(width) + 'x' + str(height) + '/' + quote_plus(path)
|
||||||
|
|
||||||
args = dict()
|
args = dict()
|
||||||
args['width'] = width
|
args['width'] = width
|
||||||
args['height'] = height
|
args['height'] = height
|
||||||
args['url'] = path
|
args['url'] = path
|
||||||
|
|
||||||
if not AuthToken=='':
|
if not AuthToken == '':
|
||||||
args['X-Plex-Token'] = AuthToken
|
args['X-Plex-Token'] = AuthToken
|
||||||
|
|
||||||
return transcodePath + '?' + urlencode(args)
|
return transcodePath + '?' + urlencode(args)
|
||||||
|
@ -1062,10 +1067,10 @@ class PlexAPI():
|
||||||
result:
|
result:
|
||||||
final path to image file
|
final path to image file
|
||||||
"""
|
"""
|
||||||
if not AuthToken=='':
|
if not AuthToken == '':
|
||||||
xargs = dict()
|
xargs = dict()
|
||||||
xargs['X-Plex-Token'] = AuthToken
|
xargs['X-Plex-Token'] = AuthToken
|
||||||
if path.find('?')==-1:
|
if path.find('?') == -1:
|
||||||
path = path + '?' + urlencode(xargs)
|
path = path + '?' + urlencode(xargs)
|
||||||
else:
|
else:
|
||||||
path = path + '&' + urlencode(xargs)
|
path = path + '&' + urlencode(xargs)
|
||||||
|
@ -1095,7 +1100,7 @@ class PlexAPI():
|
||||||
args['maxAudioBitrate'] = maxAudioBitrate
|
args['maxAudioBitrate'] = maxAudioBitrate
|
||||||
|
|
||||||
xargs = clientinfo.ClientInfo().getXArgsDeviceInfo(options)
|
xargs = clientinfo.ClientInfo().getXArgsDeviceInfo(options)
|
||||||
if not AuthToken=='':
|
if not AuthToken == '':
|
||||||
xargs['X-Plex-Token'] = AuthToken
|
xargs['X-Plex-Token'] = AuthToken
|
||||||
|
|
||||||
return transcodePath + urlencode(args) + '&' + urlencode(xargs)
|
return transcodePath + urlencode(args) + '&' + urlencode(xargs)
|
||||||
|
@ -1110,10 +1115,10 @@ class PlexAPI():
|
||||||
result:
|
result:
|
||||||
final path to audio file
|
final path to audio file
|
||||||
"""
|
"""
|
||||||
if not AuthToken=='':
|
if not AuthToken == '':
|
||||||
xargs = dict()
|
xargs = dict()
|
||||||
xargs['X-Plex-Token'] = AuthToken
|
xargs['X-Plex-Token'] = AuthToken
|
||||||
if path.find('?')==-1:
|
if path.find('?') == -1:
|
||||||
path = path + '?' + urlencode(xargs)
|
path = path + '?' + urlencode(xargs)
|
||||||
else:
|
else:
|
||||||
path = path + '&' + urlencode(xargs)
|
path = path + '&' + urlencode(xargs)
|
||||||
|
@ -1229,7 +1234,7 @@ class API():
|
||||||
res = self.item[0][self.part].attrib.get('file')
|
res = self.item[0][self.part].attrib.get('file')
|
||||||
except:
|
except:
|
||||||
res = None
|
res = None
|
||||||
if res:
|
if res is not None:
|
||||||
res = unquote(res).decode('utf-8')
|
res = unquote(res).decode('utf-8')
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@ -1946,7 +1951,8 @@ class API():
|
||||||
kodiindex = 0
|
kodiindex = 0
|
||||||
for stream in mediastreams:
|
for stream in mediastreams:
|
||||||
index = stream.attrib['id']
|
index = stream.attrib['id']
|
||||||
# Since Emby returns all possible tracks together, have to pull only external subtitles.
|
# Since Emby returns all possible tracks together, have to pull
|
||||||
|
# only external subtitles.
|
||||||
key = stream.attrib.get('key')
|
key = stream.attrib.get('key')
|
||||||
# IsTextSubtitleStream if true, is available to download from emby.
|
# IsTextSubtitleStream if true, is available to download from emby.
|
||||||
if stream.attrib.get('streamType') == "3" and key:
|
if stream.attrib.get('streamType') == "3" and key:
|
||||||
|
@ -2031,27 +2037,61 @@ class API():
|
||||||
listItem.addStreamInfo(
|
listItem.addStreamInfo(
|
||||||
"video", {'duration': self.getRuntime()[1]})
|
"video", {'duration': self.getRuntime()[1]})
|
||||||
|
|
||||||
def validatePlayurl(self, playurl, typus):
|
def validatePlayurl(self, path, typus, forceCheck=False):
|
||||||
"""
|
"""
|
||||||
Returns a valid url for Kodi, e.g. with substituted path
|
Returns a valid path for Kodi, e.g. with '\' substituted to '\\' in
|
||||||
|
Unicode. Returns None if this is not possible
|
||||||
|
|
||||||
|
path : Unicode
|
||||||
|
typus : Plex type from PMS xml
|
||||||
|
forceCheck : Will always try to check validity of path
|
||||||
|
Will also skip confirmation dialog if path not found
|
||||||
"""
|
"""
|
||||||
|
if path is None:
|
||||||
|
return None
|
||||||
|
types = {
|
||||||
|
'movie': 'movie',
|
||||||
|
'show': 'tv',
|
||||||
|
'season': 'tv',
|
||||||
|
'episode': 'tv',
|
||||||
|
'artist': 'music',
|
||||||
|
'album': 'music',
|
||||||
|
'song': 'music',
|
||||||
|
'track': 'music',
|
||||||
|
}
|
||||||
|
typus = types[typus]
|
||||||
if utils.window('remapSMB') == 'true':
|
if utils.window('remapSMB') == 'true':
|
||||||
playurl = playurl.replace(utils.window('remapSMB%sOrg' % typus),
|
path = path.replace(utils.window('remapSMB%sOrg' % typus),
|
||||||
utils.window('remapSMB%sNew' % typus))
|
utils.window('remapSMB%sNew' % typus))
|
||||||
# There might be backslashes left over:
|
# There might be backslashes left over:
|
||||||
playurl = playurl.replace('\\', '/')
|
path = path.replace('\\', '/')
|
||||||
elif utils.window('replaceSMB') == 'true':
|
elif utils.window('replaceSMB') == 'true':
|
||||||
if playurl.startswith('\\\\'):
|
if path.startswith('\\\\'):
|
||||||
playurl = 'smb:' + playurl.replace('\\', '/')
|
path = 'smb:' + path.replace('\\', '/')
|
||||||
if (utils.window('emby_pathverified') != "true" and
|
if utils.window('emby_pathverified') == 'true' and forceCheck is False:
|
||||||
not xbmcvfs.exists(playurl.encode('utf-8'))):
|
return path
|
||||||
|
|
||||||
|
check = xbmcvfs.exists(path.encode('utf-8'))
|
||||||
|
# exists() NEEDS either a '/' or '\\' at the end of a DIR name
|
||||||
|
if check is False:
|
||||||
|
check = xbmcvfs.exists((path + '/').encode('utf-8'))
|
||||||
|
if check is False:
|
||||||
|
check = xbmcvfs.exists((path + '\\').encode('utf-8'))
|
||||||
|
if check is False:
|
||||||
|
if forceCheck is False:
|
||||||
# Validate the path is correct with user intervention
|
# Validate the path is correct with user intervention
|
||||||
if self.askToValidate(playurl):
|
if self.askToValidate(path):
|
||||||
utils.window('emby_shouldStop', value="true")
|
utils.window('emby_shouldStop', value="true")
|
||||||
playurl = False
|
path = None
|
||||||
utils.window('emby_pathverified', value='true')
|
utils.window('emby_pathverified', value='true')
|
||||||
utils.settings('emby_pathverified', value='true')
|
utils.settings('emby_pathverified', value='true')
|
||||||
return playurl
|
else:
|
||||||
|
path = None
|
||||||
|
elif forceCheck is False:
|
||||||
|
if utils.window('emby_pathverified') != 'true':
|
||||||
|
utils.window('emby_pathverified', value='true')
|
||||||
|
utils.settings('emby_pathverified', value='true')
|
||||||
|
return path
|
||||||
|
|
||||||
def askToValidate(self, url):
|
def askToValidate(self, url):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -440,8 +440,8 @@ class Movies(Items):
|
||||||
# Something went wrong, trying to use non-direct paths
|
# Something went wrong, trying to use non-direct paths
|
||||||
doIndirect = True
|
doIndirect = True
|
||||||
else:
|
else:
|
||||||
playurl = API.validatePlayurl(playurl, 'movie')
|
playurl = API.validatePlayurl(playurl, API.getType())
|
||||||
if playurl is False:
|
if playurl is None:
|
||||||
return False
|
return False
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -450,7 +450,6 @@ class Movies(Items):
|
||||||
# Network share
|
# Network share
|
||||||
filename = playurl.rsplit("/", 1)[1]
|
filename = playurl.rsplit("/", 1)[1]
|
||||||
path = playurl.replace(filename, "")
|
path = playurl.replace(filename, "")
|
||||||
utils.window('emby_pathverified', value="true")
|
|
||||||
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.movies/"
|
||||||
|
@ -1041,8 +1040,8 @@ class TVShows(Items):
|
||||||
# Something went wrong, trying to use non-direct paths
|
# Something went wrong, trying to use non-direct paths
|
||||||
doIndirect = True
|
doIndirect = True
|
||||||
else:
|
else:
|
||||||
playurl = API.validatePlayurl(playurl, 'tv')
|
playurl = API.validatePlayurl(playurl, API.getType())
|
||||||
if playurl is False:
|
if playurl is None:
|
||||||
return False
|
return False
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -1052,12 +1051,6 @@ class TVShows(Items):
|
||||||
# Network path
|
# Network path
|
||||||
path = "%s/" % playurl
|
path = "%s/" % playurl
|
||||||
toplevelpath = "%s/" % dirname(dirname(path))
|
toplevelpath = "%s/" % dirname(dirname(path))
|
||||||
if (utils.window('emby_pathverified') != "true" and
|
|
||||||
not xbmcvfs.exists(path.encode('utf-8'))):
|
|
||||||
# Validate the path is correct with user intervention
|
|
||||||
if self.askToValidate(playurl):
|
|
||||||
return False
|
|
||||||
utils.window('emby_pathverified', value="true")
|
|
||||||
if doIndirect:
|
if doIndirect:
|
||||||
# Set plugin path
|
# Set plugin path
|
||||||
toplevelpath = "plugin://plugin.video.plexkodiconnect.tvshows/"
|
toplevelpath = "plugin://plugin.video.plexkodiconnect.tvshows/"
|
||||||
|
@ -1331,13 +1324,8 @@ class TVShows(Items):
|
||||||
# Something went wrong, trying to use non-direct paths
|
# Something went wrong, trying to use non-direct paths
|
||||||
doIndirect = True
|
doIndirect = True
|
||||||
else:
|
else:
|
||||||
playurl = API.validatePlayurl(playurl, 'tv')
|
playurl = API.validatePlayurl(playurl, API.getType())
|
||||||
if playurl is False:
|
if playurl is None:
|
||||||
return False
|
|
||||||
if (utils.window('emby_pathverified') != "true" and
|
|
||||||
not xbmcvfs.exists(playurl.encode('utf-8'))):
|
|
||||||
# Validate the path is correct with user intervention
|
|
||||||
if self.askToValidate(playurl):
|
|
||||||
return False
|
return False
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -1346,7 +1334,6 @@ class TVShows(Items):
|
||||||
# Network share
|
# Network share
|
||||||
filename = playurl.rsplit("/", 1)[1]
|
filename = playurl.rsplit("/", 1)[1]
|
||||||
path = playurl.replace(filename, "")
|
path = playurl.replace(filename, "")
|
||||||
utils.window('emby_pathverified', value="true")
|
|
||||||
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.movies/"
|
||||||
|
@ -2085,13 +2072,8 @@ class Music(Items):
|
||||||
# Something went wrong, trying to use non-direct paths
|
# Something went wrong, trying to use non-direct paths
|
||||||
doIndirect = True
|
doIndirect = True
|
||||||
else:
|
else:
|
||||||
playurl = API.validatePlayurl(playurl, 'music')
|
playurl = API.validatePlayurl(playurl, API.getType())
|
||||||
if playurl is False:
|
if playurl is None:
|
||||||
return False
|
|
||||||
if (utils.window('emby_pathverified') != "true" and
|
|
||||||
not xbmcvfs.exists(playurl.encode('utf-8'))):
|
|
||||||
# Validate the path is correct with user intervention
|
|
||||||
if self.askToValidate(playurl):
|
|
||||||
return False
|
return False
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -2100,7 +2082,6 @@ class Music(Items):
|
||||||
# Network share
|
# Network share
|
||||||
filename = playurl.rsplit("/", 1)[1]
|
filename = playurl.rsplit("/", 1)[1]
|
||||||
path = playurl.replace(filename, "")
|
path = playurl.replace(filename, "")
|
||||||
utils.window('emby_pathverified', value="true")
|
|
||||||
if doIndirect:
|
if doIndirect:
|
||||||
# Plex works a bit differently
|
# Plex works a bit differently
|
||||||
path = "%s%s" % (self.server, item[0][0].attrib.get('key'))
|
path = "%s%s" % (self.server, item[0][0].attrib.get('key'))
|
||||||
|
|
|
@ -91,34 +91,25 @@ class PlayUtils():
|
||||||
Returns the path/playurl if successful, False otherwise
|
Returns the path/playurl if successful, False otherwise
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Requirement: Filesystem, Accessible path
|
# set to either 'Direct Stream=1' or 'Transcode=2'
|
||||||
if utils.settings('playFromStream') == "true":
|
if utils.settings('playType') != "0":
|
||||||
# User forcing to play via HTTP
|
# User forcing to play via HTTP
|
||||||
self.logMsg("Can't direct play, user enabled play from HTTP.", 1)
|
self.logMsg("User chose to not direct play", 1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.h265enabled():
|
if self.h265enabled():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
path = self.API.getFilePath()
|
path = self.API.validatePlayurl(self.API.getFilePath(),
|
||||||
|
self.API.getType(),
|
||||||
|
forceCheck=True)
|
||||||
if path is None:
|
if path is None:
|
||||||
self.logMsg('PMS item does not have a filepath', 2)
|
|
||||||
return False
|
|
||||||
# Assign network protocol
|
|
||||||
if path.startswith('\\\\'):
|
|
||||||
path = path.replace('\\\\', 'smb://')
|
|
||||||
path = path.replace('\\', '/')
|
|
||||||
# Plex returns Windows paths as e.g. 'c:\slfkjelf\slfje\file.mkv'
|
|
||||||
elif '\\' in path:
|
|
||||||
path = path.replace('\\', '\\\\')
|
|
||||||
|
|
||||||
if xbmcvfs.exists(path):
|
|
||||||
self.logMsg('Kodi can access file %s - direct playing' % path, 2)
|
|
||||||
return path
|
|
||||||
else:
|
|
||||||
self.logMsg('Kodi cannot access file %s - no direct play'
|
self.logMsg('Kodi cannot access file %s - no direct play'
|
||||||
% path, 2)
|
% path, 1)
|
||||||
return False
|
return False
|
||||||
|
else:
|
||||||
|
self.logMsg('Kodi can access file %s - direct playing' % path, 1)
|
||||||
|
return path
|
||||||
|
|
||||||
def directPlay(self):
|
def directPlay(self):
|
||||||
|
|
||||||
|
@ -198,13 +189,17 @@ class PlayUtils():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isDirectStream(self):
|
def isDirectStream(self):
|
||||||
if not self.h265enabled():
|
# set to 'Transcode=2'
|
||||||
|
if utils.settings('playType') == "2":
|
||||||
|
# User forcing to play via HTTP
|
||||||
|
self.logMsg("User chose to transcode", 1)
|
||||||
|
return False
|
||||||
|
if self.h265enabled():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Verify the bitrate
|
# Verify the bitrate
|
||||||
if not self.isNetworkSufficient():
|
if not self.isNetworkSufficient():
|
||||||
self.logMsg(
|
self.logMsg("The network speed is insufficient to direct stream "
|
||||||
"The network speed is insufficient to direct stream file.", 1)
|
"file. Transcoding", 1)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -228,11 +223,18 @@ class PlayUtils():
|
||||||
return playurl
|
return playurl
|
||||||
|
|
||||||
def isNetworkSufficient(self):
|
def isNetworkSufficient(self):
|
||||||
|
"""
|
||||||
settings = self.getBitrate()
|
Returns True if the network is sufficient (set in file settings)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
sourceBitrate = int(self.API.getDataFromPartOrMedia('bitrate'))
|
sourceBitrate = int(self.API.getDataFromPartOrMedia('bitrate'))
|
||||||
self.logMsg("The add-on settings bitrate is: %s, the video bitrate required is: %s" % (settings, sourceBitrate), 1)
|
except:
|
||||||
|
self.logMsg('Could not detect source bitrate. It is assumed to be'
|
||||||
|
'sufficient', 1)
|
||||||
|
return True
|
||||||
|
settings = self.getBitrate()
|
||||||
|
self.logMsg("The add-on settings bitrate is: %s, the video bitrate"
|
||||||
|
"required is: %s" % (settings, sourceBitrate), 1)
|
||||||
if settings < sourceBitrate:
|
if settings < sourceBitrate:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -37,13 +37,7 @@
|
||||||
<setting id="plexToken" label="plexToken" type="text" default="" visible="false" />
|
<setting id="plexToken" label="plexToken" type="text" default="" visible="false" />
|
||||||
<setting id="plexHomeSize" type="number" default="1" visible="false" />
|
<setting id="plexHomeSize" type="number" default="1" visible="false" />
|
||||||
</category>
|
</category>
|
||||||
<category label="Plex Companion">
|
|
||||||
<setting type="lsep" label="39008" />
|
|
||||||
<setting id="plexCompanion" label="39004" type="bool" default="true" />
|
|
||||||
<setting id="deviceNameOpt" label="30504" type="bool" default="false" />
|
|
||||||
<setting id="deviceName" label="30016" type="text" visible="eq(-1,true)" default="Kodi" />
|
|
||||||
<setting id="companionPort" label="39005" type="number" default="3005" option="int" visible="eq(-3,true)"/>
|
|
||||||
</category>
|
|
||||||
<category label="30506"><!-- Sync Options -->
|
<category label="30506"><!-- Sync Options -->
|
||||||
<setting type="lsep" label="30537" /><!-- Restart if you make changes -->
|
<setting type="lsep" label="30537" /><!-- Restart if you make changes -->
|
||||||
<setting id="syncEmptyShows" type="bool" label="30508" default="false" visible="false"/>
|
<setting id="syncEmptyShows" type="bool" label="30508" default="false" visible="false"/>
|
||||||
|
@ -63,14 +57,7 @@
|
||||||
<setting type="lsep" label="30538" /><!-- Complete Re-Sync necessary -->
|
<setting type="lsep" label="30538" /><!-- Complete Re-Sync necessary -->
|
||||||
<setting id="enableMusic" type="bool" label="30509" default="true" />
|
<setting id="enableMusic" type="bool" label="30509" default="true" />
|
||||||
<setting id="useDirectPaths" type="enum" label="30511" values="Addon(Default)|Native(Direct paths)" default="0" visible="true"/> <!-- Playback mode -->
|
<setting id="useDirectPaths" type="enum" label="30511" values="Addon(Default)|Native(Direct paths)" default="0" visible="true"/> <!-- Playback mode -->
|
||||||
<setting id="replaceSMB" type="bool" label="39034" default="true" visible="eq(-1,1)"/> <!-- replace all Plex paths with SMB paths -->
|
|
||||||
<setting id="remapSMB" type="bool" label="39035" default="false" visible="eq(-2,1)"/> <!-- replace Plex paths /volume1/media or \\myserver\media with a custom SMB path smb://NAS/mystuff -->
|
|
||||||
<setting id="remapSMBmovieOrg" type="text" label="39037" default="" visible="eq(-1,true)"/> <!-- Original Plex MOVIE path to replace -->
|
|
||||||
<setting id="remapSMBmovieNew" type="text" label="39038" default="smb://" visible="eq(-2,true)"/> <!-- Replace Plex MOVIE with: -->
|
|
||||||
<setting id="remapSMBtvOrg" type="text" label="39039" default="" visible="eq(-3,true)"/> <!-- Original Plex TV SHOWS path to replace: -->
|
|
||||||
<setting id="remapSMBtvNew" type="text" label="39040" default="smb://" visible="eq(-4,true)"/> <!-- Replace Plex TV SHOWS with: -->
|
|
||||||
<setting id="remapSMBmusicOrg" type="text" label="39041" default="" visible="eq(-5,true)"/> <!-- Original Plex MUSIC path to replace: -->
|
|
||||||
<setting id="remapSMBmusicNew" type="text" label="39042" default="smb://" visible="eq(-6,true)"/> <!-- Replace Plex MUSIC with: -->
|
|
||||||
|
|
||||||
<setting id="streamMusic" type="bool" label="30510" default="false" visible="false" subsetting="true"/> <!-- Direct stream Music library -->
|
<setting id="streamMusic" type="bool" label="30510" default="false" visible="false" subsetting="true"/> <!-- Direct stream Music library -->
|
||||||
<setting type="lsep" label="30523" visible="false"/> <!-- Music metadata options -->
|
<setting type="lsep" label="30523" visible="false"/> <!-- Music metadata options -->
|
||||||
|
@ -81,6 +68,18 @@
|
||||||
<setting id="emby_pathverified" type="bool" default="false" visible="false" /> <!-- If 'false': one single warning message pops up if PKC cannot verify direct paths -->
|
<setting id="emby_pathverified" type="bool" default="false" visible="false" /> <!-- If 'false': one single warning message pops up if PKC cannot verify direct paths -->
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
<category label="39057"><!-- Customize Paths -->
|
||||||
|
<setting type="lsep" label="39056" /><!-- Used by Sync and to attempt to direct play -->
|
||||||
|
<setting id="replaceSMB" type="bool" label="39034" default="true" /> <!-- replace all Plex paths with SMB paths -->
|
||||||
|
<setting id="remapSMB" type="bool" label="39035" default="false" /> <!-- replace Plex paths /volume1/media or \\myserver\media with a custom SMB path smb://NAS/mystuff -->
|
||||||
|
<setting id="remapSMBmovieOrg" type="text" label="39037" default="" visible="eq(-1,true)"/> <!-- Original Plex MOVIE path to replace -->
|
||||||
|
<setting id="remapSMBmovieNew" type="text" label="39038" default="smb://" visible="eq(-2,true)"/> <!-- Replace Plex MOVIE with: -->
|
||||||
|
<setting id="remapSMBtvOrg" type="text" label="39039" default="" visible="eq(-3,true)"/> <!-- Original Plex TV SHOWS path to replace: -->
|
||||||
|
<setting id="remapSMBtvNew" type="text" label="39040" default="smb://" visible="eq(-4,true)"/> <!-- Replace Plex TV SHOWS with: -->
|
||||||
|
<setting id="remapSMBmusicOrg" type="text" label="39041" default="" visible="eq(-5,true)"/> <!-- Original Plex MUSIC path to replace: -->
|
||||||
|
<setting id="remapSMBmusicNew" type="text" label="39042" default="smb://" visible="eq(-6,true)"/> <!-- Replace Plex MUSIC with: -->
|
||||||
|
</category>
|
||||||
|
|
||||||
<category label="30516"><!-- Playback -->
|
<category label="30516"><!-- Playback -->
|
||||||
<setting type="sep" />
|
<setting type="sep" />
|
||||||
<setting id="enableCinema" type="bool" label="30518" default="true" />
|
<setting id="enableCinema" type="bool" label="30518" default="true" />
|
||||||
|
@ -92,15 +91,16 @@
|
||||||
<setting id="deleteMovies" type="bool" label="30116" visible="eq(-2,true)" default="false" subsetting="true" />
|
<setting id="deleteMovies" type="bool" label="30116" visible="eq(-2,true)" default="false" subsetting="true" />
|
||||||
<setting id="resumeJumpBack" type="slider" label="30521" default="10" range="0,1,120" option="int" />
|
<setting id="resumeJumpBack" type="slider" label="30521" default="10" range="0,1,120" option="int" />
|
||||||
<setting type="sep" />
|
<setting type="sep" />
|
||||||
<setting id="playFromStream" type="bool" label="30002" default="false" />
|
<setting id="playType" type="enum" label="30002" values="Direct Play (default)|Direct Stream|Force Transcode" default="0" />
|
||||||
<setting id="transcoderVideoQualities" type="enum" label="30160" values="420x420, 320Kbps|576x320, 720Kbps|720x480, 1.5Mbps|1024x768, 2Mbps|1280x720, 3Mbps|1280x720, 4Mbps|1920x1080, 8Mbps|1920x1080, 10Mbps|1920x1080, 12Mbps|1920x1080, 20Mbps|1920x1080, 40Mbps" visible="eq(-1,true)" default="11" />
|
<setting id="transcoderVideoQualities" type="enum" label="30160" values="420x420, 320Kbps|576x320, 720Kbps|720x480, 1.5Mbps|1024x768, 2Mbps|1280x720, 3Mbps|1280x720, 4Mbps|1920x1080, 8Mbps|1920x1080, 10Mbps|1920x1080, 12Mbps|1920x1080, 20Mbps|1920x1080, 40Mbps" default="11" />
|
||||||
<setting id="audioBoost" type="slider" label="39001" default="0" range="0,10,100" option="int"/>
|
|
||||||
<setting id="transcodeH265" type="enum" label="30522" default="0" values="Disabled (default)|480p (and higher)|720p (and higher)|1080p" />
|
<setting id="transcodeH265" type="enum" label="30522" default="0" values="Disabled (default)|480p (and higher)|720p (and higher)|1080p" />
|
||||||
|
<setting id="audioBoost" type="slider" label="39001" default="0" range="0,10,100" option="int"/>
|
||||||
<setting id="subtitleSize" label="39002" type="slider" option="int" range="0,30,300" default="100" />
|
<setting id="subtitleSize" label="39002" type="slider" option="int" range="0,30,300" default="100" />
|
||||||
<setting id="markPlayed" type="number" visible="false" default="95" />
|
<setting id="markPlayed" type="number" visible="false" default="95" />
|
||||||
<setting id="failedCount" type="number" visible="false" default="0" />
|
<setting id="failedCount" type="number" visible="false" default="0" />
|
||||||
<setting id="networkCreds" type="text" visible="false" default="" />
|
<setting id="networkCreds" type="text" visible="false" default="" />
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<category label="30235" visible="false">
|
<category label="30235" visible="false">
|
||||||
<setting id="enableCoverArt" type="bool" label="30157" default="true" visible="false"/>
|
<setting id="enableCoverArt" type="bool" label="30157" default="true" visible="false"/>
|
||||||
|
@ -113,8 +113,16 @@
|
||||||
<setting id="newmusictime" type="number" label="30533" visible="false" default="2" option="int" subsetting="true" />
|
<setting id="newmusictime" type="number" label="30533" visible="false" default="2" option="int" subsetting="true" />
|
||||||
</category>
|
</category>
|
||||||
-->
|
-->
|
||||||
|
<category label="Plex Companion">
|
||||||
|
<setting type="lsep" label="39008" />
|
||||||
|
<setting id="plexCompanion" label="39004" type="bool" default="true" />
|
||||||
|
<setting id="deviceNameOpt" label="30504" type="bool" default="false" />
|
||||||
|
<setting id="deviceName" label="30016" type="text" visible="eq(-1,true)" default="Kodi" />
|
||||||
|
<setting id="companionPort" label="39005" type="number" default="3005" option="int" visible="eq(-3,true)"/>
|
||||||
|
</category>
|
||||||
|
|
||||||
<category label="39045"><!-- Appearance Tweaks -->
|
<category label="39045"><!-- Appearance Tweaks -->
|
||||||
|
<setting id="connectMsg" type="bool" label="30249" default="true" />
|
||||||
<setting type="lsep" label="39046" />
|
<setting type="lsep" label="39046" />
|
||||||
<setting id="OnDeckTvAppendShow" type="bool" label="39047" default="false" /><!--On Deck view: Append show title to episode-->
|
<setting id="OnDeckTvAppendShow" type="bool" label="39047" default="false" /><!--On Deck view: Append show title to episode-->
|
||||||
<setting id="OnDeckTvAppendSeason" type="bool" label="39048" default="false" /><!--On Deck view: Append season number to episode-->
|
<setting id="OnDeckTvAppendSeason" type="bool" label="39048" default="false" /><!--On Deck view: Append season number to episode-->
|
||||||
|
@ -123,7 +131,6 @@
|
||||||
<category label="30022"><!-- Advanced -->
|
<category label="30022"><!-- Advanced -->
|
||||||
<setting id="logLevel" type="enum" label="30004" values="Disabled|Info|Debug" default="1" />
|
<setting id="logLevel" type="enum" label="30004" values="Disabled|Info|Debug" default="1" />
|
||||||
<setting id="startupDelay" type="number" label="30529" default="0" option="int" />
|
<setting id="startupDelay" type="number" label="30529" default="0" option="int" />
|
||||||
<setting id="connectMsg" type="bool" label="30249" default="true" />
|
|
||||||
<setting label="39018" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=repair)" option="close" /> <!-- Repair local database (force update all content) -->
|
<setting label="39018" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=repair)" option="close" /> <!-- Repair local database (force update all content) -->
|
||||||
<setting label="39020" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=texturecache)" option="close" /> <!-- Cache all images to Kodi texture cache -->
|
<setting label="39020" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect/?mode=texturecache)" option="close" /> <!-- Cache all images to Kodi texture cache -->
|
||||||
<setting label="30535" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect?mode=deviceid)" /><!-- Reset device id uuid -->
|
<setting label="30535" type="action" action="RunPlugin(plugin://plugin.video.plexkodiconnect?mode=deviceid)" /><!-- Reset device id uuid -->
|
||||||
|
|
Loading…
Reference in a new issue