Direct playing movie works
This commit is contained in:
parent
681e57b350
commit
bc65b6082d
6 changed files with 239 additions and 129 deletions
|
@ -41,7 +41,6 @@ import xbmc
|
|||
|
||||
import struct
|
||||
import time
|
||||
import urllib
|
||||
import urllib2
|
||||
import httplib
|
||||
import socket
|
||||
|
@ -52,6 +51,7 @@ import Queue
|
|||
import traceback
|
||||
|
||||
import re
|
||||
import json
|
||||
|
||||
try:
|
||||
import xml.etree.cElementTree as etree
|
||||
|
@ -87,6 +87,12 @@ class PlexAPI():
|
|||
self.deviceName = client.getDeviceName()
|
||||
self.plexversion = client.getVersion()
|
||||
self.platform = client.getPlatform()
|
||||
self.userId = utils.window('emby_currUser')
|
||||
self.token = utils.window('emby_accessToken%s' % self.userId)
|
||||
self.server = utils.window('emby_server%s' % self.userId)
|
||||
self.plexLogin = utils.settings('plexLogin')
|
||||
self.plexToken = utils.settings('plexToken')
|
||||
self.machineIdentifier = utils.window('plex_machineIdentifier')
|
||||
|
||||
self.doUtils = downloadutils.DownloadUtils()
|
||||
|
||||
|
@ -167,6 +173,7 @@ class PlexAPI():
|
|||
headerOptions={'X-Plex-Token': token}
|
||||
)
|
||||
self.logMsg("Response was: %s" % r, 2)
|
||||
# List of exception returns, when connection failed
|
||||
exceptionlist = [
|
||||
'',
|
||||
401
|
||||
|
@ -596,22 +603,30 @@ class PlexAPI():
|
|||
requests. An authentication option is NOT yet added.
|
||||
|
||||
Inputs:
|
||||
JSON=True will enforce a JSON answer
|
||||
options: dictionary of options that will override the
|
||||
standard header options otherwise set.
|
||||
JSON=True will enforce a JSON answer, never mind any options
|
||||
Output:
|
||||
header dictionary
|
||||
"""
|
||||
# Get addon infos
|
||||
xargs = dict()
|
||||
xargs['User-agent'] = self.addonName
|
||||
xargs['X-Plex-Device'] = self.deviceName
|
||||
# xargs['X-Plex-Model'] = ''
|
||||
xargs['X-Plex-Platform'] = self.platform
|
||||
xargs['X-Plex-Client-Platform'] = self.platform
|
||||
xargs['X-Plex-Product'] = self.addonName
|
||||
xargs['X-Plex-Version'] = self.plexversion
|
||||
xargs['X-Plex-Client-Identifier'] = self.clientId
|
||||
xargs = {
|
||||
'User-agent': self.addonName,
|
||||
'X-Plex-Device': self.deviceName,
|
||||
'X-Plex-Platform': self.platform,
|
||||
'X-Plex-Client-Platform': self.platform,
|
||||
'X-Plex-Product': self.addonName,
|
||||
'X-Plex-Version': self.plexversion,
|
||||
'X-Plex-Client-Identifier': self.clientId,
|
||||
'machineIdentifier': self.machineIdentifier,
|
||||
'Accept': 'application/xml'
|
||||
}
|
||||
|
||||
try:
|
||||
xargs['X-Plex-Token'] = self.token
|
||||
except NameError:
|
||||
# no token needed/saved yet
|
||||
pass
|
||||
if JSON:
|
||||
xargs['Accept'] = 'application/json'
|
||||
if options:
|
||||
|
@ -821,31 +836,6 @@ class PlexAPI():
|
|||
dprint(__name__, 1, "====== MyPlex sign out XML finished ======")
|
||||
dprint(__name__, 0, 'MyPlex Sign Out done')
|
||||
|
||||
def UserAccessRestricted(self, username):
|
||||
"""
|
||||
Returns True if the user's access is restricted (parental restrictions)
|
||||
False otherwise.
|
||||
|
||||
Returns False also if access cannot be checked because plex.tv cannot
|
||||
be reached.
|
||||
"""
|
||||
plexToken = utils.settings('plexToken')
|
||||
users = self.MyPlexListHomeUsers(plexToken)
|
||||
# If an error is encountered, set to False
|
||||
if not users:
|
||||
self.logMsg("Could not check user access restrictions.", 1)
|
||||
self.logMsg("Setting restrictions to False.", 1)
|
||||
return False
|
||||
for user in users:
|
||||
if username in user['title']:
|
||||
restricted = user['restricted']
|
||||
if restricted == '1':
|
||||
restricted = True
|
||||
else:
|
||||
restricted = False
|
||||
self.logMsg("Successfully checked user parental access for %s: restricted access is set to %s" % (username, restricted), 1)
|
||||
return restricted
|
||||
|
||||
def GetUserArtworkURL(self, username):
|
||||
"""
|
||||
Returns the URL for the user's Avatar. Or False if something went
|
||||
|
@ -877,8 +867,8 @@ class PlexAPI():
|
|||
Will return empty strings if failed.
|
||||
"""
|
||||
string = self.__language__
|
||||
plexToken = utils.settings('plexToken')
|
||||
plexLogin = utils.settings('plexLogin')
|
||||
plexLogin = self.plexLogin
|
||||
plexToken = self.plexToken
|
||||
self.logMsg("Getting user list.", 1)
|
||||
# Get list of Plex home users
|
||||
users = self.MyPlexListHomeUsers(plexToken)
|
||||
|
@ -1021,54 +1011,6 @@ class PlexAPI():
|
|||
users.append(user.attrib)
|
||||
return users
|
||||
|
||||
def getTranscodeVideoPath(self, path, AuthToken, options, action, quality, subtitle, audio, partIndex):
|
||||
"""
|
||||
Transcode Video support
|
||||
|
||||
parameters:
|
||||
path
|
||||
AuthToken
|
||||
options - dict() of PlexConnect-options as received from aTV
|
||||
action - transcoder action: Auto, Directplay, Transcode
|
||||
quality - (resolution, quality, bitrate)
|
||||
subtitle - {'selected', 'dontBurnIn', 'size'}
|
||||
audio - {'boost'}
|
||||
result:
|
||||
final path to pull in PMS transcoder
|
||||
"""
|
||||
UDID = options['PlexConnectUDID']
|
||||
|
||||
transcodePath = '/video/:/transcode/universal/start.m3u8?'
|
||||
|
||||
vRes = quality[0]
|
||||
vQ = quality[1]
|
||||
mVB = quality[2]
|
||||
dprint(__name__, 1, "Setting transcode quality Res:{0} Q:{1} {2}Mbps", vRes, vQ, mVB)
|
||||
dprint(__name__, 1, "Subtitle: selected {0}, dontBurnIn {1}, size {2}", subtitle['selected'], subtitle['dontBurnIn'], subtitle['size'])
|
||||
dprint(__name__, 1, "Audio: boost {0}", audio['boost'])
|
||||
|
||||
args = dict()
|
||||
args['session'] = UDID
|
||||
args['protocol'] = 'hls'
|
||||
args['videoResolution'] = vRes
|
||||
args['maxVideoBitrate'] = mVB
|
||||
args['videoQuality'] = vQ
|
||||
args['directStream'] = '0' if action=='Transcode' else '1'
|
||||
# 'directPlay' - handled by the client in MEDIARUL()
|
||||
args['subtitleSize'] = subtitle['size']
|
||||
args['skipSubtitles'] = subtitle['dontBurnIn'] #'1' # shut off PMS subtitles. Todo: skip only for aTV native/SRT (or other supported)
|
||||
args['audioBoost'] = audio['boost']
|
||||
args['fastSeek'] = '1'
|
||||
args['path'] = path
|
||||
args['partIndex'] = partIndex
|
||||
|
||||
xargs = getXArgsDeviceInfo(options)
|
||||
xargs['X-Plex-Client-Capabilities'] = "protocols=http-live-streaming,http-mp4-streaming,http-streaming-video,http-streaming-video-720p,http-mp4-video,http-mp4-video-720p;videoDecoders=h264{profile:high&resolution:1080&level:41};audioDecoders=mp3,aac{bitrate:160000}"
|
||||
if not AuthToken=='':
|
||||
xargs['X-Plex-Token'] = AuthToken
|
||||
|
||||
return transcodePath + urlencode(args) + '&' + urlencode(xargs)
|
||||
|
||||
def getDirectVideoPath(self, key, AuthToken):
|
||||
"""
|
||||
Direct Video Play support
|
||||
|
@ -1309,7 +1251,7 @@ class PlexAPI():
|
|||
'includePopularLeaves': 1,
|
||||
'includeConcerts': 1
|
||||
}
|
||||
url = url + '?' + urllib.urlencode(arguments)
|
||||
url = url + '?' + urlencode(arguments)
|
||||
headerOptions = {'Accept': 'application/xml'}
|
||||
xml = self.doUtils.downloadUrl(url, headerOptions=headerOptions)
|
||||
if not xml:
|
||||
|
@ -1324,6 +1266,7 @@ class API():
|
|||
self.item = item
|
||||
self.clientinfo = clientinfo.ClientInfo()
|
||||
self.addonName = self.clientinfo.getAddonName()
|
||||
self.clientId = self.clientinfo.getDeviceId()
|
||||
self.userId = utils.window('emby_currUser')
|
||||
self.server = utils.window('emby_server%s' % self.userId)
|
||||
self.token = utils.window('emby_accessToken%s' % self.userId)
|
||||
|
@ -1771,7 +1714,7 @@ class API():
|
|||
token = {'X-Plex-Token': self.token}
|
||||
xargs = PlexAPI().getXArgsDeviceInfo(options=token)
|
||||
xargs.update(arguments)
|
||||
url = "%s?%s" % (url, urllib.urlencode(xargs))
|
||||
url = "%s?%s" % (url, urlencode(xargs))
|
||||
return url
|
||||
|
||||
def getMediaStreams(self):
|
||||
|
@ -1939,5 +1882,141 @@ class API():
|
|||
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
|
||||
% (server, parentId, maxWidth, maxHeight, parentTag, customquery))
|
||||
allartworks['Primary'] = artwork
|
||||
|
||||
return allartworks
|
||||
|
||||
def getTranscodeVideoPath(self, action, quality={}, subtitle={}, audioboost=None, partIndex=None, options={}):
|
||||
"""
|
||||
Transcode Video support
|
||||
|
||||
Input:
|
||||
action 'Transcode' OR any other string
|
||||
quality: {'videoResolution': 'resolution',
|
||||
'videoQuality': 'quality',
|
||||
'maxVideoBitrate': 'bitrate'}
|
||||
subtitle {'selected', 'dontBurnIn', 'size'}
|
||||
audioboost Guess this takes an int as str
|
||||
partIndex No idea
|
||||
options dict() of PlexConnect-options as received from aTV
|
||||
Output:
|
||||
final path to pull in PMS transcoder
|
||||
"""
|
||||
# path to item
|
||||
transcodePath = self.server + \
|
||||
'/video/:/transcode/universal/start.m3u8?'
|
||||
|
||||
ID = self.getKey()
|
||||
path = self.server + '/library/metadata/' + ID
|
||||
args = {
|
||||
'session': self.clientId,
|
||||
'protocol': 'hls',
|
||||
'fastSeek': '1',
|
||||
'path': path,
|
||||
'X-Plex-Client-Capabilities': "protocols=http-live-streaming,"
|
||||
"http-streaming-video,"
|
||||
"http-streaming-video-720p,"
|
||||
"http-streaming-video-1080p,"
|
||||
"http-mp4-streaming,"
|
||||
"http-mp4-video,"
|
||||
"http-mp4-video-720p,"
|
||||
"http-mp4-video-1080p;"
|
||||
"videoDecoders="
|
||||
"h264{profile:high&resolution:1080&level:51};"
|
||||
"audioDecoders="
|
||||
"mp3,"
|
||||
"aac{bitrate:160000},"
|
||||
"ac3{channels:6},"
|
||||
"dts{channels:6}"
|
||||
# 'partIndex': partIndex What do we do with this?!?
|
||||
}
|
||||
# All the settings
|
||||
if subtitle:
|
||||
args_update = {
|
||||
'subtitleSize': subtitle['size'],
|
||||
'skipSubtitles': subtitle['dontBurnIn'] # '1': shut off PMS
|
||||
}
|
||||
args.update(args_update)
|
||||
self.logMsg(
|
||||
"Subtitle: selected %s, dontBurnIn %s, size %s"
|
||||
% (subtitle['selected'], subtitle['dontBurnIn'],
|
||||
subtitle['size']),
|
||||
1
|
||||
)
|
||||
if audioboost:
|
||||
args_update = {
|
||||
'audioBoost': audioboost
|
||||
}
|
||||
args.update(args_update)
|
||||
self.logMsg("audioboost: %s" % audioboost, 1)
|
||||
if action == 'Transcode':
|
||||
# Possible Plex settings:
|
||||
# 'videoResolution': vRes,
|
||||
# 'maxVideoBitrate': mVB,
|
||||
# : vQ
|
||||
self.logMsg("Setting transcode quality to: %s" % quality, 1)
|
||||
args['directStream'] = '0'
|
||||
args.update(quality)
|
||||
else:
|
||||
args['directStream'] = '1'
|
||||
|
||||
xargs = PlexAPI().getXArgsDeviceInfo(options=options)
|
||||
return transcodePath + urlencode(args) + '&' + urlencode(xargs)
|
||||
|
||||
def adjustResume(self, resume_seconds):
|
||||
|
||||
resume = 0
|
||||
if resume_seconds:
|
||||
resume = round(float(resume_seconds), 6)
|
||||
jumpback = int(utils.settings('resumeJumpBack'))
|
||||
if resume > jumpback:
|
||||
# To avoid negative bookmark
|
||||
resume = resume - jumpback
|
||||
|
||||
return resume
|
||||
|
||||
def returnParts(self):
|
||||
"""
|
||||
TODO
|
||||
"""
|
||||
item = self.item
|
||||
PartCount = 0
|
||||
# Run through parts
|
||||
for child in item[0][0]:
|
||||
if child.tag == 'Part':
|
||||
PartCount += PartCount
|
||||
|
||||
def externalSubs(self, playurl):
|
||||
|
||||
externalsubs = []
|
||||
mapping = {}
|
||||
|
||||
item = self.item
|
||||
itemid = self.getKey()
|
||||
try:
|
||||
mediastreams = item[0][0][0]
|
||||
except (TypeError, KeyError, IndexError):
|
||||
return
|
||||
|
||||
kodiindex = 0
|
||||
for stream in mediastreams:
|
||||
|
||||
# index = stream['Index']
|
||||
index = stream.attrib['id']
|
||||
# Since Emby returns all possible tracks together, have to pull only external subtitles.
|
||||
# IsTextSubtitleStream if true, is available to download from emby.
|
||||
if (stream.attrib['streamType'] == "3" and
|
||||
stream.attrib['format']):
|
||||
|
||||
# Direct stream
|
||||
# PLEX: TODO!!
|
||||
url = ("%s/Videos/%s/%s/Subtitles/%s/Stream.srt"
|
||||
% (self.server, itemid, itemid, index))
|
||||
|
||||
# map external subtitles for mapping
|
||||
mapping[kodiindex] = index
|
||||
externalsubs.append(url)
|
||||
kodiindex += 1
|
||||
|
||||
mapping = json.dumps(mapping)
|
||||
utils.window('emby_%s.indexMapping' % playurl, value=mapping)
|
||||
|
||||
return externalsubs
|
||||
|
|
|
@ -25,13 +25,14 @@ import playbackutils as pbutils
|
|||
import playutils
|
||||
import api
|
||||
|
||||
import PlexAPI
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
||||
def doPlayback(itemid, dbid):
|
||||
|
||||
emby = embyserver.Read_EmbyServer()
|
||||
item = emby.getItem(itemid)
|
||||
item = PlexAPI.PlexAPI().GetPlexMetadata(itemid) # Now xml, not json!
|
||||
pbutils.PlaybackUtils(item).play(itemid, dbid)
|
||||
|
||||
##### DO RESET AUTH #####
|
||||
|
|
|
@ -360,7 +360,7 @@ class Movies(Items):
|
|||
utils.window('emby_pathverified', value="true")
|
||||
else:
|
||||
# Set plugin path and media flags using real filename
|
||||
path = "plugin://plugin.video.plexkodiconnect.movies/"
|
||||
path = "plugin://plugin.video.emby.movies/"
|
||||
params = {
|
||||
|
||||
'filename': filename.encode('utf-8'),
|
||||
|
@ -704,7 +704,7 @@ class HomeVideos(Items):
|
|||
utils.window('emby_pathverified', value="true")
|
||||
else:
|
||||
# Set plugin path and media flags using real filename
|
||||
path = "plugin://plugin.video.plexkodiconnect.movies/"
|
||||
path = "plugin://plugin.video.emby.movies/"
|
||||
params = {
|
||||
|
||||
'filename': filename.encode('utf-8'),
|
||||
|
|
|
@ -18,6 +18,8 @@ import playlist
|
|||
import read_embyserver as embyserver
|
||||
import utils
|
||||
|
||||
import PlexAPI
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
||||
|
@ -27,7 +29,7 @@ class PlaybackUtils():
|
|||
def __init__(self, item):
|
||||
|
||||
self.item = item
|
||||
self.API = api.API(self.item)
|
||||
self.API = PlexAPI.API(self.item)
|
||||
|
||||
self.clientInfo = clientinfo.ClientInfo()
|
||||
self.addonName = self.clientInfo.getAddonName()
|
||||
|
@ -107,8 +109,9 @@ class PlaybackUtils():
|
|||
currentPosition += 1
|
||||
|
||||
############### -- CHECK FOR INTROS ################
|
||||
|
||||
if utils.settings('enableCinema') == "true" and not seektime:
|
||||
# PLEX: todo. Seems like Plex returns a playlist WITH trailers
|
||||
# if utils.settings('enableCinema') == "true" and not seektime:
|
||||
if False:
|
||||
# if we have any play them when the movie/show is not being resumed
|
||||
url = "{server}/emby/Users/{UserId}/Items/%s/Intros?format=json" % itemid
|
||||
intros = doUtils.downloadUrl(url)
|
||||
|
@ -145,14 +148,17 @@ class PlaybackUtils():
|
|||
# Extend our current playlist with the actual item to play
|
||||
# only if there's no playlist first
|
||||
self.logMsg("Adding main item to playlist.", 1)
|
||||
self.pl.addtoPlaylist(dbid, item['Type'].lower())
|
||||
# self.pl.addtoPlaylist(dbid, item['Type'].lower())
|
||||
self.pl.addtoPlaylist(dbid, item[0].attrib['type'].lower())
|
||||
|
||||
# Ensure that additional parts are played after the main item
|
||||
currentPosition += 1
|
||||
|
||||
############### -- CHECK FOR ADDITIONAL PARTS ################
|
||||
|
||||
if item.get('PartCount'):
|
||||
# Plex: TODO. Guess parts are sent back like trailers.
|
||||
# if item.get('PartCount'):
|
||||
if False:
|
||||
# Only add to the playlist after intros have played
|
||||
partcount = item['PartCount']
|
||||
url = "{server}/emby/Videos/%s/AdditionalParts?format=json" % itemid
|
||||
|
@ -215,11 +221,14 @@ class PlaybackUtils():
|
|||
def setProperties(self, playurl, listitem):
|
||||
# Set all properties necessary for plugin path playback
|
||||
item = self.item
|
||||
itemid = item['Id']
|
||||
itemtype = item['Type']
|
||||
# itemid = item['Id']
|
||||
itemid = self.API.getKey()
|
||||
# itemtype = item['Type']
|
||||
itemtype = item[0].attrib['type']
|
||||
resume, runtime = self.API.getRuntime()
|
||||
|
||||
embyitem = "emby_%s" % playurl
|
||||
utils.window('%s.runtime' % embyitem, value=str(item.get('RunTimeTicks')))
|
||||
utils.window('%s.runtime' % embyitem, value=str(runtime))
|
||||
utils.window('%s.type' % embyitem, value=itemtype)
|
||||
utils.window('%s.itemid' % embyitem, value=itemid)
|
||||
|
||||
|
@ -231,7 +240,8 @@ class PlaybackUtils():
|
|||
# Append external subtitles to stream
|
||||
playmethod = utils.window('%s.playmethod' % embyitem)
|
||||
# Only for direct play and direct stream
|
||||
subtitles = self.externalSubs(playurl)
|
||||
# subtitles = self.externalSubs(playurl)
|
||||
subtitles = self.API.externalSubs(playurl)
|
||||
if playmethod in ("DirectStream", "Transcode"):
|
||||
# Direct play automatically appends external
|
||||
listitem.setSubtitles(subtitles)
|
||||
|
@ -278,7 +288,8 @@ class PlaybackUtils():
|
|||
item = self.item
|
||||
artwork = self.artwork
|
||||
|
||||
allartwork = artwork.getAllArtwork(item, parentInfo=True)
|
||||
# allartwork = artwork.getAllArtwork(item, parentInfo=True)
|
||||
allartwork = self.API.getAllArtwork(parentInfo=True)
|
||||
# Set artwork for listitem
|
||||
arttypes = {
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import xbmcvfs
|
|||
import clientinfo
|
||||
import utils
|
||||
|
||||
import PlexAPI
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
||||
|
@ -24,6 +26,9 @@ class PlayUtils():
|
|||
|
||||
self.userid = utils.window('emby_currUser')
|
||||
self.server = utils.window('emby_server%s' % self.userid)
|
||||
self.machineIdentifier = utils.window('plex_machineIdentifier')
|
||||
|
||||
self.plx = PlexAPI.API(item)
|
||||
|
||||
def logMsg(self, msg, lvl=1):
|
||||
|
||||
|
@ -36,34 +41,39 @@ class PlayUtils():
|
|||
item = self.item
|
||||
playurl = None
|
||||
|
||||
if item['MediaSources'][0]['Protocol'] == "Http":
|
||||
# Only play as http
|
||||
self.logMsg("File protocol is http.", 1)
|
||||
playurl = self.httpPlay()
|
||||
utils.window('emby_%s.playmethod' % playurl, value="DirectStream")
|
||||
# if item['MediaSources'][0]['Protocol'] == "Http":
|
||||
# # Only play as http
|
||||
# self.logMsg("File protocol is http.", 1)
|
||||
# playurl = self.httpPlay()
|
||||
# utils.window('emby_%s.playmethod' % playurl, value="DirectStream")
|
||||
|
||||
elif self.isDirectPlay():
|
||||
# elif self.isDirectPlay():
|
||||
|
||||
self.logMsg("File is direct playing.", 1)
|
||||
playurl = self.directPlay()
|
||||
playurl = playurl.encode('utf-8')
|
||||
# Set playmethod property
|
||||
utils.window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
||||
# self.logMsg("File is direct playing.", 1)
|
||||
# playurl = self.directPlay()
|
||||
# playurl = playurl.encode('utf-8')
|
||||
# # Set playmethod property
|
||||
# utils.window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
||||
|
||||
elif self.isDirectStream():
|
||||
if self.isDirectStream():
|
||||
|
||||
self.logMsg("File is direct streaming.", 1)
|
||||
playurl = self.directStream()
|
||||
playurl = self.plx.getTranscodeVideoPath('direct')
|
||||
# Set playmethod property
|
||||
utils.window('emby_%s.playmethod' % playurl, value="DirectStream")
|
||||
|
||||
elif self.isTranscoding():
|
||||
|
||||
self.logMsg("File is transcoding.", 1)
|
||||
playurl = self.transcoding()
|
||||
quality = {
|
||||
'bitrate': self.getBitrate()
|
||||
}
|
||||
playurl = self.plx.getTranscodeVideoPath(
|
||||
'Transcode', quality=quality
|
||||
)
|
||||
# Set playmethod property
|
||||
utils.window('emby_%s.playmethod' % playurl, value="Transcode")
|
||||
|
||||
self.logMsg("The playurl is: %s" % playurl, 1)
|
||||
return playurl
|
||||
|
||||
def httpPlay(self):
|
||||
|
@ -192,13 +202,16 @@ class PlayUtils():
|
|||
item = self.item
|
||||
|
||||
if (utils.settings('transcodeH265') == "true" and
|
||||
item['MediaSources'][0]['Name'].startswith("1080P/H265")):
|
||||
item[0][0].attrib('videoCodec').startswith("h265") and
|
||||
item[0][0].attrib('videoResolution').startswith("1080")):
|
||||
# Avoid H265 1080p
|
||||
self.logMsg("Option to transcode 1080P/H265 enabled.", 1)
|
||||
return False
|
||||
|
||||
# Requirement: BitRate, supported encoding
|
||||
canDirectStream = item['MediaSources'][0]['SupportsDirectStream']
|
||||
# canDirectStream = item['MediaSources'][0]['SupportsDirectStream']
|
||||
# Plex: always able?!?
|
||||
canDirectStream = True
|
||||
# Make sure the server supports it
|
||||
if not canDirectStream:
|
||||
return False
|
||||
|
@ -215,16 +228,18 @@ class PlayUtils():
|
|||
item = self.item
|
||||
server = self.server
|
||||
|
||||
itemid = item['Id']
|
||||
type = item['Type']
|
||||
itemid = self.plx.getKey()
|
||||
type = item[0].tag
|
||||
|
||||
if 'Path' in item and item['Path'].endswith('.strm'):
|
||||
# Allow strm loading when direct streaming
|
||||
playurl = self.directPlay()
|
||||
elif type == "Audio":
|
||||
# if 'Path' in item and item['Path'].endswith('.strm'):
|
||||
# # Allow strm loading when direct streaming
|
||||
# playurl = self.directPlay()
|
||||
if type == "Audio":
|
||||
playurl = "%s/emby/Audio/%s/stream.mp3" % (server, itemid)
|
||||
else:
|
||||
playurl = "%s/emby/Videos/%s/stream?static=true" % (server, itemid)
|
||||
playurl = "{server}/player/playback/playMedia?key=%2Flibrary%2Fmetadata%2F%s&offset=0&X-Plex-Client-Identifier={clientId}&machineIdentifier={SERVER ID}&address={SERVER IP}&port={SERVER PORT}&protocol=http&path=http%3A%2F%2F{SERVER IP}%3A{SERVER PORT}%2Flibrary%2Fmetadata%2F{MEDIA ID}" % (itemid)
|
||||
playurl = self.plx.replaceURLtags()
|
||||
|
||||
return playurl
|
||||
|
||||
|
@ -233,7 +248,7 @@ class PlayUtils():
|
|||
settings = self.getBitrate()*1000
|
||||
|
||||
try:
|
||||
sourceBitrate = int(self.item['MediaSources'][0]['Bitrate'])
|
||||
sourceBitrate = int(self.item[0][0].attrib['bitrate'])
|
||||
except (KeyError, TypeError):
|
||||
self.logMsg("Bitrate value is missing.", 1)
|
||||
else:
|
||||
|
@ -245,7 +260,8 @@ class PlayUtils():
|
|||
return True
|
||||
|
||||
def isTranscoding(self):
|
||||
|
||||
# I hope Plex transcodes everything
|
||||
return True
|
||||
item = self.item
|
||||
|
||||
canTranscode = item['MediaSources'][0]['SupportsTranscoding']
|
||||
|
|
|
@ -234,12 +234,13 @@ class UserClient(threading.Thread):
|
|||
self.currUserId = userId
|
||||
self.currServer = self.getServer()
|
||||
self.currToken = self.getToken()
|
||||
self.machineIdentifier = self.getServerId()
|
||||
self.ssl = self.getSSLverify()
|
||||
self.sslcert = self.getSSL()
|
||||
|
||||
# Test the validity of current token
|
||||
if authenticated == False:
|
||||
url = "%s/emby/Users/%s?format=json" % (self.currServer, userId)
|
||||
url = "%s/clients" % (self.currServer)
|
||||
utils.window('emby_currUser', value=userId)
|
||||
utils.window('emby_accessToken%s' % userId, value=self.currToken)
|
||||
result = doUtils.downloadUrl(url)
|
||||
|
@ -254,6 +255,7 @@ class UserClient(threading.Thread):
|
|||
utils.window('emby_accessToken%s' % userId, value=self.currToken)
|
||||
utils.window('emby_server%s' % userId, value=self.currServer)
|
||||
utils.window('emby_server_%s' % userId, value=self.getServer(prefix=False))
|
||||
utils.window('plex_machineIdentifier', value=self.machineIdentifier)
|
||||
|
||||
# Set DownloadUtils values
|
||||
doUtils.setUsername(username)
|
||||
|
@ -279,6 +281,7 @@ class UserClient(threading.Thread):
|
|||
|
||||
username = self.getUsername()
|
||||
server = self.getServer()
|
||||
machineIdentifier = self.getServerId()
|
||||
|
||||
# If there's no settings.xml
|
||||
if not hasSettings:
|
||||
|
|
Loading…
Reference in a new issue