diff --git a/resources/lib/DownloadUtils.py b/resources/lib/DownloadUtils.py
index 436a19d5..c76681bd 100644
--- a/resources/lib/DownloadUtils.py
+++ b/resources/lib/DownloadUtils.py
@@ -21,8 +21,7 @@ class DownloadUtils():
clientInfo = ClientInformation()
addonName = clientInfo.getAddonName()
- addonId = clientInfo.getAddonId()
- addon = xbmcaddon.Addon(id=addonId)
+ addon = xbmcaddon.Addon()
WINDOW = xbmcgui.Window(10000)
# Requests session
@@ -79,6 +78,7 @@ class DownloadUtils():
"GoHome,PageUp,NextLetter,GoToSearch,"
"GoToSettings,PageDown,PreviousLetter,TakeScreenshot,"
"VolumeUp,VolumeDown,ToggleMute,SendString,DisplayMessage,"
+ "SetAudioStreamIndex,SetSubtitleStreamIndex,"
"Mute,Unmute,SetVolume,"
"Play,Playstate,PlayNext"
@@ -183,7 +183,6 @@ class DownloadUtils():
# Replace for the real values and append api_key
url = url.replace("{server}", self.server, 1)
url = url.replace("{UserId}", self.userId, 1)
- #url = "%s&api_key=%s" % (url, self.token)
self.logMsg("URL: %s" % url, 2)
# Prepare request
@@ -293,7 +292,7 @@ class DownloadUtils():
if r.headers['X-Application-Error-Code'] == "ParentalControl":
# Parental control - access restricted
WINDOW.setProperty("Server_status", "restricted")
- xbmcgui.Dialog().notification("Emby server", "Access restricted.", xbmcgui.NOTIFICATION_ERROR, time=5000)
+ xbmcgui.Dialog().notification("Emby server", "Access restricted.", xbmcgui.NOTIFICATION_ERROR, icon="special://home/addons/plugin.video.emby/icon.png", time=5000)
return False
if (status == "401") or (status == "Auth"):
@@ -303,7 +302,7 @@ class DownloadUtils():
# Tell UserClient token has been revoked.
WINDOW.setProperty("Server_status", "401")
self.logMsg("HTTP Error: %s" % e, 0)
- xbmcgui.Dialog().notification("Error connecting", "Unauthorized.", xbmcgui.NOTIFICATION_ERROR)
+ xbmcgui.Dialog().notification("Error connecting", "Unauthorized.", xbmcgui.NOTIFICATION_ERROR, icon="special://home/addons/plugin.video.emby/icon.png")
return 401
elif (r.status_code == 301) or (r.status_code == 302):
diff --git a/resources/lib/PlayUtils.py b/resources/lib/PlayUtils.py
index 7d7e8f90..69bc92a7 100644
--- a/resources/lib/PlayUtils.py
+++ b/resources/lib/PlayUtils.py
@@ -210,11 +210,6 @@ class PlayUtils():
deviceId = self.clientInfo.getMachineId()
playurl = "%s/mediabrowser/Videos/%s/master.m3u8?mediaSourceId=%s" % (server, id, id)
playurl = "%s&VideoCodec=h264&AudioCodec=aac,ac3&deviceId=%s&VideoBitrate=%s" % (playurl, deviceId, self.getVideoBitRate()*1000)
-
- mediaSources = result[u'MediaSources']
- prefs = self.audioSubsPref(mediaSources)
-
- playurl = "%s%s" % (playurl, prefs)
self.logMsg("Playurl: %s" % playurl)
return playurl
@@ -312,110 +307,4 @@ class PlayUtils():
return True
else:
self.logMsg("Path is detected as follow: %s. Try direct streaming." % path, 2)
- return False
-
- def audioSubsPref(self, mediaSources):
-
- addon = xbmcaddon.Addon()
-
- defaultAudio = mediaSources[0][u'DefaultAudioStreamIndex']
- playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
-
- codecs = [
- # Possible codecs
- u'und', u'ac3', u'dts', u'5.1', u'aac', u'mp3', u'dca'
- ]
-
- try:
- mediaStream = mediaSources[0].get('MediaStreams')
- audiotracks = {}
- substracks = {}
- defaultSubs = None
-
- for stream in mediaStream:
- # Since Emby returns all possible tracks together, have to sort them.
- if u'Audio' in stream[u'Type']:
- if u'Language' in stream:
- audiotracks[stream[u'Language']] = stream[u'Index']
- else:
- audiotracks[stream[u'Codec']] = stream[u'Index']
-
- if u'Subtitle' in stream[u'Type']:
- if u'Language' in stream:
- substracks[stream[u'Language']] = stream[u'Index']
- if stream[u'IsDefault'] == True:
- defaultSubs = stream[u'Language']
- else:
- substracks[stream[u'Codec']] = stream[u'Index']
- if stream[u'IsDefault']:
- defaultSubs = stream[u'Codec']
-
- self.logMsg("%s %s %s" % (defaultSubs, audiotracks, substracks), 1)
-
- if len(audiotracks) == 1 and len(substracks) == 0:
- # There's only one audio track and no subtitles
- playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
- return playurlprefs
-
- codec_intrack = False
- for codec in codecs:
- for track in audiotracks:
- if codec in track:
- codec_intrack = True
-
- if self.audioPref in audiotracks:
- self.logMsg("Door 1", 2)
- # Audio pref is available
- playurlprefs = "&AudioStreamIndex=%s" % audiotracks[self.audioPref]
-
- if addon.getSetting('subsoverride') == "true":
- # Subs are forced.
- if self.subsPref in substracks:
- self.logMsg("Door 1.1", 2)
- playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[self.subsPref])
- else:
- # Use default subs
- if defaultSubs != None:
- self.logMsg("Door 1.2", 2)
- playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[defaultSubs])
-
- elif (len(audiotracks) == 1) and not codec_intrack:
- self.logMsg("Door 2", 2)
- # 1. There's one audio track.
- # 2. The audio is defined as a language.
- # 3. Audio pref is not available, guaranteed.
- playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
-
- if self.subsPref in substracks:
- self.logMsg("Door 2.1", 2)
- # Subs pref is available.
- playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[self.subsPref])
- else:
- # Use default subs
- if defaultSubs != None:
- self.logMsg("Door 2.2", 2)
- playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[defaultSubs])
-
- elif len(audiotracks) == 1 and codec_intrack:
- self.logMsg("Door 3", 2)
- # 1. There one audio track.
- # 2. The audio is undefined or a codec.
- # 3. Audio track is mislabeled.
- playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
-
- if self.subsPref in substracks:
- # If the subtitle is available, only display
- # if the setting is enabled.
- if addon.getSetting('subsoverride') == "true":
- # Subs are forced.
- self.logMsg("Door 3.1", 2)
- playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[self.subsPref])
- else:
- # Use default subs
- if defaultSubs != None:
- self.logMsg("Door 3.2", 2)
- playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[defaultSubs])
-
- except: pass
-
- return playurlprefs
\ No newline at end of file
+ return False
\ No newline at end of file
diff --git a/resources/lib/PlaybackUtils.py b/resources/lib/PlaybackUtils.py
index 7940f39f..b6a85329 100644
--- a/resources/lib/PlaybackUtils.py
+++ b/resources/lib/PlaybackUtils.py
@@ -97,6 +97,13 @@ class PlaybackUtils():
xbmc.log("Failed to retrieve the playback path/url.")
return
+ if WINDOW.getProperty("%splaymethod" % playurl) == "Transcode":
+ playurlprefs = self.audioSubsPref(playurl, result.get("MediaSources"))
+ if playurlprefs:
+ playurl = playurlprefs
+ else: # User cancelled dialog
+ return
+
thumbPath = API().getArtwork(result, "Primary")
#if the file is a virtual strm file, we need to override the path by reading it's contents
@@ -146,22 +153,6 @@ class PlaybackUtils():
WINDOW.setProperty(playurl+"runtimeticks", str(result.get("RunTimeTicks")))
WINDOW.setProperty(playurl+"type", result.get("Type"))
WINDOW.setProperty(playurl+"item_id", id)
-
- mediaSources = result.get("MediaSources")
- if(mediaSources != None):
- mediaStream = mediaSources[0].get('MediaStreams')
- defaultsubs = ""
- for stream in mediaStream:
- if u'Subtitle' in stream[u'Type'] and stream[u'IsDefault']:
- if u'Language' in stream:
- defaultsubs = stream[u'Language']
- else:
- defaultsubs = stream[u'Codec']
- WINDOW.setProperty("%ssubs" % playurl, defaultsubs.encode('utf-8'))
- if mediaSources[0].get('DefaultAudioStreamIndex') != None:
- WINDOW.setProperty(playurl+"AudioStreamIndex", str(mediaSources[0].get('DefaultAudioStreamIndex')))
- if mediaSources[0].get('DefaultSubtitleStreamIndex') != None:
- WINDOW.setProperty(playurl+"SubtitleStreamIndex", str(mediaSources[0].get('DefaultSubtitleStreamIndex')))
#launch the playback - only set the listitem props if we're not using the setresolvedurl approach
if setup == "service":
@@ -174,6 +165,76 @@ class PlaybackUtils():
else:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem)
+ def audioSubsPref(self, url, mediaSources):
+
+ WINDOW = xbmcgui.Window(10000)
+ # Present the list of audio to select from
+ audioStreamsList = {}
+ audioStreams = []
+ selectAudioIndex = ""
+ subtitleStreamsList = {}
+ subtitleStreams = ['No subtitles']
+ selectSubsIndex = ""
+ playurlprefs = "%s" % url
+
+ mediaStream = mediaSources[0].get('MediaStreams')
+ for stream in mediaStream:
+ index = stream['Index']
+ # Since Emby returns all possible tracks together, have to sort them.
+ if 'Audio' in stream['Type']:
+ try:
+ track = stream['Language']
+ audioStreamsList[track] = index
+ audioStreams.append(track)
+ except:
+ track = stream['Codec']
+ audioStreamsList[track] = index
+ audioStreams.append(track)
+
+ elif 'Subtitle' in stream['Type']:
+ try:
+ track = stream['Language']
+ subtitleStreamsList[track] = index
+ subtitleStreams.append(track)
+ except:
+ track = stream['Codec']
+ subtitleStreamsList[track] = index
+ subtitleStreams.append(track)
+
+ if len(audioStreams) > 1:
+ resp = xbmcgui.Dialog().select("Choose the audio stream", audioStreams)
+ if resp > -1:
+ # User selected audio
+ selected = audioStreams[resp]
+ selected_audioIndex = audioStreamsList[selected]
+ playurlprefs += "&AudioStreamIndex=%s" % selected_audioIndex
+ selectAudioIndex = str(selected_audioIndex)
+ else: return False
+ else: # There's only one audiotrack.
+ audioIndex = audioStreamsList[audioStreams[0]]
+ playurlprefs += "&AudioStreamIndex=%s" % audioIndex
+ selectAudioIndex = str(audioIndex)
+
+ if len(subtitleStreams) > 1:
+ resp = xbmcgui.Dialog().select("Choose the subtitle stream", subtitleStreams)
+ if resp == 0:
+ # User selected no subtitles
+ pass
+ elif resp > -1:
+ # User selected subtitles
+ selected = subtitleStreams[resp]
+ selected_subsIndex = subtitleStreamsList[selected]
+ playurlprefs += "&SubtitleStreamIndex=%s" % selected_subsIndex
+ selectSubsIndex = str(selected_subsIndex)
+ else: return False
+
+ # Reset the method with the new playurl
+ WINDOW.setProperty("%splaymethod" % playurlprefs, "Transcode")
+ WINDOW.setProperty("%sAudioStreamIndex" % playurlprefs, selectAudioIndex)
+ WINDOW.setProperty("%sSubtitleStreamIndex" % playurlprefs, selectSubsIndex)
+
+ return playurlprefs
+
def setArt(self, list,name,path):
if name=='thumb' or name=='fanart_image' or name=='small_poster' or name=='tiny_poster' or name == "medium_landscape" or name=='medium_poster' or name=='small_fanartimage' or name=='medium_fanartimage' or name=='fanart_noindicators':
list.setProperty(name, path)
diff --git a/resources/lib/Player.py b/resources/lib/Player.py
index 4eab6ea2..81d95a84 100644
--- a/resources/lib/Player.py
+++ b/resources/lib/Player.py
@@ -68,6 +68,8 @@ class Player( xbmc.Player ):
def stopAll(self):
+ WINDOW = xbmcgui.Window(10000)
+
if(len(self.played_information) == 0):
return
@@ -86,6 +88,7 @@ class Player( xbmc.Player ):
refresh_id = data.get("refresh_id")
currentFile = data.get("currentfile")
type = data.get("Type")
+ playMethod = data.get('playmethod')
# Prevent websocket feedback
self.WINDOW.setProperty("played_itemId", item_id)
@@ -116,12 +119,12 @@ class Player( xbmc.Player ):
listItem = [item_id]
LibrarySync().removefromDB(listItem, True)
- # Stop transcoding
- if self.WINDOW.getProperty("transcoding%s" % item_id) == "true":
- deviceId = self.clientInfo.getMachineId()
- url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId
- self.doUtils.downloadUrl(url, type="DELETE")
- self.WINDOW.clearProperty("transcoding%s" % item_id)
+ # Stop transcoding
+ if playMethod == "Transcode":
+ self.logMsg("Transcoding for %s terminated." % item_id)
+ deviceId = self.clientInfo.getMachineId()
+ url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId
+ self.doUtils.downloadUrl(url, type="DELETE")
self.played_information.clear()
@@ -190,11 +193,38 @@ class Player( xbmc.Player ):
if playTime:
postdata['PositionTicks'] = int(playTime * 10000000)
- if audioindex:
- postdata['AudioStreamIndex'] = audioindex
+ if playMethod != "Transcode":
+ # Get current audio and subtitles track
+ track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid":1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
+ result = xbmc.executeJSONRPC(track_query)
+ result = json.loads(result)
+ indexAudio = result['result']['currentaudiostream']['index']
+ indexSubs = result['result']['currentsubtitle']['index']
+ subsEnabled = result['result']['subtitleenabled']
- if subtitleindex:
- postdata['SubtitleStreamIndex'] = subtitleindex
+ # Convert back into an Emby index
+ audioTracks = len(xbmc.Player().getAvailableAudioStreams())
+ indexAudio = indexAudio + 1
+ if subsEnabled:
+ indexSubs = indexSubs + audioTracks + 1
+ else:
+ indexSubs = ""
+
+ if audioindex == indexAudio:
+ postdata['AudioStreamIndex'] = audioindex
+ else:
+ postdata['AudioStreamIndex'] = indexAudio
+ data['AudioStreamIndex'] = indexAudio
+
+ if subtitleindex == indexSubs:
+ postdata['SubtitleStreamIndex'] = subtitleindex
+ else:
+ postdata['SubtitleStreamIndex'] = indexSubs
+ data['SubtitleStreamIndex'] = indexSubs
+
+ else:
+ data['AudioStreamIndex'] = audioindex
+ data['SubtitleStreamIndex'] = subtitleindex
postdata = json.dumps(postdata)
self.logMsg("Report: %s" % postdata, 2)
@@ -227,7 +257,7 @@ class Player( xbmc.Player ):
def onPlayBackStarted( self ):
# Will be called when xbmc starts playing a file
- WINDOW = self.WINDOW
+ WINDOW = xbmcgui.Window(10000)
addon = self.addon
xbmcplayer = self.xbmcplayer
self.stopAll()
@@ -255,8 +285,6 @@ class Player( xbmc.Player ):
# only ever use the win props here, use the data map in all other places
runtime = WINDOW.getProperty(currentFile + "runtimeticks")
refresh_id = WINDOW.getProperty(currentFile + "refresh_id")
- audioindex = WINDOW.getProperty(currentFile + "AudioStreamIndex")
- subtitleindex = WINDOW.getProperty(currentFile + "SubtitleStreamIndex")
playMethod = WINDOW.getProperty(currentFile + "playmethod")
itemType = WINDOW.getProperty(currentFile + "type")
@@ -281,11 +309,27 @@ class Player( xbmc.Player ):
'IsMuted': muted
}
- if audioindex:
+ # Get the current audio track and subtitles
+ if playMethod == "Transcode":
+ audioindex = WINDOW.getProperty(currentFile + "AudioStreamIndex")
+ subtitleindex = WINDOW.getProperty(currentFile + "SubtitleStreamIndex")
postdata['AudioStreamIndex'] = audioindex
-
- if subtitleindex:
postdata['SubtitleStreamIndex'] = subtitleindex
+
+ else:
+ track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid": 1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
+ result = xbmc.executeJSONRPC(track_query)
+ result = json.loads(result)
+ indexAudio = result['result']['currentaudiostream']['index']
+ indexSubs = result['result']['currentsubtitle']['index']
+ subsEnabled = result['result']['subtitleenabled']
+
+ postdata['AudioStreamIndex'] = indexAudio + 1
+ if subsEnabled:
+ audioTracks = len(xbmc.Player().getAvailableAudioStreams())
+ postdata['SubtitleStreamIndex'] = indexSubs + audioTracks + 1
+ else:
+ postdata['SubtitleStreamIndex'] = ""
# Post playback to server
self.logMsg("Sending POST play started.", 1)
@@ -297,8 +341,8 @@ class Player( xbmc.Player ):
'item_id': item_id,
'refresh_id': refresh_id,
'currentfile': currentFile,
- 'AudioStreamIndex': audioindex,
- 'SubtitleStreamIndex': subtitleindex,
+ 'AudioStreamIndex': postdata['AudioStreamIndex'],
+ 'SubtitleStreamIndex': postdata['SubtitleStreamIndex'],
'playmethod': playMethod,
'Type': itemType,
'currentPosition': int(seekTime)
@@ -349,4 +393,4 @@ class Player( xbmc.Player ):
def onPlayBackStopped( self ):
# Will be called when user stops xbmc playing a file
self.logMsg("onPlayBackStopped", 0)
- self.stopAll()
+ self.stopAll()
\ No newline at end of file
diff --git a/resources/lib/WebSocketClient.py b/resources/lib/WebSocketClient.py
index 97d3097e..938eadf4 100644
--- a/resources/lib/WebSocketClient.py
+++ b/resources/lib/WebSocketClient.py
@@ -96,7 +96,7 @@ class WebSocketThread(threading.Thread):
xbmc.executebuiltin("Dialog.Close(all,true)")
xbmc.executebuiltin("XBMC.Notification(Playlist: Added %s items to Playlist,)" % len(itemIds))
PlaybackUtils().PLAYAllItems(itemIds, startPositionTicks)
- # Don't think this is being used.
+
elif "PlayNext" in playCommand:
xbmc.executebuiltin("XBMC.Notification(Playlist: Added %s items to Playlist,)" % len(itemIds))
playlist = PlaybackUtils().AddToPlaylist(itemIds)
@@ -155,7 +155,7 @@ class WebSocketThread(threading.Thread):
command = data['Name']
arguments = data.get("Arguments")
- if command in ('Mute', 'Unmute', 'SetVolume'):
+ if command in ('Mute', 'Unmute', 'SetVolume', 'SetSubtitleStreamIndex', 'SetAudioStreamIndex'):
# These commands need to be reported back
if command == "Mute":
xbmc.executebuiltin('Mute')
@@ -164,6 +164,14 @@ class WebSocketThread(threading.Thread):
elif command == "SetVolume":
volume = arguments['Volume']
xbmc.executebuiltin('SetVolume(%s[,showvolumebar])' % volume)
+ elif command == "SetSubtitleStreamIndex":
+ # Emby merges audio and subtitle index together
+ audioTracks = len(xbmc.Player().getAvailableAudioStreams())
+ index = int(arguments['Index']) - audioTracks
+ xbmc.Player().setSubtitleStream(index - 1)
+ elif command == "SetAudioStreamIndex":
+ index = int(arguments['Index'])
+ xbmc.Player().setAudioStream(index - 1)
# Report playback
WINDOW.setProperty('commandUpdate', "true")
diff --git a/resources/settings.xml b/resources/settings.xml
index 08628b03..ad857d3c 100644
--- a/resources/settings.xml
+++ b/resources/settings.xml
@@ -33,8 +33,6 @@
-
-