コード例 #1
0
 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
         cache_identifier = g.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 ---
         # 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})
コード例 #2
0
def build_media_tag(player_state, manifest):
    """Build the playTimes and the mediaId data by parsing manifest and the current player streams used"""
    common.fix_locale_languages(manifest['audio_tracks'])
    duration = player_state['elapsed_seconds'] * 1000

    audio_downloadable_id, audio_track_id = _find_audio_data(
        player_state, manifest)
    video_downloadable_id, video_track_id = _find_video_data(
        player_state, manifest)
    # Warning 'currentsubtitle' value in player_state on Kodi 18
    # do not have proprieties like isdefault, isforced, isimpaired
    # if in the future the implementation will be done it should be available only on Kodi 19
    # then for now we leave the subtitles as disabled

    text_track_id = 'T:1:1;1;NONE;0;1;'

    play_times = {
        'total': duration,
        'audio': [{
            'downloadableId': audio_downloadable_id,
            'duration': duration
        }],
        'video': [{
            'downloadableId': video_downloadable_id,
            'duration': duration
        }],
        'text': []
    }

    # Format example: "A:1:1;2;en;1;|V:2:1;2;;default;1;CE3;0;|T:1:1;1;NONE;0;1;"
    media_id = '|'.join([audio_track_id, video_track_id, text_track_id])

    return play_times, media_id
コード例 #3
0
 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})
コード例 #4
0
def build_media_tag(player_state, manifest):
    """Build the playTimes and the mediaId data by parsing manifest and the current player streams used"""
    common.fix_locale_languages(manifest['audio_tracks'])
    duration = player_state['elapsed_seconds'] * 1000

    audio_downloadable_id, audio_track_id = _find_audio_data(
        player_state, manifest)
    video_downloadable_id, video_track_id = _find_video_data(
        player_state, manifest)
    # Todo: subtitles data set always as disabled, could be added in future
    text_track_id = 'T:1:1;1;NONE;0;1;'

    play_times = {
        'total': duration,
        'audio': [{
            'downloadableId': audio_downloadable_id,
            'duration': duration
        }],
        'video': [{
            'downloadableId': video_downloadable_id,
            'duration': duration
        }],
        'text': []
    }

    # Format example: "A:1:1;2;en;1;|V:2:1;2;;default;1;CE3;0;|T:1:1;1;NONE;0;1;"
    media_id = '|'.join([audio_track_id, video_track_id, text_track_id])

    return play_times, media_id
コード例 #5
0
def convert_to_dash(manifest):
    """Convert a Netflix style manifest to MPEGDASH manifest"""
    seconds = manifest['duration'] / 1000
    init_length = seconds / 2 * 12 + 20 * 1000
    duration = "PT" + str(seconds) + ".00S"

    root = _mpd_manifest_root(duration)
    period = ET.SubElement(root, 'Period', start='PT0S', duration=duration)
    protection = _protection_info(manifest) if manifest['hasDrmStreams'] else None
    drm_streams = manifest['hasDrmStreams']

    for video_track in manifest['video_tracks']:
        _convert_video_track(
            video_track, period, init_length, protection, drm_streams)

    common.fix_locale_languages(manifest['audio_tracks'])
    common.fix_locale_languages(manifest['timedtexttracks'])

    default_audio_language_index = _get_default_audio_language(manifest)
    for index, audio_track in enumerate(manifest['audio_tracks']):
        _convert_audio_track(audio_track, period, init_length,
                             (index == default_audio_language_index), drm_streams)

    default_subtitle_language_index = _get_default_subtitle_language(manifest)
    for index, text_track in enumerate(manifest['timedtexttracks']):
        if text_track['isNoneTrack']:
            continue
        _convert_text_track(text_track, period,
                            default=(index == default_subtitle_language_index))

    xml = ET.tostring(root, encoding='utf-8', method='xml')
    common.save_file('manifest.mpd', xml)
    return xml.decode('utf-8').replace('\n', '').replace('\r', '').encode('utf-8')
コード例 #6
0
def convert_to_dash(manifest):
    """Convert a Netflix style manifest to MPEG-DASH manifest"""
    from xbmcaddon import Addon
    isa_version = Addon('inputstream.adaptive').getAddonInfo('version')

    has_drm_streams = manifest['hasDrmStreams']
    protection_info = _get_protection_info(manifest) if has_drm_streams else None

    seconds = int(manifest['duration'] / 1000)
    init_length = int(seconds / 2 * 12 + 20 * 1000)
    duration = "PT" + str(seconds) + ".00S"

    root = _mpd_manifest_root(duration)
    period = ET.SubElement(root, 'Period', start='PT0S', duration=duration)

    for video_track in manifest['video_tracks']:
        _convert_video_track(video_track, period, init_length, protection_info, has_drm_streams)

    common.fix_locale_languages(manifest['audio_tracks'])
    common.fix_locale_languages(manifest['timedtexttracks'])

    default_audio_language_index = _get_default_audio_language(manifest)
    for index, audio_track in enumerate(manifest['audio_tracks']):
        _convert_audio_track(audio_track, period, init_length, (index == default_audio_language_index), has_drm_streams)

    default_subtitle_language_index = _get_default_subtitle_language(manifest)
    for index, text_track in enumerate(manifest['timedtexttracks']):
        if text_track['isNoneTrack']:
            continue
        _convert_text_track(text_track, period, (index == default_subtitle_language_index), isa_version)

    xml = ET.tostring(root, encoding='utf-8', method='xml')
    if common.is_debug_verbose():
        common.save_file('manifest.mpd', xml)
    return xml.decode('utf-8').replace('\n', '').replace('\r', '').encode('utf-8')
