def _on_playback_started(self):
     player_id = _get_player_id()
     self._notify_all(ActionManager.call_on_playback_started,
                      self._get_player_state(player_id))
     if LOG.is_enabled and G.ADDON.getSettingBool('show_codec_info'):
         common.json_rpc('Input.ExecuteAction', {'action': 'codecinfo'})
     self.active_player_id = player_id
 def initialize(self, data):
     self.is_kodi_forced_subtitles_only = common.get_kodi_subtitle_language() == 'forced_only'
     self.is_prefer_alternative_lang = G.ADDON.getSettingBool('prefer_alternative_lang')
     self.is_prefer_sub_impaired = common.json_rpc('Settings.GetSettingValue',
                                                   {'setting': 'accessibility.subhearing'}).get('value')
     self.is_prefer_audio_impaired = common.json_rpc('Settings.GetSettingValue',
                                                     {'setting': 'accessibility.audiovisual'}).get('value')
예제 #3
0
 def remove_watched_status(self, videoid):
     """Remove the watched status from the Netflix service"""
     if not ui.ask_for_confirmation(
             common.get_local_string(30168),
             common.get_local_string(30300).format(
                 xbmc.getInfoLabel('ListItem.Label'))):
         return
     if not api.remove_watched_status(videoid):
         ui.show_notification(
             'The operation was cancelled due to an unexpected error')
         return
     # Check if item is in the cache
     videoid_exists, list_id = common.make_http_call(
         'get_continuewatching_videoid_exists',
         {'video_id': str(videoid.value)})
     if videoid_exists:
         # Try to remove the videoid from the list in the cache
         try:
             video_list_sorted_data = G.CACHE.get(cache_utils.CACHE_COMMON,
                                                  list_id)
             del video_list_sorted_data.videos[videoid.value]
             G.CACHE.add(cache_utils.CACHE_COMMON, list_id,
                         video_list_sorted_data)
             common.json_rpc(
                 'Input.Down')  # Avoids selection back to the top
         except CacheMiss:
             pass
     common.container_refresh()
예제 #4
0
 def my_list(self, videoid, pathitems):
     """Add or remove an item from my list"""
     operation = pathitems[1]
     api.update_my_list(videoid, operation, self.params)
     sync_library(videoid, operation)
     if operation == 'remove' and common.WndHomeProps[common.WndHomeProps.CURRENT_DIRECTORY_MENU_ID] == 'myList':
         common.json_rpc('Input.Down')  # Avoids selection back to the top
     common.container_refresh()
예제 #5
0
 def _on_playback_started(self):
     player_id = _get_player_id()
     self._notify_all(PlaybackActionManager.on_playback_started,
                      self._get_player_state(player_id))
     if common.is_debug_verbose() and g.ADDON.getSettingBool(
             'show_codec_info'):
         common.json_rpc('Input.ExecuteAction', {'action': 'codecinfo'})
     self.active_player_id = player_id
예제 #6
0
def _raspberry_disable_omxplayer():
    """Check and disable OMXPlayer (not compatible with Netflix video streams)"""
    # Only Kodi 18 has this property, from Kodi 19 OMXPlayer has been removed
    if not g.KODI_VERSION.is_major_ver('18'):
        return
    value = common.json_rpc('Settings.GetSettingValue', {'setting': 'videoplayer.useomxplayer'})
    if value.get('value'):
        common.json_rpc('Settings.SetSettingValue', {'setting': 'videoplayer.useomxplayer', 'value': False})
def _set_kodi_settings(system):
    """Method for self-configuring Kodi settings"""
    if system == 'android':
        # Media Codec hardware acceleration is mandatory, otherwise only the audio stream is played
        try:
            json_rpc('Settings.SetSettingValue', {'setting': 'videoplayer.usemediacodecsurface', 'value': True})
            json_rpc('Settings.SetSettingValue', {'setting': 'videoplayer.usemediacodec', 'value': True})
        except IOError as exc:
            LOG.error('Changing Kodi settings caused the following error: {}', exc)
