def _show_only_forced_subtitle(self): # Forced stream not found, then fix Kodi bug if user chose to apply the workaround # Kodi bug???: # If the kodi player is set with "forced only" subtitle setting, Kodi use this behavior: # 1) try to select forced subtitle that matches audio language # 2) if missing the forced subtitle in language, then # Kodi try to select: The first "forced" subtitle or the first "regular" subtitle # that can respect the chosen language or not, depends on the available streams # So can cause a wrong subtitle language or in a permanent display of subtitles! # This does not reflect the setting chosen in the Kodi player and is very annoying! # There is no other solution than to disable the subtitles manually. if self.legacy_kodi_version: # --- ONLY FOR KODI VERSION 18 --- # NOTE: With Kodi 18 it is not possible to read the properties of the streams # so the only possible way is to read the data from the manifest file audio_language = common.get_kodi_audio_language() cache_identifier = get_esn() + '_' + self.videoid.value manifest_data = G.CACHE.get(CACHE_MANIFESTS, cache_identifier) common.fix_locale_languages(manifest_data['timedtexttracks']) if not any( text_track.get('isForcedNarrative', False) is True and text_track['language'] == audio_language for text_track in manifest_data['timedtexttracks']): self.sc_settings.update({'subtitleenabled': False}) else: # --- ONLY FOR KODI VERSION 19 --- audio_language = common.get_kodi_audio_language( iso_format=xbmc.ISO_639_2, use_fallback=False) if audio_language == 'mediadefault': # Find the language of the default audio track audio_list = self.player_state.get(STREAMS['audio']['list']) for audio_track in audio_list: if audio_track['isdefault']: audio_language = audio_track['language'] break player_stream = self.player_state.get( STREAMS['subtitle']['current']) if player_stream is None: return if audio_language == 'original': # Do nothing is_language_appropriate = True else: is_language_appropriate = player_stream[ 'language'] == audio_language # Check if the current stream is forced and with an appropriate subtitle language if not player_stream['isforced'] or not is_language_appropriate: self.sc_settings.update({'subtitleenabled': False})
def _get_default_audio_language(manifest): channelList = {'1.0': '1', '2.0': '2'} channelListDolby = {'5.1': '6', '7.1': '8'} audio_language = common.get_kodi_audio_language() # Try to find the preferred language with the right channels if g.ADDON.getSettingBool('enable_dolby_sound'): for index, audio_track in enumerate(manifest['audio_tracks']): if audio_track['language'] == audio_language and audio_track[ 'channels'] in channelListDolby: return index # If dolby audio track not exists check other channels list for index, audio_track in enumerate(manifest['audio_tracks']): if audio_track['language'] == audio_language and audio_track[ 'channels'] in channelList: return index # If there is no matches to preferred language, try to sets the original language track as default # Check if the dolby audio track in selected language exists if g.ADDON.getSettingBool('enable_dolby_sound'): for index, audio_track in enumerate(manifest['audio_tracks']): if audio_track['isNative'] and audio_track[ 'channels'] in channelListDolby: return index # If dolby audio track not exists check other channels list for index, audio_track in enumerate(manifest['audio_tracks']): if audio_track['isNative'] and audio_track['channels'] in channelList: return index return 0
def _get_default_subtitle_language(manifest): subtitle_language = common.get_kodi_subtitle_language() if subtitle_language == 'forced_only': if g.ADDON.getSettingBool('forced_subtitle_workaround'): # When we set "forced only" subtitles in Kodi Player, Kodi use this behavior: # 1) try to select forced subtitle that matches audio language # 2) when missing, try to select the first "regular" subtitle that matches audio language # This Kodi behavior is totally non sense. If forced is selected you must not view the regular subtitles # There is no other solution than to disable the subtitles manually. audio_language = common.get_kodi_audio_language() if not any( text_track.get('isForcedNarrative', False) is True and text_track['language'] == audio_language for text_track in manifest['timedtexttracks']): xbmc.Player().showSubtitles(False) # Leave the selection of forced subtitles to Kodi return -1 else: for index, text_track in enumerate(manifest['timedtexttracks']): if text_track['isNoneTrack']: continue if not text_track.get('isForcedNarrative') and text_track[ 'language'] == subtitle_language: return index return -1
def _get_current_audio_language(self): # Get current audio language audio_list = self.player_state.get(STREAMS['audio']['list']) audio_language = common.get_kodi_audio_language( iso_format=xbmc.ISO_639_2) if audio_language == 'mediadefault': # Netflix do not have a "Media default" track then we rely on the language of current nf profile, # although due to current Kodi locale problems could be not always accurate. profile_language_code = G.LOCAL_DB.get_profile_config('language') audio_language = common.convert_language_iso( profile_language_code[0:2], xbmc.ISO_639_2) if audio_language == 'original': # Find the language of the original audio track stream = next( (audio_track for audio_track in audio_list if audio_track['isoriginal']), None) audio_language = stream['language'] elif G.ADDON.getSettingBool('prefer_alternative_lang'): # Get the alternative language code # Here we have only the language code without country code, we do not know the country code to be used, # usually there are only two tracks with the same language and different countries, # then we try to find the language with the country code two_letter_lang_code = common.convert_language_iso(audio_language) stream = next( (audio_track for audio_track in audio_list if audio_track['language'].startswith(two_letter_lang_code + '-')), None) if stream: audio_language = stream['language'] return audio_language
def _show_only_forced_subtitle(self): # Forced stream not found, then fix Kodi bug if user chose to apply the workaround # Kodi bug???: # If the kodi player is set with "forced only" subtitle setting, Kodi use this behavior: # 1) try to select forced subtitle that matches audio language # 2) if missing the forced subtitle in language, then # Kodi try to select: The first "forced" subtitle or the first "regular" subtitle # that can respect the chosen language or not, depends on the available streams # So can cause a wrong subtitle language or in a permanent display of subtitles! # This does not reflect the setting chosen in the Kodi player and is very annoying! # There is no other solution than to disable the subtitles manually. audio_language = common.get_kodi_audio_language() if self.legacy_kodi_version: # --- ONLY FOR KODI VERSION 18 --- # NOTE: With Kodi 18 it is not possible to read the properties of the streams # so the only possible way is to read the data from the manifest file manifest_data = json.loads(common.load_file('manifest.json')) common.fix_locale_languages(manifest_data['timedtexttracks']) if not any( text_track.get('isForcedNarrative', False) is True and text_track['language'] == audio_language for text_track in manifest_data['timedtexttracks']): self.sc_settings.update({'subtitleenabled': False}) else: # --- ONLY FOR KODI VERSION 19 --- # Check the current stream player_stream = self.player_state.get( STREAMS['subtitle']['current']) if not player_stream[ 'isforced'] or player_stream['language'] != audio_language: self.sc_settings.update({'subtitleenabled': False})
def _ensure_forced_subtitle_only_kodi18(self): """Ensures the display of forced subtitles only with the audio language set [KODI 18]""" # With Kodi 18 it is not possible to read the properties of the player streams, # so the only possible way is to read the data from the manifest file from resources.lib.common.cache_utils import CACHE_MANIFESTS from resources.lib.utils.esn import get_esn # Get the manifest cache_identifier = get_esn() + '_' + self.videoid.value manifest = G.CACHE.get(CACHE_MANIFESTS, cache_identifier) common.fix_locale_languages(manifest['timedtexttracks']) # Get the language audio_language = common.get_kodi_audio_language() if audio_language == 'mediadefault': # Netflix do not have a "Media default" track then we rely on the language of current nf profile, # although due to current Kodi locale problems could be not always accurate. profile_language_code = G.LOCAL_DB.get_profile_config('language') audio_language = profile_language_code[0:2] if audio_language == 'original': # Find the language of the original audio track stream = next((audio_track for audio_track in manifest['audio_tracks'] if audio_track['isNative']), None) if not stream: return audio_language = stream['language'] # Check in the manifest if there is a forced subtitle in the specified language if not any( text_track.get('isForcedNarrative', False) and text_track['language'] == audio_language for text_track in manifest['timedtexttracks']): self.sc_settings.update({'subtitleenabled': False})
def _get_default_audio_language(manifest): channel_list = {'1.0': '1', '2.0': '2'} channel_list_dolby = {'5.1': '6', '7.1': '8'} audio_language = common.get_kodi_audio_language() index = 0 # Try to find the preferred language with the right channels if g.ADDON.getSettingBool('enable_dolby_sound'): index = _find_audio_track_index(manifest, 'language', audio_language, channel_list_dolby) # If dolby audio track not exists check other channels list if index is None: index = _find_audio_track_index(manifest, 'language', audio_language, channel_list) # If there is no matches to preferred language, # try to sets the original language track as default # Check if the dolby audio track in selected language exists if index is None and g.ADDON.getSettingBool('enable_dolby_sound'): index = _find_audio_track_index(manifest, 'isNative', True, channel_list_dolby) # If dolby audio track not exists check other channels list if index is None: index = _find_audio_track_index(manifest, 'isNative', True, channel_list) return index
def _get_default_audio_track_id(manifest): """Get the track id of the audio track to be set as default""" channels_stereo = ['1.0', '2.0'] channels_multi = ['5.1', '7.1'] is_prefer_stereo = G.ADDON.getSettingBool('prefer_audio_stereo') audio_language = common.get_kodi_audio_language() audio_stream = {} if audio_language == 'mediadefault': # Netflix do not have a "Media default" track then we rely on the language of current nf profile, # due to current Kodi locale problems this could not be accurate. profile_language_code = G.LOCAL_DB.get_profile_config('language') audio_language = profile_language_code[0:2] if not audio_language == 'original': # If set give priority to the same audio language with different country if G.ADDON.getSettingBool('prefer_alternative_lang'): # Here we have only the language code without country code, we do not know the country code to be used, # usually there are only two tracks with the same language and different countries, # then we try to find the language with the country code stream = next((audio_track for audio_track in manifest['audio_tracks'] if audio_track['language'].startswith(audio_language + '-')), None) if stream: audio_language = stream['language'] # Try find the default track based on the Netflix profile language if not is_prefer_stereo: audio_stream = _find_audio_stream(manifest, 'language', audio_language, channels_multi) if not audio_stream: audio_stream = _find_audio_stream(manifest, 'language', audio_language, channels_stereo) # Try find the default track based on the original audio language if not audio_stream and not is_prefer_stereo: audio_stream = _find_audio_stream(manifest, 'isNative', True, channels_multi) if not audio_stream: audio_stream = _find_audio_stream(manifest, 'isNative', True, channels_stereo) return audio_stream.get('id')
def _get_preferred_audio_language(self): """ Get the language code of the preferred audio as set in Kodi Player setting :return: The language code (as ISO with 2 letters) """ audio_language = common.get_kodi_audio_language() if audio_language == 'mediadefault': # Netflix do not have a "Media default" track then we rely on the language of current nf profile, # although due to current Kodi locale problems could be not always accurate. profile_language_code = G.LOCAL_DB.get_profile_config('language') audio_language = profile_language_code[:2] if audio_language == 'original': # Get current audio languages audio_list = self.player_state.get(STREAMS['audio']['list']) # Find the language of the original audio track stream = next( (audio_track for audio_track in audio_list if audio_track['isoriginal']), None) # stream['language'] can be ISO 3 letters or with country code (pt-BR) / converted with LOCALE_CONV_TABLE if stream is None: # Means some problem, let the code break audio_language = None else: if '-' in stream['language']: audio_language = stream['language'][:2] else: audio_language = common.convert_language_iso( stream['language']) return audio_language
def _select_lang_with_country_code(self): """Force selection of the audio/subtitles language with country code""" # If Kodi Player audio language is not set as "mediadefault" the language with country code for # audio/subtitles, will never be selected automatically, then we try to do this manually. audio_language = self._get_current_audio_language() if '-' not in audio_language: # There is no audio language with country code or different settings have been chosen return # Audio side if common.get_kodi_audio_language() not in ['mediadefault', 'original']: audio_list = self.player_state.get(STREAMS['audio']['list']) stream = None if self.is_prefer_audio_impaired: stream = next((audio_track for audio_track in audio_list if audio_track['language'] == audio_language and audio_track['isimpaired'] and audio_track['isdefault']), # The default track can change is user choose 2ch as def None) if not stream: stream = next((audio_track for audio_track in audio_list if audio_track['language'] == audio_language and not audio_track['isimpaired'] and audio_track['isdefault']), # The default track can change is user choose 2ch as def None) if stream: self.sc_settings.update({'audio': stream}) # We update the current player state data to avoid wrong behaviour with features executed after self.player_state[STREAMS['audio']['current']] = stream # Subtitles side subtitle_list = self.player_state.get(STREAMS['subtitle']['list']) if not any(subtitle_track for subtitle_track in subtitle_list if subtitle_track['language'].startswith(audio_language[:2] + '-')): self.sc_settings.update({'subtitleenabled': False}) return if self.is_kodi_forced_subtitles_only: subtitle_language = audio_language else: # Get the subtitles language set in Kodi Player setting subtitle_language = common.get_kodi_subtitle_language() # Get the alternative language code # Here we have only the language code without country code, we do not know the country code to be used, # usually there are only two tracks with the same language and different countries, # then we try to find the language with the country code _stream = next((subtitle_track for subtitle_track in subtitle_list if subtitle_track['language'].startswith(subtitle_language + '-')), None) if _stream: subtitle_language = _stream['language'] stream_sub = self._find_subtitle_stream(subtitle_language, self.is_kodi_forced_subtitles_only) if stream_sub: self.sc_settings.update({'subtitleenabled': True}) self.sc_settings.update({'subtitle': stream_sub}) # We update the current player state data to avoid wrong behaviour with features executed after self.player_state[STREAMS['subtitle']['current']] = stream_sub else: self.sc_settings.update({'subtitleenabled': False})
def _select_lang_with_country_code(self): """Force selection of the audio/subtitles language with country code""" # --- Audio side --- # NOTE: Kodi is able to auto-select the language with country code for audio/subtitles only # if audio track is set as default and the Kodi Player audio language is set as "mediadefault". pref_audio_language = self._get_preferred_audio_language() # Get current audio languages audio_list = self.player_state.get(STREAMS['audio']['list']) lang_code = _find_lang_with_country_code(audio_list, pref_audio_language) if lang_code and common.get_kodi_audio_language() not in [ 'mediadefault', 'original' ]: stream_audio = None if common.get_kodi_is_prefer_audio_impaired(): stream_audio = next( (audio_track for audio_track in audio_list if audio_track['language'] == lang_code and audio_track['isimpaired'] and audio_track['isdefault'] ), # The default track can change is user choose 2ch None) if not stream_audio: stream_audio = next( (audio_track for audio_track in audio_list if audio_track['language'] == lang_code and not audio_track['isimpaired'] and audio_track['isdefault'] ), # The default track can change is user choose 2ch None) if stream_audio: self.sc_settings.update({'audio': stream_audio}) # We update the current player state data to avoid wrong behaviour with features executed after self.player_state[STREAMS['audio']['current']] = stream_audio # --- Subtitles side --- # Get the subtitles language set in Kodi Player setting pref_subtitle_language = self._get_preferred_subtitle_language() if not pref_subtitle_language: return subtitle_list = self.player_state.get(STREAMS['subtitle']['list']) lang_code = _find_lang_with_country_code(subtitle_list, pref_subtitle_language) if not lang_code: return stream_sub = self._find_subtitle_stream( lang_code, self.is_kodi_forced_subtitles_only) if stream_sub: self.sc_settings.update({'subtitleenabled': True}) self.sc_settings.update({'subtitle': stream_sub}) # We update the current player state data to avoid wrong behaviour with features executed after self.player_state[STREAMS['subtitle']['current']] = stream_sub
def _show_only_forced_subtitle(): # When we have "forced only" subtitle setting in Kodi Player, Kodi use this behavior: # 1) try to select forced subtitle that matches audio language # 2) when missing, try to select the first "regular" subtitle that matches audio language # This Kodi behavior is totally non sense. # If forced is selected you must not view the regular subtitles # There is no other solution than to disable the subtitles manually. manifest_data = json.loads(common.load_file('manifest.json')) common.fix_locale_languages(manifest_data['timedtexttracks']) audio_language = common.get_kodi_audio_language() if not any( text_track.get('isForcedNarrative', False) is True and text_track['language'] == audio_language for text_track in manifest_data['timedtexttracks']): xbmc.Player().showSubtitles(False)
def _get_default_subtitle_language(manifest): subtitle_language = common.get_kodi_subtitle_language() is_forced = subtitle_language == 'forced_only' if is_forced: subtitle_language = common.get_kodi_audio_language() for index, text_track in enumerate(manifest['timedtexttracks']): if text_track['isNoneTrack']: continue if text_track.get('isForcedNarrative', False) != is_forced: continue if text_track['language'] != subtitle_language: continue return index # Leave the selection of forced subtitles to Kodi return -1