コード例 #7
0
def convert_to_dash(manifest):
    """Convert a Netflix style manifest to MPEG-DASH manifest"""
    from xbmcaddon import Addon
    isa_version = g.remove_ver_suffix(
        g.py2_decode(Addon('inputstream.adaptive').getAddonInfo('version')))

    # If a CDN server has stability problems it may cause errors with streaming,
    # we allow users to select a different CDN server
    # (should be managed by ISA but is currently is not implemented)
    cdn_index = int(g.ADDON.getSettingString('cdn_server')[-1]) - 1

    seconds = manifest['duration'] / 1000
    init_length = int(seconds / 2 * 12 + 20 * 1000)
    duration = "PT" + str(int(seconds)) + ".00S"

    root = _mpd_manifest_root(duration)
    period = ET.SubElement(root, 'Period', start='PT0S', duration=duration)

    has_video_drm_streams = manifest['video_tracks'][0].get(
        'hasDrmStreams', False)
    video_protection_info = _get_protection_info(
        manifest['video_tracks'][0]) if has_video_drm_streams else None

    for video_track in manifest['video_tracks']:
        _convert_video_track(video_track, period, init_length,
                             video_protection_info, has_video_drm_streams,
                             cdn_index)

    common.fix_locale_languages(manifest['audio_tracks'])
    common.fix_locale_languages(manifest['timedtexttracks'])

    has_audio_drm_streams = manifest['audio_tracks'][0].get(
        'hasDrmStreams', False)

    default_audio_language_index = _get_default_audio_language(manifest)
    for index, audio_track in enumerate(manifest['audio_tracks']):
        _convert_audio_track(audio_track, period, init_length,
                             (index == default_audio_language_index),
                             has_audio_drm_streams, cdn_index)

    default_subtitle_language_index = _get_default_subtitle_language(manifest)
    for index, text_track in enumerate(manifest['timedtexttracks']):
        if text_track['isNoneTrack']:
            continue
        _convert_text_track(text_track, period,
                            (index == default_subtitle_language_index),
                            cdn_index, isa_version)

    xml = ET.tostring(root, encoding='utf-8', method='xml')
    if common.is_debug_verbose():
        common.save_file('manifest.mpd', xml)
    return xml.decode('utf-8').replace('\n', '').replace('\r',
                                                         '').encode('utf-8')
コード例 #8
0
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)
コード例 #9
0
def convert_to_dash(manifest):
    """Convert a Netflix style manifest to MPEG-DASH manifest"""
    # If a CDN server has stability problems it may cause errors with streaming,
    # we allow users to select a different CDN server
    # (should be managed by ISA but is currently is not implemented)
    cdn_index = int(G.ADDON.getSettingString('cdn_server')[-1]) - 1

    seconds = manifest['duration'] / 1000
    init_length = int(seconds / 2 * 12 + 20 * 1000)
    duration = "PT" + str(int(seconds)) + ".00S"

    root = _mpd_manifest_root(duration)
    period = ET.SubElement(root, 'Period', start='PT0S', duration=duration)

    has_video_drm_streams = manifest['video_tracks'][0].get(
        'hasDrmStreams', False)
    video_protection_info = _get_protection_info(
        manifest['video_tracks'][0]) if has_video_drm_streams else None

    for video_track in manifest['video_tracks']:
        _convert_video_track(video_track, period, init_length,
                             video_protection_info, has_video_drm_streams,
                             cdn_index)

    common.fix_locale_languages(manifest['audio_tracks'])
    common.fix_locale_languages(manifest['timedtexttracks'])

    has_audio_drm_streams = manifest['audio_tracks'][0].get(
        'hasDrmStreams', False)

    id_default_audio_tracks = _get_id_default_audio_tracks(manifest)
    for audio_track in manifest['audio_tracks']:
        is_default = audio_track['id'] in id_default_audio_tracks
        _convert_audio_track(audio_track, period, init_length, is_default,
                             has_audio_drm_streams, cdn_index)

    for text_track in manifest['timedtexttracks']:
        if text_track['isNoneTrack']:
            continue
        is_default = _is_default_subtitle(manifest, text_track)
        _convert_text_track(text_track, period, is_default, cdn_index)

    xml = ET.tostring(root, encoding='utf-8', method='xml')
    if LOG.level == LOG.LEVEL_VERBOSE:
        common.save_file_def('manifest.mpd', xml)
    return xml.decode('utf-8').replace('\n', '').replace('\r',
                                                         '').encode('utf-8')