예제 #8
0
 def _on_playback_started(self, data):
     # When UpNext addon play a video while we are inside Netflix addon and
     # not externally like Kodi library, the playerid become -1 this id does not exist
     player_id = data['player'][
         'playerid'] if data['player']['playerid'] > -1 else 1
     self.active_player_id = player_id
     self._notify_all(PlaybackActionManager.on_playback_started,
                      self._get_player_state())
     if common.is_debug_verbose() and g.ADDON.getSettingBool(
             'show_codec_info'):
         common.json_rpc('Input.ExecuteAction', {'action': 'codecinfo'})
예제 #9
0
def _remove_from_kodi_library(videoid):
    """Remove an item from the Kodi library."""
    common.info('Removing {} videoid from Kodi library', videoid)
    try:
        kodi_library_items = [get_item(videoid)]
        if videoid.mediatype == common.VideoId.SHOW or videoid.mediatype == common.VideoId.SEASON:
            # Retrieve the all episodes in the export folder
            filters = {
                'and': [{
                    'field': 'path',
                    'operator': 'startswith',
                    'value': os.path.dirname(kodi_library_items[0]['file'])
                }, {
                    'field': 'filename',
                    'operator': 'endswith',
                    'value': '.strm'
                }]
            }
            if videoid.mediatype == common.VideoId.SEASON:
                # Add a season filter in case we just want to remove a season
                filters['and'].append({
                    'field':
                    'season',
                    'operator':
                    'is',
                    'value':
                    str(kodi_library_items[0]['season'])
                })
            kodi_library_items = common.get_library_items(
                common.VideoId.EPISODE, filters)
        for item in kodi_library_items:
            rpc_params = {
                'movie': ['VideoLibrary.RemoveMovie', 'movieid'],
                # We should never remove an entire show
                # 'show': ['VideoLibrary.RemoveTVShow', 'tvshowid'],
                # Instead we delete all episodes listed in the JSON query above
                'show': ['VideoLibrary.RemoveEpisode', 'episodeid'],
                'season': ['VideoLibrary.RemoveEpisode', 'episodeid'],
                'episode': ['VideoLibrary.RemoveEpisode', 'episodeid']
            }[videoid.mediatype]
            common.debug(item)
            common.json_rpc(rpc_params[0],
                            {rpc_params[1]: item[rpc_params[1]]})
    except ItemNotFound:
        common.warn('Cannot remove {} from Kodi library, item not present',
                    videoid)
    except KeyError as exc:
        ui.show_notification(common.get_local_string(30120), time=7500)
        common.warn(
            'Cannot remove {} from Kodi library, Kodi does not support this (yet)',
            exc)
 def _find_subtitle_stream(self, audio_language, audio_list):
     # Check if there is an audio track available in the preferred audio language
     if not any(audio_track['language'] == audio_language
                for audio_track in audio_list):
         # No audio available for the preferred audio language,
         # then try find a regular subtitle in the preferred audio language
         subtitles_list = self.player_state.get(STREAMS['subtitle']['list'])
         # Take in account if a user have enabled Kodi impaired subtitles preference
         is_prefer_impaired = common.json_rpc(
             'Settings.GetSettingValue', {
                 'setting': 'accessibility.subhearing'
             }).get('value')
         stream = next((subtitle_track for subtitle_track in subtitles_list
                        if subtitle_track['language'] == audio_language
                        and not subtitle_track['isforced']
                        and subtitle_track['isimpaired']),
                       None) if is_prefer_impaired else None
         if not stream:
             stream = next((subtitle_track
                            for subtitle_track in subtitles_list
                            if subtitle_track['language'] == audio_language
                            and not subtitle_track['isforced']
                            and not subtitle_track['isimpaired']), None)
         return stream
     return None
예제 #11
0
    def _get_player_state(self, player_id=None):
        try:
            player_state = common.json_rpc(
                'Player.GetProperties', {
                    'playerid':
                    self.active_player_id or player_id,
                    'properties': [
                        'audiostreams', 'currentaudiostream',
                        'currentvideostream', 'subtitles', 'currentsubtitle',
                        'subtitleenabled', 'percentage', 'time'
                    ]
                })
        except IOError:
            return {}

        # Sometime may happen that when you stop playback, a player status without data is read,
        # so all dict values are returned with a default empty value,
        # then return an empty status instead of fake data
        if not player_state['audiostreams']:
            return {}

        # convert time dict to elapsed seconds
        player_state['elapsed_seconds'] = (
            player_state['time']['hours'] * 3600 +
            player_state['time']['minutes'] * 60 +
            player_state['time']['seconds'])

        return player_state
