Movie with multiple parts now working
This commit is contained in:
parent
1970e00b16
commit
93ad4ae0cb
3 changed files with 67 additions and 26 deletions
|
@ -1272,6 +1272,8 @@ class API():
|
||||||
self.item = item
|
self.item = item
|
||||||
# which child in the XML response shall we look at?
|
# which child in the XML response shall we look at?
|
||||||
self.child = 0
|
self.child = 0
|
||||||
|
# which media part in the XML response shall we look at?
|
||||||
|
self.part = 0
|
||||||
self.clientinfo = clientinfo.ClientInfo()
|
self.clientinfo = clientinfo.ClientInfo()
|
||||||
self.addonName = self.clientinfo.getAddonName()
|
self.addonName = self.clientinfo.getAddonName()
|
||||||
self.clientId = self.clientinfo.getDeviceId()
|
self.clientId = self.clientinfo.getDeviceId()
|
||||||
|
@ -1287,15 +1289,28 @@ class API():
|
||||||
"""
|
"""
|
||||||
Which child in the XML response shall we look at and work with?
|
Which child in the XML response shall we look at and work with?
|
||||||
"""
|
"""
|
||||||
self.child = number
|
self.child = int(number)
|
||||||
self.logMsg("Set child number to %s" % number, 1)
|
self.logMsg("Set child number to %s" % number, 1)
|
||||||
|
|
||||||
def getChild(self):
|
def getChildNumber(self):
|
||||||
"""
|
"""
|
||||||
Returns the child in the XML response that we're currently looking at
|
Returns the child in the XML response that we're currently looking at
|
||||||
"""
|
"""
|
||||||
return self.child
|
return self.child
|
||||||
|
|
||||||
|
def setPartNumber(self, number=0):
|
||||||
|
"""
|
||||||
|
Sets the part number to work with (used to deal with Movie with several
|
||||||
|
parts).
|
||||||
|
"""
|
||||||
|
self.part = int(number)
|
||||||
|
|
||||||
|
def getPartNumber(self):
|
||||||
|
"""
|
||||||
|
Returns the current media part number we're dealing with.
|
||||||
|
"""
|
||||||
|
return self.part
|
||||||
|
|
||||||
def convert_date(self, stamp):
|
def convert_date(self, stamp):
|
||||||
"""
|
"""
|
||||||
convert_date(stamp) converts a Unix time stamp (seconds passed since
|
convert_date(stamp) converts a Unix time stamp (seconds passed since
|
||||||
|
@ -1630,9 +1645,10 @@ class API():
|
||||||
Output:
|
Output:
|
||||||
resume, runtime as floats. 0.0 if not found
|
resume, runtime as floats. 0.0 if not found
|
||||||
"""
|
"""
|
||||||
item = self.item
|
|
||||||
time_factor = 1.0 / 1000.0 # millisecond -> seconds
|
time_factor = 1.0 / 1000.0 # millisecond -> seconds
|
||||||
|
item = self.item
|
||||||
item = item[self.child].attrib
|
item = item[self.child].attrib
|
||||||
|
|
||||||
try:
|
try:
|
||||||
runtime = float(item['duration'])
|
runtime = float(item['duration'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -1970,29 +1986,36 @@ class API():
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
action 'Transcode' OR any other string
|
action 'Transcode' OR any other string
|
||||||
|
|
||||||
quality: {
|
quality: {
|
||||||
'videoResolution': 'resolution',
|
'videoResolution': 'resolution',
|
||||||
'videoQuality': 'quality',
|
'videoQuality': 'quality',
|
||||||
'maxVideoBitrate': 'bitrate'
|
'maxVideoBitrate': 'bitrate'
|
||||||
}
|
}
|
||||||
subtitle {'selected', 'dontBurnIn', 'size'}
|
subtitle {'selected', 'dontBurnIn', 'size'}
|
||||||
audioboost Guess this takes an int as str
|
audioboost e.g. 100
|
||||||
partIndex No idea
|
partIndex Index number of media part, starting with 0
|
||||||
options dict() of PlexConnect-options as received from aTV
|
options dict() of PlexConnect-options as received from aTV
|
||||||
Output:
|
Output:
|
||||||
final path to pull in PMS transcoder
|
final path to pull in PMS transcoder
|
||||||
|
|
||||||
|
TODO: mediaIndex
|
||||||
"""
|
"""
|
||||||
# path to item
|
# path to item
|
||||||
transcodePath = self.server + \
|
transcodePath = self.server + \
|
||||||
'/video/:/transcode/universal/start.m3u8?'
|
'/video/:/transcode/universal/start.m3u8?'
|
||||||
|
|
||||||
ID = self.getKey()
|
ID = self.getKey()
|
||||||
path = self.server + '/library/metadata/' + ID
|
if partIndex is not None:
|
||||||
|
path = self.server + '/library/metadata/' + ID
|
||||||
|
else:
|
||||||
|
path = self.item[self.child][0][self.part].attrib['key']
|
||||||
args = {
|
args = {
|
||||||
'session': self.clientId,
|
'session': self.clientId,
|
||||||
'protocol': 'hls',
|
'protocol': 'hls', # also seen: 'dash'
|
||||||
'fastSeek': '1',
|
'fastSeek': '1',
|
||||||
'path': path,
|
'path': path,
|
||||||
|
'mediaIndex': 0, # Probably refering to XML reply sheme
|
||||||
'X-Plex-Client-Capabilities': "protocols=http-live-streaming,"
|
'X-Plex-Client-Capabilities': "protocols=http-live-streaming,"
|
||||||
"http-streaming-video,"
|
"http-streaming-video,"
|
||||||
"http-streaming-video-720p,"
|
"http-streaming-video-720p,"
|
||||||
|
@ -2008,12 +2031,16 @@ class API():
|
||||||
"aac{bitrate:160000},"
|
"aac{bitrate:160000},"
|
||||||
"ac3{channels:6},"
|
"ac3{channels:6},"
|
||||||
"dts{channels:6}"
|
"dts{channels:6}"
|
||||||
# 'partIndex': partIndex What do we do with this?!?
|
# 'offset': 0 # Resume point
|
||||||
|
# 'directPlay': 0 # 1 if Kodi can also handle the container
|
||||||
}
|
}
|
||||||
# All the settings
|
# All the settings
|
||||||
|
if partIndex is not None:
|
||||||
|
args['partIndex'] = partIndex
|
||||||
if subtitle:
|
if subtitle:
|
||||||
args_update = {
|
args_update = {
|
||||||
'subtitleSize': subtitle['size'],
|
'subtitles': 'burn',
|
||||||
|
'subtitleSize': subtitle['size'], # E.g. 100
|
||||||
'skipSubtitles': subtitle['dontBurnIn'] # '1': shut off PMS
|
'skipSubtitles': subtitle['dontBurnIn'] # '1': shut off PMS
|
||||||
}
|
}
|
||||||
args.update(args_update)
|
args.update(args_update)
|
||||||
|
@ -2118,3 +2145,9 @@ class API():
|
||||||
if not xml:
|
if not xml:
|
||||||
self.logMsg("Error retrieving metadata for %s" % url, 1)
|
self.logMsg("Error retrieving metadata for %s" % url, 1)
|
||||||
return xml
|
return xml
|
||||||
|
|
||||||
|
def GetParts(self):
|
||||||
|
"""
|
||||||
|
Returns the parts of the specified video child in the XML response
|
||||||
|
"""
|
||||||
|
return self.item[self.child][0]
|
|
@ -123,7 +123,7 @@ class PlaybackUtils():
|
||||||
getTrailers = False
|
getTrailers = False
|
||||||
self.logMsg("Skip trailers.", 1)
|
self.logMsg("Skip trailers.", 1)
|
||||||
if getTrailers:
|
if getTrailers:
|
||||||
for i in range(0, playListSize):
|
for i in range(0, playListSize - 1):
|
||||||
# The server randomly returns intros, process them
|
# The server randomly returns intros, process them
|
||||||
# Set the child in XML Plex response to a trailer
|
# Set the child in XML Plex response to a trailer
|
||||||
API.setChildNumber(i)
|
API.setChildNumber(i)
|
||||||
|
@ -154,28 +154,28 @@ class PlaybackUtils():
|
||||||
currentPosition += 1
|
currentPosition += 1
|
||||||
|
|
||||||
############### -- CHECK FOR ADDITIONAL PARTS ################
|
############### -- CHECK FOR ADDITIONAL PARTS ################
|
||||||
|
parts = API.GetParts()
|
||||||
# Plex: TODO. Guess parts are sent back like trailers.
|
partcount = len(parts)
|
||||||
# if item.get('PartCount'):
|
if partcount > 1:
|
||||||
if False:
|
|
||||||
# Only add to the playlist after intros have played
|
# Only add to the playlist after intros have played
|
||||||
partcount = item['PartCount']
|
i = 0
|
||||||
url = "{server}/emby/Videos/%s/AdditionalParts?format=json" % itemid
|
for part in parts:
|
||||||
parts = doUtils.downloadUrl(url)
|
API.setPartNumber(i)
|
||||||
for part in parts['Items']:
|
|
||||||
|
|
||||||
additionalListItem = xbmcgui.ListItem()
|
additionalListItem = xbmcgui.ListItem()
|
||||||
additionalPlayurl = putils.PlayUtils(part).getPlayUrl()
|
additionalPlayurl = playutils.getPlayUrl(
|
||||||
self.logMsg("Adding additional part: %s" % partcount, 1)
|
child=-1,
|
||||||
|
partIndex=i)
|
||||||
|
self.logMsg("Adding additional part: %s" % i, 1)
|
||||||
|
|
||||||
# Set listitem and properties for each additional parts
|
# Set listitem and properties for each additional parts
|
||||||
pbutils = PlaybackUtils(part)
|
pbutils = PlaybackUtils(item)
|
||||||
pbutils.setProperties(additionalPlayurl, additionalListItem)
|
pbutils.setProperties(additionalPlayurl, additionalListItem)
|
||||||
pbutils.setArtwork(additionalListItem)
|
pbutils.setArtwork(additionalListItem)
|
||||||
|
|
||||||
playlist.add(additionalPlayurl, additionalListItem, index=currentPosition)
|
playlist.add(additionalPlayurl, additionalListItem, index=currentPosition)
|
||||||
self.pl.verifyPlaylist()
|
self.pl.verifyPlaylist()
|
||||||
currentPosition += 1
|
currentPosition += 1
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
if dummyPlaylist:
|
if dummyPlaylist:
|
||||||
# Added a dummy file to the playlist,
|
# Added a dummy file to the playlist,
|
||||||
|
@ -194,7 +194,7 @@ class PlaybackUtils():
|
||||||
|
|
||||||
# For transcoding only, ask for audio/subs pref
|
# For transcoding only, ask for audio/subs pref
|
||||||
if utils.window('emby_%s.playmethod' % playurl) == "Transcode":
|
if utils.window('emby_%s.playmethod' % playurl) == "Transcode":
|
||||||
playurl = playutils.audioSubsPref(playurl, child=self.API.getChild())
|
playurl = playutils.audioSubsPref(playurl, child=self.API.getChildNumber())
|
||||||
utils.window('emby_%s.playmethod' % playurl, value="Transcode")
|
utils.window('emby_%s.playmethod' % playurl, value="Transcode")
|
||||||
|
|
||||||
listitem.setPath(playurl)
|
listitem.setPath(playurl)
|
||||||
|
|
|
@ -36,10 +36,13 @@ class PlayUtils():
|
||||||
utils.logMsg("%s %s" % (self.addonName, self.className), msg, lvl)
|
utils.logMsg("%s %s" % (self.addonName, self.className), msg, lvl)
|
||||||
|
|
||||||
|
|
||||||
def getPlayUrl(self, child=0):
|
def getPlayUrl(self, child=0, partIndex=None):
|
||||||
|
|
||||||
item = self.item
|
item = self.item
|
||||||
|
# NO, I am not very fond of this construct!
|
||||||
self.API.setChildNumber(child)
|
self.API.setChildNumber(child)
|
||||||
|
if partIndex is not None:
|
||||||
|
self.API.setPartNumber(partIndex)
|
||||||
playurl = None
|
playurl = None
|
||||||
|
|
||||||
# if item['MediaSources'][0]['Protocol'] == "Http":
|
# if item['MediaSources'][0]['Protocol'] == "Http":
|
||||||
|
@ -59,7 +62,10 @@ class PlayUtils():
|
||||||
if self.isDirectStream():
|
if self.isDirectStream():
|
||||||
|
|
||||||
self.logMsg("File is direct streaming.", 1)
|
self.logMsg("File is direct streaming.", 1)
|
||||||
playurl = self.API.getTranscodeVideoPath('direct')
|
playurl = self.API.getTranscodeVideoPath(
|
||||||
|
'direct',
|
||||||
|
partIndex=partIndex
|
||||||
|
)
|
||||||
# Set playmethod property
|
# Set playmethod property
|
||||||
utils.window('emby_%s.playmethod' % playurl, value="DirectStream")
|
utils.window('emby_%s.playmethod' % playurl, value="DirectStream")
|
||||||
|
|
||||||
|
@ -70,7 +76,9 @@ class PlayUtils():
|
||||||
'bitrate': self.getBitrate()
|
'bitrate': self.getBitrate()
|
||||||
}
|
}
|
||||||
playurl = self.API.getTranscodeVideoPath(
|
playurl = self.API.getTranscodeVideoPath(
|
||||||
'Transcode', quality=quality
|
'Transcode',
|
||||||
|
quality=quality,
|
||||||
|
partIndex=partIndex
|
||||||
)
|
)
|
||||||
# Set playmethod property
|
# Set playmethod property
|
||||||
utils.window('emby_%s.playmethod' % playurl, value="Transcode")
|
utils.window('emby_%s.playmethod' % playurl, value="Transcode")
|
||||||
|
|
Loading…
Reference in a new issue