From 0dc4f91908d37545fb819f95d3a77e2681d79cd0 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 9 Jun 2015 05:30:01 -0500 Subject: [PATCH] Audio and subs auto selection Now supports Direct stream, Transcoding and Direct path --- resources/lib/KodiMonitor.py | 9 +++ resources/lib/PlayUtils.py | 133 ++++++++++++++++++++++++++++++----- resources/lib/Player.py | 4 +- 3 files changed, 128 insertions(+), 18 deletions(-) diff --git a/resources/lib/KodiMonitor.py b/resources/lib/KodiMonitor.py index 938ae554..92e8b16e 100644 --- a/resources/lib/KodiMonitor.py +++ b/resources/lib/KodiMonitor.py @@ -86,6 +86,15 @@ class Kodi_Monitor(xbmc.Monitor): 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: diff --git a/resources/lib/PlayUtils.py b/resources/lib/PlayUtils.py index 078551bb..1a26fc5a 100644 --- a/resources/lib/PlayUtils.py +++ b/resources/lib/PlayUtils.py @@ -22,6 +22,9 @@ class PlayUtils(): addonId = clientInfo.getAddonId() addon = xbmcaddon.Addon(id=addonId) + audioPref = addon.getSetting('Audiopref') + subsPref = addon.getSetting('Subspref') + def __init__(self): self.__dict__ = self._shared_state @@ -228,27 +231,16 @@ class PlayUtils(): playurl = "%s&VideoCodec=h264&AudioCodec=aac,ac3&deviceId=%s&VideoBitrate=%s" % (playurl, deviceId, self.getVideoBitRate()*1000) mediaSources = result[u'MediaSources'] - if mediaSources[0].get('DefaultAudioStreamIndex') != None: - playurl = "%s&AudioStreamIndex=%s" % (playurl, mediaSources[0][u'DefaultAudioStreamIndex']) - if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: - playurl = "%s&SubtitleStreamIndex=%s" % (playurl, mediaSources[0][u'DefaultSubtitleStreamIndex']) - + prefs = self.audioSubsPref(mediaSources) + + playurl = "%s%s" % (playurl, prefs) self.logMsg("Playurl: %s" % playurl) + return playurl except: self.logMsg("Transcoding failed.") return False - - '''forceTranscodingCodecs = self.addon.getSetting('forceTranscodingCodecs') - # check if we should force encoding due to the forceTranscodingCodecs setting - if forceTranscodingCodecs: - forceTranscodingCodecsSet = frozenset(forceTranscodingCodecs.lower().split(',')) - codecs = frozenset([mediaStream.get('Codec', None) for mediaStream in result.get('MediaStreams', [])]) - commonCodecs = forceTranscodingCodecsSet & codecs - #xbmc.log("emby isDirectPlay MediaStreams codecs: %s forceTranscodingCodecs: %s, common: %s" % (codecs, forceTranscodingCodecsSet, commonCodecs)) - if commonCodecs: - return False''' # Works out if the network quality can play directly or if transcoding is needed def isNetworkQualitySufficient(self, result): @@ -320,6 +312,9 @@ class PlayUtils(): # Convert Emby path to a path we can verify path = self.directPlay(result) + if not path: + return False + try: pathexists = xbmcvfs.exists(path) except: @@ -336,4 +331,110 @@ class PlayUtils(): return True else: self.logMsg("Path is detected as follow: %s. Try direct streaming." % path, 2) - return False \ No newline at end of file + return False + + def audioSubsPref(self, mediaSources): + + addon = xbmcaddon.Addon(id=self.addonId) + + 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 diff --git a/resources/lib/Player.py b/resources/lib/Player.py index bc66d599..707c2903 100644 --- a/resources/lib/Player.py +++ b/resources/lib/Player.py @@ -240,7 +240,7 @@ class Player( xbmc.Player ): # Set audio and subtitles automatically # Following Emby user preference. - if playMethod == "DirectPlay": + if playMethod == "DirectPlay" or playMethod == "DirectStream": # Only currently compatible with DirectPlay. # Tested on plugin://, unsure about direct paths. audiotracks = xbmcplayer.getAvailableAudioStreams() @@ -250,7 +250,7 @@ class Player( xbmc.Player ): codecs = [ # Possible codecs - 'und','Stereo','AC3','DTS', '5.1', + 'und','Stereo','AC3','DTS', '5.1' #'Stereo - Stereo','AC3 5.1', 'DTS 5.1', 'DTS-HD MA 5.1' ]