예제 #12
0
def _get_default_audio_language(manifest):
    channelList = {'1.0': '1', '2.0': '2'}
    channelListDolby = {'5.1': '6', '7.1': '8'}

    # Read language in kodi settings
    audio_language = common.json_rpc('Settings.GetSettingValue', {'setting': 'locale.audiolanguage'})
    audio_language = xbmc.convertLanguage(audio_language['value'], xbmc.ISO_639_1)
    audio_language = audio_language if audio_language else xbmc.getLanguage(xbmc.ISO_639_1, False)
    audio_language = audio_language if audio_language else 'en'

    # 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
                break
    # 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
            break

    # 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
                break
    # 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
            break
    return 0
예제 #13
0
def _remove_from_kodi_library(videoid):
    """Remove an item from the Kodi library."""
    common.debug('Removing {} videoid from Kodi library'.format(videoid))
    try:
        kodi_library_item = get_item(videoid)
        rpc_params = {
            'movie': ['VideoLibrary.RemoveMovie', 'movieid'],
            'show': ['VideoLibrary.RemoveTVShow', 'tvshowid'],
            'episode': ['VideoLibrary.RemoveEpisode', 'episodeid']
        }[videoid.mediatype]
        common.json_rpc(rpc_params[0],
                        {rpc_params[1]: kodi_library_item[rpc_params[1]]})
    except ItemNotFound:
        common.debug(
            'Cannot remove {} from Kodi library, item not present'.format(
                videoid))
    except KeyError as exc:
        ui.show_notification(common.get_local_string(30120), time=7500)
        common.warn('Cannot remove {} from Kodi library, '
                    'Kodi does not support this (yet)'.format(exc))
def auto_scroll(list_data):
    """
    Auto scroll the current viewed list to select the last partial watched or next episode to be watched,
    works only with Sync of watched status with netflix
    """
    # A sad implementation to a Kodi feature available only for the Kodi library
    if not g.ADDON.getSettingBool(
            'ProgressManager_enabled') or not g.ADDON.getSettingBool(
                'select_first_unwatched'):
        return
    total_items = len(list_data)
    if total_items:
        # Delay a bit to wait for the completion of the screen update
        xbmc.sleep(100)
        if not g.KODI_VERSION.is_major_ver(
                '18'):  # These infoLabel not works on Kodi 18.x
            # Check if view sort method is "Episode" (ID 23 = SortByEpisodeNumber)
            is_sort_method_episode = xbmc.getCondVisibility(
                'Container.SortMethod(23)')
            if not is_sort_method_episode:
                return
            # Check if a selection is already done (CurrentItem return the index)
            if int(xbmc.getInfoLabel('ListItem.CurrentItem') or 2) > 1:
                return
        # Check if all items are already watched
        watched_items = sum(dict_item['info'].get('PlayCount', '0') != '0'
                            for dict_item in list_data)
        to_resume_items = sum(
            dict_item.get('ResumeTime', '0') != '0' for dict_item in list_data)
        if total_items == watched_items or (watched_items +
                                            to_resume_items) == 0:
            return
        steps = _find_index_last_watched(total_items, list_data)
        # Get the sort order of the view
        is_sort_descending = xbmc.getCondVisibility(
            'Container.SortDirection(descending)')
        if is_sort_descending:
            steps = (total_items - 1) - steps
        gui_sound_mode = common.json_rpc(
            'Settings.GetSettingValue',
            {'setting': 'audiooutput.guisoundmode'})['value']
        if gui_sound_mode != 0:
            # Disable GUI sounds to avoid squirting sound with item selections
            common.json_rpc('Settings.SetSettingValue', {
                'setting': 'audiooutput.guisoundmode',
                'value': 0
            })
        # Auto scroll the list
        for _ in range(0, steps + 1):
            common.json_rpc('Input.Down')
        if gui_sound_mode != 0:
            # Restore GUI sounds
            common.json_rpc('Settings.SetSettingValue', {
                'setting': 'audiooutput.guisoundmode',
                'value': gui_sound_mode
            })
