diff --git a/resources/lib/PlayUtils.py b/resources/lib/PlayUtils.py index 3c291790..a5b97af1 100644 --- a/resources/lib/PlayUtils.py +++ b/resources/lib/PlayUtils.py @@ -166,12 +166,6 @@ class PlayUtils(): elif "Video" in type: playurl = "%s/mediabrowser/Videos/%s/stream?static=true" % (server, id) - # Verify audio and subtitles - mediaSources = result[u'MediaSources'] - if mediaSources[0].get('DefaultAudioStreamIndex') != None: - playurl = "%s&AudioStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultAudioStreamIndex')) - if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: - playurl = "%s&SubtitleStreamIndex=%s" % (playurl, mediaSources[0].get('DefaultSubtitleStreamIndex')) elif "Audio" in type: playurl = "%s/mediabrowser/Audio/%s/stream.mp3" % (server, id) diff --git a/resources/lib/PlaybackUtils.py b/resources/lib/PlaybackUtils.py index f61510e7..c6aa8782 100644 --- a/resources/lib/PlaybackUtils.py +++ b/resources/lib/PlaybackUtils.py @@ -91,18 +91,21 @@ class PlaybackUtils(): return self.AddToPlaylist(itemsToPlay) playurl = PlayUtils().getPlayUrl(server, id, result) + if playurl == False or WINDOW.getProperty('playurlFalse') == "true": WINDOW.clearProperty('playurlFalse') xbmc.log("Failed to retrieve the playback path/url.") return if WINDOW.getProperty("%splaymethod" % playurl) == "Transcode": + # Transcoding, we pull every track to set before playback starts 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 @@ -114,6 +117,13 @@ class PlaybackUtils(): listItem = xbmcgui.ListItem(path=playurl, iconImage=thumbPath, thumbnailImage=thumbPath) + if WINDOW.getProperty("%splaymethod" % playurl) != "Transcode": + # Only for direct play and direct stream + # Append external subtitles to stream + subtitleList = self.externalSubs(id, playurl, server, result.get('MediaSources')) + listItem.setSubtitles(subtitleList) + #pass + # Can not play virtual items if (result.get("LocationType") == "Virtual"): xbmcgui.Dialog().ok(self.language(30128), self.language(30129)) @@ -164,6 +174,38 @@ class PlaybackUtils(): else: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) + def externalSubs(self, id, playurl, server, mediaSources): + + externalsubs = [] + mapping = {} + + mediaStream = mediaSources[0].get('MediaStreams') + kodiindex = 0 + for stream in mediaStream: + + index = stream['Index'] + # Since Emby returns all possible tracks together, have to pull only external subtitles. + # IsTextSubtitleStream if true, is available to download from emby. + if "Subtitle" in stream['Type'] and stream['IsExternal'] and stream['IsTextSubtitleStream']: + + playmethod = utils.window("%splaymethod" % playurl) + + if "DirectPlay" in playmethod: + # Direct play, get direct path + url = PlayUtils().directPlay(stream) + elif "DirectStream" in playmethod: # Direct stream + url = "%s/Videos/%s/%s/Subtitles/%s/Stream.srt" % (server, id, id, index) + + # map external subtitles for mapping + mapping[kodiindex] = index + externalsubs.append(url) + kodiindex += 1 + + mapping = json.dumps(mapping) + utils.window('%sIndexMapping' % playurl, mapping) + + return externalsubs + def audioSubsPref(self, url, mediaSources): WINDOW = xbmcgui.Window(10000) diff --git a/resources/lib/Player.py b/resources/lib/Player.py index 1de341cf..9997f7d7 100644 --- a/resources/lib/Player.py +++ b/resources/lib/Player.py @@ -211,8 +211,24 @@ class Player( xbmc.Player ): # Convert back into an Emby index audioTracks = len(xbmc.Player().getAvailableAudioStreams()) indexAudio = indexAudio + 1 + if subsEnabled and len(xbmc.Player().getAvailableSubtitleStreams()) > 0: - indexSubs = indexSubs + audioTracks + 1 + WINDOW = xbmcgui.Window(10000) + mapping = WINDOW.getProperty("%sIndexMapping" % currentFile) + externalIndex = json.loads(mapping) + if externalIndex: + # If there's external subtitles added via PlaybackUtils + if externalIndex.get(str(indexSubs)): + # If the current subtitle is in the mapping + indexSubs = externalIndex[str(indexSubs)] + else: + # Internal subtitle currently selected + external = len(externalIndex) + indexSubs = indexSubs - external + audioTracks + 1 + else: + # No external subtitles added via PlayUtils + audioTracks = len(xbmc.Player().getAvailableAudioStreams()) + indexSubs = indexSubs + audioTracks + 1 else: indexSubs = "" @@ -292,6 +308,9 @@ class Player( xbmc.Player ): refresh_id = WINDOW.getProperty(currentFile + "refresh_id") playMethod = WINDOW.getProperty(currentFile + "playmethod") itemType = WINDOW.getProperty(currentFile + "type") + mapping = WINDOW.getProperty("%sIndexMapping" % currentFile) + + self.logMsg("Mapping for index: %s" % mapping) # Get playback volume volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}' @@ -304,6 +323,7 @@ class Player( xbmc.Player ): url = "{server}/mediabrowser/Sessions/Playing" postdata = { + 'QueueableMediaTypes': "Video", 'CanSeek': True, 'ItemId': item_id, @@ -325,6 +345,7 @@ class Player( xbmc.Player ): 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) + # Audio tracks indexAudio = result.get('result', 0) if indexAudio: @@ -337,11 +358,25 @@ class Player( xbmc.Player ): subsEnabled = result.get('result', "") if subsEnabled: subsEnabled = subsEnabled.get('subtitleenabled', "") + # Postdata for the audio and subs tracks + audioTracks = len(xbmc.Player().getAvailableAudioStreams()) postdata['AudioStreamIndex'] = indexAudio + 1 + if subsEnabled and len(xbmc.Player().getAvailableSubtitleStreams()) > 0: - audioTracks = len(xbmc.Player().getAvailableAudioStreams()) - postdata['SubtitleStreamIndex'] = indexSubs + audioTracks + 1 + externalIndex = json.loads(mapping) + if externalIndex: + # If there's external subtitles added via PlaybackUtils + if externalIndex.get(str(indexSubs)): + # If the current subtitle is in the mapping + postdata['SubtitleStreamIndex'] = externalIndex[str(indexSubs)] + else: + # Internal subtitle currently selected + external = len(externalIndex) + postdata['SubtitleStreamIndex'] = indexSubs - external + audioTracks + 1 + else: + # No external subtitles added via PlayUtils + postdata['SubtitleStreamIndex'] = indexSubs + audioTracks + 1 else: postdata['SubtitleStreamIndex'] = "" @@ -349,6 +384,7 @@ class Player( xbmc.Player ): self.logMsg("Sending POST play started.", 1) self.doUtils.downloadUrl(url, postBody=postdata, type="POST") + # save data map for updates and position calls data = { 'runtime': runtime, diff --git a/resources/lib/WebSocketClient.py b/resources/lib/WebSocketClient.py index 5f15f924..39cfd6b2 100644 --- a/resources/lib/WebSocketClient.py +++ b/resources/lib/WebSocketClient.py @@ -165,9 +165,28 @@ class WebSocketThread(threading.Thread): 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) + xbmcplayer = xbmc.Player() + currentFile = xbmcplayer.getPlayingFile() + embyIndex = int(arguments['Index']) + + mapping = WINDOW.getProperty("%sIndexMapping" % currentFile) + externalIndex = json.loads(mapping) + + if externalIndex: + # If there's external subtitles added via PlaybackUtils + for index in externalIndex: + if externalIndex[index] == embyIndex: + xbmcplayer.setSubtitleStream(int(index)) + else: + # User selected internal subtitles + external = len(externalIndex) + audioTracks = len(xbmcplayer.getAvailableAudioStreams()) + xbmcplayer.setSubtitleStream(external + embyIndex - audioTracks - 1) + else: + # Emby merges audio and subtitle index together + audioTracks = len(xbmcplayer.getAvailableAudioStreams()) + xbmcplayer.setSubtitleStream(index - audioTracks - 1) + elif command == "SetAudioStreamIndex": index = int(arguments['Index']) xbmc.Player().setAudioStream(index - 1)