parent
56400e54da
commit
72ed20e47f
6 changed files with 169 additions and 125 deletions
|
@ -1851,7 +1851,6 @@ msgctxt "#39702"
|
|||
msgid "Browse by folder"
|
||||
msgstr ""
|
||||
|
||||
|
||||
# For use with addon.xml (PKC metadata for Kodi, e.g. description)
|
||||
# Addon Summary
|
||||
msgctxt "#39703"
|
||||
|
@ -1869,3 +1868,29 @@ msgstr ""
|
|||
msgctxt "#39705"
|
||||
msgid "Use at your own risk"
|
||||
msgstr ""
|
||||
|
||||
|
||||
# If user gets prompted to choose between several subtitles. Leave the number one at the beginning of the string!
|
||||
msgctxt "#39706"
|
||||
msgid "1 No subtitles"
|
||||
msgstr ""
|
||||
|
||||
# If user gets prompted to choose between several audio/subtitle tracks and language is unknown
|
||||
msgctxt "#39707"
|
||||
msgid "unknown"
|
||||
msgstr ""
|
||||
|
||||
# If user gets prompted to choose between several subtitles and Plex adds the "default" flag
|
||||
msgctxt "#39708"
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
# If user gets prompted to choose between several subtitles and Plex adds the "forced" flag
|
||||
msgctxt "#39709"
|
||||
msgid "Forced"
|
||||
msgstr ""
|
||||
|
||||
# If user gets prompted to choose between several subtitles the subtitle cannot be downloaded (has no 'key' attribute from the PMS), the subtitle needs to be burned in
|
||||
msgctxt "#39710"
|
||||
msgid "burn-in"
|
||||
msgstr ""
|
||||
|
|
|
@ -2282,6 +2282,7 @@ class API():
|
|||
'hasMDE': 1,
|
||||
'location': 'lan',
|
||||
'mediaBufferSize': '16384',
|
||||
'subtitleSize': settings('subtitleSize')
|
||||
# 'copyts': 1,
|
||||
# 'offset': 0, # Resume point
|
||||
}
|
||||
|
@ -2313,7 +2314,7 @@ class API():
|
|||
if key:
|
||||
# We do know the language - temporarily download
|
||||
if stream.attrib.get('languageCode') is not None:
|
||||
path = self.__download_external_subtitles(
|
||||
path = self.download_external_subtitles(
|
||||
"{server}%s" % key,
|
||||
"subtitle.%s.%s" % (stream.attrib['languageCode'],
|
||||
stream.attrib['codec']))
|
||||
|
@ -2331,7 +2332,7 @@ class API():
|
|||
return externalsubs
|
||||
|
||||
@staticmethod
|
||||
def __download_external_subtitles(url, filename):
|
||||
def download_external_subtitles(url, filename):
|
||||
"""
|
||||
One cannot pass the subtitle language for ListItems. Workaround; will
|
||||
download the subtitle at url to the Kodi PKC directory in a temp dir
|
||||
|
|
|
@ -106,7 +106,8 @@ class KodiMonitor(Monitor):
|
|||
log.error("Could not find itemid in plex database for a "
|
||||
"video library update")
|
||||
else:
|
||||
# Stop from manually marking as watched unwatched, with actual playback.
|
||||
# Stop from manually marking as watched unwatched, with
|
||||
# actual playback.
|
||||
if window('plex_skipWatched%s' % itemid) == "true":
|
||||
# property is set in player.py
|
||||
window('plex_skipWatched%s' % itemid, clear=True)
|
||||
|
@ -171,11 +172,11 @@ class KodiMonitor(Monitor):
|
|||
|
||||
# Try to get a Kodi ID
|
||||
# If PKC was used - native paths, not direct paths
|
||||
plexid = window('plex_%s.itemid' % tryEncode(currentFile))
|
||||
plex_id = window('plex_%s.itemid' % tryEncode(currentFile))
|
||||
# Get rid of the '' if the window property was not set
|
||||
plexid = None if not plexid else plexid
|
||||
plex_id = None if not plex_id else plex_id
|
||||
kodiid = None
|
||||
if plexid is None:
|
||||
if plex_id is None:
|
||||
log.debug('Did not get Plex id from window properties')
|
||||
try:
|
||||
kodiid = data['item']['id']
|
||||
|
@ -183,30 +184,39 @@ class KodiMonitor(Monitor):
|
|||
log.debug('Did not get a Kodi id from Kodi, darn')
|
||||
# For direct paths, if we're not streaming something
|
||||
# When using Widgets, Kodi doesn't tell us shit so we need this hack
|
||||
if (kodiid is None and plexid is None and typus != 'song'
|
||||
if (kodiid is None and plex_id is None and typus != 'song'
|
||||
and not currentFile.startswith('http')):
|
||||
(kodiid, typus) = get_kodiid_from_filename(currentFile)
|
||||
if kodiid is None:
|
||||
return
|
||||
|
||||
if plexid is None:
|
||||
if plex_id is None:
|
||||
# Get Plex' item id
|
||||
with plexdb.Get_Plex_DB() as plexcursor:
|
||||
plex_dbitem = plexcursor.getItem_byKodiId(kodiid, typus)
|
||||
try:
|
||||
plexid = plex_dbitem[0]
|
||||
plex_id = plex_dbitem[0]
|
||||
except TypeError:
|
||||
log.info("No Plex id returned for kodiid %s. Aborting playback"
|
||||
" report" % kodiid)
|
||||
return
|
||||
log.debug("Found Plex id %s for Kodi id %s for type %s"
|
||||
% (plexid, kodiid, typus))
|
||||
% (plex_id, kodiid, typus))
|
||||
|
||||
# Switch subtitle tracks if applicable
|
||||
subtitle = window('plex_%s.subtitle' % tryEncode(currentFile))
|
||||
if window(tryEncode('plex_%s.playmethod' % currentFile)) \
|
||||
== 'Transcode' and subtitle:
|
||||
if window('plex_%s.subtitle' % currentFile) == 'None':
|
||||
self.xbmcplayer.showSubtitles(False)
|
||||
else:
|
||||
self.xbmcplayer.setSubtitleStream(int(subtitle))
|
||||
|
||||
# Set some stuff if Kodi initiated playback
|
||||
if ((settings('useDirectPaths') == "1" and not typus == "song")
|
||||
or
|
||||
(typus == "song" and settings('enableMusic') == "true")):
|
||||
if self.StartDirectPath(plexid,
|
||||
if self.StartDirectPath(plex_id,
|
||||
typus,
|
||||
tryEncode(currentFile)) is False:
|
||||
log.error('Could not initiate monitoring; aborting')
|
||||
|
@ -214,19 +224,19 @@ class KodiMonitor(Monitor):
|
|||
|
||||
# Save currentFile for cleanup later and to be able to access refs
|
||||
window('plex_lastPlayedFiled', value=currentFile)
|
||||
window('plex_currently_playing_itemid', value=plexid)
|
||||
window("plex_%s.itemid" % tryEncode(currentFile), value=plexid)
|
||||
window('plex_currently_playing_itemid', value=plex_id)
|
||||
window("plex_%s.itemid" % tryEncode(currentFile), value=plex_id)
|
||||
log.info('Finish playback startup')
|
||||
|
||||
def StartDirectPath(self, plexid, type, currentFile):
|
||||
def StartDirectPath(self, plex_id, type, currentFile):
|
||||
"""
|
||||
Set some additional stuff if playback was initiated by Kodi, not PKC
|
||||
"""
|
||||
xml = self.doUtils('{server}/library/metadata/%s' % plexid)
|
||||
xml = self.doUtils('{server}/library/metadata/%s' % plex_id)
|
||||
try:
|
||||
xml[0].attrib
|
||||
except:
|
||||
log.error('Did not receive a valid XML for plexid %s.' % plexid)
|
||||
log.error('Did not receive a valid XML for plex_id %s.' % plex_id)
|
||||
return False
|
||||
# Setup stuff, because playback was started by Kodi, not PKC
|
||||
api = API(xml[0])
|
||||
|
|
|
@ -75,10 +75,7 @@ class PlaybackUtils():
|
|||
|
||||
playmethod = window('plex_%s.playmethod' % playurl)
|
||||
if playmethod == "Transcode":
|
||||
window('plex_%s.playmethod' % playurl, clear=True)
|
||||
playurl = tryEncode(playutils.audioSubsPref(
|
||||
listitem, tryDecode(playurl)))
|
||||
window('plex_%s.playmethod' % playurl, "Transcode")
|
||||
playutils.audioSubsPref(listitem, tryDecode(playurl))
|
||||
listitem.setPath(playurl)
|
||||
api.set_playback_win_props(playurl, listitem)
|
||||
result.listitem = listitem
|
||||
|
@ -195,12 +192,7 @@ class PlaybackUtils():
|
|||
# Would be using the direct path
|
||||
log.debug("Adding contextmenu item for direct paths")
|
||||
if window('plex_%s.playmethod' % playurl) == "Transcode":
|
||||
window('plex_%s.playmethod' % playurl,
|
||||
clear=True)
|
||||
playurl = tryEncode(playutils.audioSubsPref(
|
||||
listitem, tryDecode(playurl)))
|
||||
window('plex_%s.playmethod' % playurl,
|
||||
value="Transcode")
|
||||
playutils.audioSubsPref(listitem, tryDecode(playurl))
|
||||
api.CreateListItemFromPlexItem(listitem)
|
||||
api.set_playback_win_props(playurl, listitem)
|
||||
api.set_listitem_artwork(listitem)
|
||||
|
@ -246,10 +238,7 @@ class PlaybackUtils():
|
|||
# For transcoding only, ask for audio/subs pref
|
||||
if (window('plex_%s.playmethod' % playurl) == "Transcode" and
|
||||
not contextmenu_play):
|
||||
window('plex_%s.playmethod' % playurl, clear=True)
|
||||
playurl = tryEncode(playutils.audioSubsPref(
|
||||
listitem, tryDecode(playurl)))
|
||||
window('plex_%s.playmethod' % playurl, value="Transcode")
|
||||
playutils.audioSubsPref(listitem, tryDecode(playurl))
|
||||
|
||||
listitem.setPath(playurl)
|
||||
api.set_playback_win_props(playurl, listitem)
|
||||
|
|
|
@ -396,7 +396,8 @@ class Player(xbmc.Player):
|
|||
'%s.type' % plex_item,
|
||||
'%s.runtime' % plex_item,
|
||||
'%s.playcount' % plex_item,
|
||||
'%s.playlistPosition' % plex_item
|
||||
'%s.playlistPosition' % plex_item,
|
||||
'%s.subtitle' % plex_item,
|
||||
)
|
||||
for item in cleanup:
|
||||
window(item, clear=True)
|
||||
|
|
|
@ -3,11 +3,9 @@
|
|||
###############################################################################
|
||||
|
||||
import logging
|
||||
from urllib import urlencode
|
||||
from downloadutils import DownloadUtils
|
||||
|
||||
import xbmcgui
|
||||
|
||||
from utils import window, settings, tryEncode, language as lang
|
||||
from utils import window, settings, tryEncode, language as lang, dialog
|
||||
import variables as v
|
||||
import PlexAPI
|
||||
|
||||
|
@ -24,6 +22,7 @@ class PlayUtils():
|
|||
|
||||
self.item = item
|
||||
self.API = PlexAPI.API(item)
|
||||
self.doUtils = DownloadUtils().downloadUrl
|
||||
|
||||
self.userid = window('currUserId')
|
||||
self.server = window('pms_server')
|
||||
|
@ -254,131 +253,150 @@ class PlayUtils():
|
|||
return res[chosen]
|
||||
|
||||
def audioSubsPref(self, listitem, url, part=None):
|
||||
dialog = xbmcgui.Dialog()
|
||||
# For transcoding only
|
||||
# Present the list of audio to select from
|
||||
audioStreamsList = []
|
||||
audioStreams = []
|
||||
# audioStreamsChannelsList = []
|
||||
subtitleStreamsList = []
|
||||
subtitleStreams = ['1 No subtitles']
|
||||
downloadableStreams = []
|
||||
# selectAudioIndex = ""
|
||||
selectSubsIndex = ""
|
||||
playurlprefs = {}
|
||||
"""
|
||||
For transcoding only
|
||||
|
||||
# Set part where we're at
|
||||
self.API.setPartNumber(part)
|
||||
Called at the very beginning of play; used to change audio and subtitle
|
||||
stream by a PUT request to the PMS
|
||||
"""
|
||||
# Set media and part where we're at
|
||||
if self.API.mediastream is None:
|
||||
self.API.getMediastreamNumber()
|
||||
if part is None:
|
||||
part = 0
|
||||
try:
|
||||
mediastreams = self.item[0][part]
|
||||
except (TypeError, KeyError, IndexError):
|
||||
return url
|
||||
|
||||
audioNum = 0
|
||||
mediastreams = self.item[self.API.mediastream][part]
|
||||
except (TypeError, IndexError):
|
||||
log.error('Could not get media %s, part %s'
|
||||
% (self.API.mediastream, part))
|
||||
return
|
||||
part_id = mediastreams.attrib['id']
|
||||
audio_streams_list = []
|
||||
audio_streams = []
|
||||
subtitle_streams_list = []
|
||||
# No subtitles as an option
|
||||
subtitle_streams = [lang(39706)]
|
||||
downloadable_streams = []
|
||||
download_subs = []
|
||||
# selectAudioIndex = ""
|
||||
select_subs_index = ""
|
||||
audio_numb = 0
|
||||
# Remember 'no subtitles'
|
||||
subNum = 1
|
||||
defaultSub = None
|
||||
sub_num = 1
|
||||
default_sub = None
|
||||
|
||||
for stream in mediastreams:
|
||||
# Since Plex returns all possible tracks together, have to sort
|
||||
# them.
|
||||
index = stream.attrib.get('id')
|
||||
type = stream.attrib.get('streamType')
|
||||
|
||||
typus = stream.attrib.get('streamType')
|
||||
# Audio
|
||||
if type == "2":
|
||||
if typus == "2":
|
||||
codec = stream.attrib.get('codec')
|
||||
channelLayout = stream.attrib.get('audioChannelLayout', "")
|
||||
try:
|
||||
track = "%s %s - %s %s" % (audioNum+1,
|
||||
track = "%s %s - %s %s" % (audio_numb+1,
|
||||
stream.attrib['language'],
|
||||
codec,
|
||||
channelLayout)
|
||||
except:
|
||||
track = "%s 'unknown' - %s %s" % (audioNum+1,
|
||||
codec,
|
||||
channelLayout)
|
||||
audioStreamsList.append(index)
|
||||
audioStreams.append(tryEncode(track))
|
||||
audioNum += 1
|
||||
track = "%s %s - %s %s" % (audio_numb+1,
|
||||
lang(39707), # unknown
|
||||
codec,
|
||||
channelLayout)
|
||||
audio_streams_list.append(index)
|
||||
audio_streams.append(tryEncode(track))
|
||||
audio_numb += 1
|
||||
|
||||
# Subtitles
|
||||
elif type == "3":
|
||||
elif typus == "3":
|
||||
try:
|
||||
track = "%s %s" % (subNum+1, stream.attrib['language'])
|
||||
except:
|
||||
track = "%s 'unknown' (%s)" % (subNum+1,
|
||||
stream.attrib.get('codec'))
|
||||
track = "%s %s" % (sub_num+1, stream.attrib['language'])
|
||||
except KeyError:
|
||||
track = "%s %s (%s)" % (sub_num+1,
|
||||
lang(39707), # unknown
|
||||
stream.attrib.get('codec'))
|
||||
default = stream.attrib.get('default')
|
||||
forced = stream.attrib.get('forced')
|
||||
downloadable = stream.attrib.get('key')
|
||||
|
||||
if default:
|
||||
track = "%s - Default" % track
|
||||
track = "%s - %s" % (track, lang(39708)) # Default
|
||||
if forced:
|
||||
track = "%s - Forced" % track
|
||||
track = "%s - %s" % (track, lang(39709)) # Forced
|
||||
if downloadable:
|
||||
downloadableStreams.append(index)
|
||||
# We do know the language - temporarily download
|
||||
if 'language' in stream.attrib:
|
||||
path = self.API.download_external_subtitles(
|
||||
'{server}%s' % stream.attrib['key'],
|
||||
"subtitle.%s.%s" % (stream.attrib['language'],
|
||||
stream.attrib['codec']))
|
||||
# We don't know the language - no need to download
|
||||
else:
|
||||
path = self.API.addPlexCredentialsToUrl(
|
||||
"%s%s" % (self.server, stream.attrib['key']))
|
||||
downloadable_streams.append(index)
|
||||
download_subs.append(tryEncode(path))
|
||||
else:
|
||||
track = "%s (burn-in)" % track
|
||||
track = "%s (%s)" % (track, lang(39710)) # burn-in
|
||||
if stream.attrib.get('selected') == '1' and downloadable:
|
||||
# Only show subs without asking user if they can be
|
||||
# turned off
|
||||
defaultSub = index
|
||||
default_sub = index
|
||||
|
||||
subtitleStreamsList.append(index)
|
||||
subtitleStreams.append(tryEncode(track))
|
||||
subNum += 1
|
||||
subtitle_streams_list.append(index)
|
||||
subtitle_streams.append(tryEncode(track))
|
||||
sub_num += 1
|
||||
|
||||
if audioNum > 1:
|
||||
resp = dialog.select(lang(33013), audioStreams)
|
||||
if audio_numb > 1:
|
||||
resp = dialog('select', lang(33013), audio_streams)
|
||||
if resp > -1:
|
||||
# User selected audio
|
||||
playurlprefs['audioStreamID'] = audioStreamsList[resp]
|
||||
else:
|
||||
# User backed out of selection - let PMS decide
|
||||
pass
|
||||
# User selected some audio track
|
||||
args = {
|
||||
'audioStreamID': audio_streams_list[resp],
|
||||
'allParts': 1
|
||||
}
|
||||
self.doUtils('{server}/library/parts/%s' % part_id,
|
||||
action_type='PUT',
|
||||
parameters=args)
|
||||
|
||||
if sub_num == 1:
|
||||
# No subtitles
|
||||
return
|
||||
|
||||
select_subs_index = None
|
||||
if (settings('pickPlexSubtitles') == 'true' and
|
||||
default_sub is not None):
|
||||
log.info('Using default Plex subtitle: %s' % default_sub)
|
||||
select_subs_index = default_sub
|
||||
else:
|
||||
# There's only one audiotrack.
|
||||
playurlprefs['audioStreamID'] = audioStreamsList[0]
|
||||
|
||||
selectSubsIndex = None
|
||||
if subNum > 1:
|
||||
if (settings('pickPlexSubtitles') == 'true' and
|
||||
defaultSub is not None):
|
||||
log.info('Using default Plex subtitle: %s' % defaultSub)
|
||||
selectSubsIndex = defaultSub
|
||||
resp = dialog('select', lang(33014), subtitle_streams)
|
||||
if resp > 0:
|
||||
select_subs_index = subtitle_streams_list[resp-1]
|
||||
else:
|
||||
resp = dialog.select(lang(33014), subtitleStreams)
|
||||
if resp > 0:
|
||||
selectSubsIndex = subtitleStreamsList[resp-1]
|
||||
else:
|
||||
# User selected no subtitles or backed out of dialog
|
||||
playurlprefs["skipSubtitles"] = 1
|
||||
if selectSubsIndex is not None:
|
||||
# Load subtitles in the listitem if downloadable
|
||||
if selectSubsIndex in downloadableStreams:
|
||||
sub_url = self.API.addPlexHeadersToUrl(
|
||||
"%s/library/streams/%s"
|
||||
% (self.server, selectSubsIndex))
|
||||
log.info("Downloadable sub: %s: %s"
|
||||
% (selectSubsIndex, sub_url))
|
||||
listitem.setSubtitles([tryEncode(sub_url)])
|
||||
# Don't additionally burn in subtitles
|
||||
playurlprefs["skipSubtitles"] = 1
|
||||
else:
|
||||
log.info('Need to burn in subtitle %s' % selectSubsIndex)
|
||||
playurlprefs["subtitleStreamID"] = selectSubsIndex
|
||||
playurlprefs["subtitleSize"] = settings('subtitleSize')
|
||||
# User selected no subtitles or backed out of dialog
|
||||
select_subs_index = ''
|
||||
|
||||
url += '&' + urlencode(playurlprefs)
|
||||
log.debug('Adding external subtitles: %s' % download_subs)
|
||||
# Enable Kodi to switch autonomously to downloadable subtitles
|
||||
if download_subs:
|
||||
listitem.setSubtitles(download_subs)
|
||||
|
||||
# Get number of channels for selected audio track
|
||||
# audioChannels = audioStreamsChannelsList.get(selectAudioIndex, 0)
|
||||
# if audioChannels > 2:
|
||||
# playurlprefs += "&AudioBitrate=384000"
|
||||
# else:
|
||||
# playurlprefs += "&AudioBitrate=192000"
|
||||
if select_subs_index in downloadable_streams:
|
||||
for i, stream in enumerate(downloadable_streams):
|
||||
if stream == select_subs_index:
|
||||
# Set the correct subtitle
|
||||
window('plex_%s.subtitle' % tryEncode(url), value=str(i))
|
||||
break
|
||||
# Don't additionally burn in subtitles
|
||||
select_subs_index = ''
|
||||
else:
|
||||
window('plex_%s.subtitle' % tryEncode(url), value='None')
|
||||
|
||||
return url
|
||||
args = {
|
||||
'subtitleStreamID': select_subs_index,
|
||||
'allParts': 1
|
||||
}
|
||||
self.doUtils('{server}/library/parts/%s' % part_id,
|
||||
action_type='PUT',
|
||||
parameters=args)
|
||||
|
|
Loading…
Reference in a new issue