def _get_player_id():
    try:
        retry = 10
        while retry:
            result = common.json_rpc('Player.GetActivePlayers')
            if result:
                return result[0]['playerid']
            time.sleep(0.1)
            retry -= 1
        LOG.warn('Player ID not obtained, fallback to ID 1')
    except IOError:
        LOG.error('Player ID not obtained, fallback to ID 1')
    return 1
예제 #16
0
 def on_playback_stopped(self, player_state):
     # It could happen that Kodi does not assign as watched a video,
     # this because the credits can take too much time, then the point where playback is stopped
     # falls in the part that kodi recognizes as unwatched (playcountminimumpercent 90% + no-mans land 2%)
     # https://kodi.wiki/view/HOW-TO:Modify_automatic_watch_and_resume_points#Settings_explained
     # In these cases we try change/fix manually the watched status of the video by using netflix offset data
     if int(player_state['percentage']) > 92:
         return
     if not self.watched_threshold or not player_state[
             'elapsed_seconds'] > self.watched_threshold:
         return
     if G.ADDON.getSettingBool(
             'sync_watched_status') and not self.is_played_from_strm:
         # This have not to be applied with our custom watched status of Netflix sync, within the addon
         return
     if self.is_played_from_strm:
         # The current video played is a STRM, then generate the path of a STRM file
         file_path = G.SHARED_DB.get_episode_filepath(
             self.videoid.tvshowid, self.videoid.seasonid,
             self.videoid.episodeid)
         url = xbmcvfs.translatePath(file_path)
         common.json_rpc('Files.SetFileDetails', {
             "file": url,
             "media": "video",
             "resume": None,
             "playcount": 1
         })
     else:
         url = common.build_url(
             videoid=self.videoid,
             mode=G.MODE_PLAY,
             params={'profile_guid': G.LOCAL_DB.get_active_profile_guid()})
         common.json_rpc('Files.SetFileDetails', {
             "file": url,
             "media": "video",
             "resume": None,
             "playcount": 1
         })
     LOG.info('Has been fixed the watched status of the video: {}', url)
예제 #17
0
def auto_scroll(dir_items):
    """
    Auto scroll the current viewed list to select the last partial watched or next episode to be watched,
    works only with Sync of watched status with netflix
    """
    # A sad implementation to a Kodi feature available only for the Kodi library
    if G.ADDON.getSettingBool(
            'sync_watched_status') and G.ADDON.getSettingBool(
                'select_first_unwatched'):
        total_items = len(dir_items)
        if total_items:
            # Delay a bit to wait for the completion of the screen update
            xbmc.sleep(200)
            if not _auto_scroll_init_checks():
                return
            # Check if all items are already watched
            watched_items = 0
            to_resume_items = 0
            for _, list_item, _ in dir_items:
                watched_items += list_item.getVideoInfoTag().getPlayCount(
                ) != 0
                to_resume_items += float(
                    list_item.getProperty('ResumeTime')) != 0
            if total_items == watched_items or (watched_items +
                                                to_resume_items) == 0:
                return
            steps = _find_index_last_watched(total_items, dir_items)
            # Get the sort order of the view
            is_sort_descending = xbmc.getCondVisibility(
                'Container.SortDirection(descending)')
            if is_sort_descending:
                steps = (total_items - 1) - steps
            gui_sound_mode = common.json_rpc(
                'Settings.GetSettingValue',
                {'setting': 'audiooutput.guisoundmode'})['value']
            if gui_sound_mode != 0:
                # Disable GUI sounds to avoid squirting sound with item selections
                common.json_rpc('Settings.SetSettingValue', {
                    'setting': 'audiooutput.guisoundmode',
                    'value': 0
                })
            # Auto scroll the list
            for _ in range(0, steps + 1):
                common.json_rpc('Input.Down')
            if gui_sound_mode != 0:
                # Restore GUI sounds
                common.json_rpc('Settings.SetSettingValue', {
                    'setting': 'audiooutput.guisoundmode',
                    'value': gui_sound_mode
                })
예제 #18
0
def _get_default_subtitle_language(manifest):
    subtitle_language = common.json_rpc('Settings.GetSettingValue', {'setting': 'locale.subtitlelanguage'})
    if subtitle_language['value'] == 'forced_only':
        # Leave the selection of forced subtitles to kodi
        return -1
    else:
        subtitle_language = xbmc.convertLanguage(subtitle_language['value'].encode('utf-8'), xbmc.ISO_639_1)
        subtitle_language = subtitle_language if subtitle_language else xbmc.getLanguage(xbmc.ISO_639_1, False)
        subtitle_language = subtitle_language if subtitle_language else 'en'

        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_player_state(self, player_id=None, time_override=None):
        try:
            player_state = common.json_rpc(
                'Player.GetProperties', {
                    'playerid':
                    self.active_player_id if player_id is None else player_id,
                    'properties': [
                        'audiostreams', 'currentaudiostream',
                        'currentvideostream', 'subtitles', 'currentsubtitle',
                        'subtitleenabled', 'percentage', 'time'
                    ]
                })
        except IOError as exc:
            LOG.warn('_get_player_state: {}', exc)
            return {}

        # convert time dict to elapsed seconds
        player_state['elapsed_seconds'] = (
            player_state['time']['hours'] * 3600 +
            player_state['time']['minutes'] * 60 +
            player_state['time']['seconds'])

        if time_override:
            player_state['time'] = time_override
            elapsed_seconds = (time_override['hours'] * 3600 +
                               time_override['minutes'] * 60 +
                               time_override['seconds'])
            player_state[
                'percentage'] = player_state['percentage'] / player_state[
                    'elapsed_seconds'] * elapsed_seconds
            player_state['elapsed_seconds'] = elapsed_seconds

        # Sometimes may happen that when you stop playback the player status is partial,
        # this is because the Kodi player stop immediately but the stop notification (from the Monitor)
        # arrives late, meanwhile in this interval of time a service tick may occur.
        if ((player_state['audiostreams'] and player_state['elapsed_seconds'])
                or (player_state['audiostreams']
                    and not player_state['elapsed_seconds']
                    and not self._last_player_state)):
            # save player state
            self._last_player_state = player_state
        else:
            # use saved player state
            player_state = self._last_player_state

        return player_state
예제 #20
0
 def _seasons(self, videoid, pathitems):
     """Show the seasons list of a tv show"""
     call_args = {
         'pathitems': pathitems,
         'tvshowid_dict': videoid.to_dict(),
         'perpetual_range_start': self.perpetual_range_start,
     }
     list_data, extra_data = common.make_call('get_seasons', call_args)
     if len(list_data) == 1:
         # Check if Kodi setting "Flatten TV show seasons" is enabled
         value = common.json_rpc('Settings.GetSettingValue',
                                 {'setting': 'videolibrary.flattentvshows'}).get('value')
         if value != 0:  # Values: 0=never, 1=if one season, 2=always
             # If there is only one season, load and show the episodes now
             pathitems = list_data[0]['url'].replace(G.BASE_URL, '').strip('/').split('/')[1:]
             videoid = common.VideoId.from_path(pathitems)
             self._episodes(videoid, pathitems)
             return
     self._seasons_directory(list_data, extra_data)
예제 #21
0
    def _get_player_state(self):
        try:
            player_state = common.json_rpc(
                'Player.GetProperties', {
                    'playerid':
                    self.active_player_id,
                    'properties': [
                        'audiostreams', 'currentaudiostream', 'subtitles',
                        'currentsubtitle', 'subtitleenabled', 'percentage',
                        'time'
                    ]
                })
        except IOError:
            return {}

        # convert time dict to elapsed seconds
        player_state['elapsed_seconds'] = (
            player_state['time']['hours'] * 3600 +
            player_state['time']['minutes'] * 60 +
            player_state['time']['seconds'])

        return player_state
예제 #22
0
def play(videoid):
    """Play an episode or movie as specified by the path"""
    is_upnext_enabled = g.ADDON.getSettingBool('UpNextNotifier_enabled')
    # For db settings 'upnext_play_callback_received' and 'upnext_play_callback_file_type' see action_controller.py
    is_upnext_callback_received = g.LOCAL_DB.get_value(
        'upnext_play_callback_received', False)
    is_upnext_callback_file_type_strm = g.LOCAL_DB.get_value(
        'upnext_play_callback_file_type', '') == 'strm'
    # This is the only way found to know if the played item come from the add-on itself or from Kodi library
    # also when Up Next Add-on is used
    is_played_from_addon = not g.IS_ADDON_EXTERNAL_CALL or (
        g.IS_ADDON_EXTERNAL_CALL and is_upnext_callback_received
        and not is_upnext_callback_file_type_strm)
    common.info('Playing {} from {} (Is Up Next Add-on call: {})', videoid,
                'add-on' if is_played_from_addon else 'external call',
                is_upnext_callback_received)

    metadata = [{}, {}]
    try:
        metadata = api.get_metadata(videoid)
        common.debug('Metadata is {}', metadata)
    except MetadataNotAvailable:
        common.warn('Metadata not available for {}', videoid)

    # Parental control PIN
    pin_result = _verify_pin(metadata[0].get('requiresPin', False))
    if not pin_result:
        if pin_result is not None:
            ui.show_notification(common.get_local_string(30106), time=8000)
        xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False)
        return

    list_item = get_inputstream_listitem(videoid)
    resume_position = None
    info_data = None
    event_data = {}
    videoid_next_episode = None

    if not is_played_from_addon or is_upnext_enabled:
        if is_upnext_enabled and videoid.mediatype == common.VideoId.EPISODE:
            # When UpNext is enabled, get the next episode to play
            videoid_next_episode = _upnext_get_next_episode_videoid(
                videoid, metadata)
        info_data = infolabels.get_info_from_netflix(
            [videoid, videoid_next_episode]
            if videoid_next_episode else [videoid])
        info, arts = info_data[videoid.value]
        # When a item is played from Kodi library or Up Next add-on is needed set info and art to list_item
        list_item.setInfo('video', info)
        list_item.setArt(arts)

    if not is_played_from_addon:
        # Workaround for resuming strm files from library
        resume_position = (
            infolabels.get_resume_info_from_library(videoid).get('position')
            if g.ADDON.getSettingBool('ResumeManager_enabled') else None)
        if resume_position:
            index_selected = (ui.ask_for_resume(resume_position)
                              if g.ADDON.getSettingBool('ResumeManager_dialog')
                              else None)
            if index_selected == -1:
                xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                                          succeeded=False,
                                          listitem=list_item)
                return
            if index_selected == 1:
                resume_position = None

    if (g.ADDON.getSettingBool('ProgressManager_enabled') and videoid.mediatype
            in [common.VideoId.MOVIE, common.VideoId.EPISODE]
            and is_played_from_addon):
        # Enable the progress manager only when:
        # - It is not an add-on external call
        # - It is an external call, but the played item is not a STRM file
        # Todo:
        #  in theory to enable in Kodi library need implement the update watched status code for items of Kodi library
        #  by using JSON RPC Files.SetFileDetails https://github.com/xbmc/xbmc/pull/17202
        #  that can be used only on Kodi 19.x
        event_data = _get_event_data(videoid)
        event_data['videoid'] = videoid.to_dict()
        event_data['is_played_by_library'] = not is_played_from_addon

    if 'raspberrypi' in common.get_system_platform(
    ) and g.KODI_VERSION.is_major_ver('18'):
        # OMX Player is not compatible with netflix video streams
        # Only Kodi 18 has this property, on Kodi 19 Omx Player has been removed
        value = common.json_rpc('Settings.GetSettingValue',
                                {'setting': 'videoplayer.useomxplayer'})
        if value.get('value'):
            common.json_rpc('Settings.SetSettingValue', {
                'setting': 'videoplayer.useomxplayer',
                'value': False
            })

    xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                              succeeded=True,
                              listitem=list_item)

    g.LOCAL_DB.set_value('last_videoid_played',
                         videoid.to_dict(),
                         table=TABLE_SESSION)

    common.debug('Sending initialization signal')
    common.send_signal(common.Signals.PLAYBACK_INITIATED, {
        'videoid':
        videoid.to_dict(),
        'videoid_next_episode':
        videoid_next_episode.to_dict() if videoid_next_episode else None,
        'metadata':
        metadata,
        'info_data':
        info_data,
        'is_played_from_addon':
        is_played_from_addon,
        'resume_position':
        resume_position,
        'event_data':
        event_data,
        'is_upnext_callback_received':
        is_upnext_callback_received
    },
                       non_blocking=True)
예제 #23
0
def play(videoid):
    """Play an episode or movie as specified by the path"""
    common.info('Playing {}', videoid)
    is_up_next_enabled = g.ADDON.getSettingBool('UpNextNotifier_enabled')
    metadata = [{}, {}]
    try:
        metadata = api.metadata(videoid)
        common.debug('Metadata is {}', metadata)
    except MetadataNotAvailable:
        common.warn('Metadata not available for {}', videoid)

    # Parental control PIN
    pin_result = _verify_pin(metadata[0].get('requiresPin', False))
    if not pin_result:
        if pin_result is not None:
            ui.show_notification(common.get_local_string(30106), time=10000)
        xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False)
        return

    list_item = get_inputstream_listitem(videoid)
    infos, art = infolabels.add_info_for_playback(
        videoid, list_item, is_up_next_enabled, skip_set_progress_status=True)

    resume_position = {}
    event_data = {}

    if g.IS_SKIN_CALL:
        # Workaround for resuming strm files from library
        resume_position = infos.get('resume', {}).get('position') \
            if g.ADDON.getSettingBool('ResumeManager_enabled') else None
        if resume_position:
            index_selected = ui.ask_for_resume(
                resume_position) if g.ADDON.getSettingBool(
                    'ResumeManager_dialog') else None
            if index_selected == -1:
                xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                                          succeeded=False,
                                          listitem=list_item)
                return
            if index_selected == 1:
                resume_position = None
    elif (g.ADDON.getSettingBool('ProgressManager_enabled') and
          videoid.mediatype in [common.VideoId.MOVIE, common.VideoId.EPISODE]):
        # To now we have this limits:
        # - enabled only with items played inside the addon then not Kodi library, need impl. JSON-RPC lib update code
        event_data = _get_event_data(videoid)
        event_data['videoid'] = videoid.to_dict()
        event_data['is_played_by_library'] = g.IS_SKIN_CALL
        # Todo: UpNext addon is incompatible with netflix watched status sync feature
        #  Problems:
        #  - Need to modify the cache (to update the watched status) on every played item
        #  - Modifying the cache after the stop, is wrong due to below problems
        #  - The new fast play, 'play_url' method, cause problems with the Player callbacks, after press play next is missing the Stop event in the controller!
        #  - To verify possibility problems of data mixing of controller._get_player_state()
        #  - The call of next video from UpNext is recognized as Skin call, because it's an external addon call, so it causes several operating problems
        is_up_next_enabled = False

    if 'raspberrypi' in common.get_system_platform(
    ) and '18' in common.GetKodiVersion().version:
        # OMX Player is not compatible with netflix video streams
        # Only Kodi 18 has this property, on Kodi 19 Omx Player has been removed
        value = common.json_rpc('Settings.GetSettingValue',
                                {'setting': 'videoplayer.useomxplayer'})
        if value.get('value'):
            common.json_rpc('Settings.SetSettingValue', {
                'setting': 'videoplayer.useomxplayer',
                'value': False
            })

    xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                              succeeded=True,
                              listitem=list_item)

    upnext_info = get_upnext_info(videoid, (infos, art),
                                  metadata) if is_up_next_enabled else None

    g.LOCAL_DB.set_value('last_videoid_played',
                         videoid.to_dict(),
                         table=TABLE_SESSION)

    common.debug('Sending initialization signal')
    common.send_signal(common.Signals.PLAYBACK_INITIATED, {
        'videoid': videoid.to_dict(),
        'infos': infos,
        'art': art,
        'timeline_markers': get_timeline_markers(metadata[0]),
        'upnext_info': upnext_info,
        'resume_position': resume_position,
        'event_data': event_data
    },
                       non_blocking=True)
예제 #24
0
def search_remove(row_id):
    """Remove a search item"""
    LOG.debug('Removing search item with ID {}', row_id)
    G.LOCAL_DB.delete_search_item(row_id)
    common.json_rpc('Input.Down')  # Avoids selection back to the top
    common.container_refresh()