Пример #1
0
 def _process_refresh(self, data):
     """
     example data: {'playQueueID': '8475', 'commandID': '11'}
     """
     xml = get_pms_playqueue(data['playQueueID'])
     if xml is None:
         return
     if len(xml) == 0:
         LOG.debug('Empty playqueue received - clearing playqueue')
         plex_type = get_plextype_from_xml(xml)
         if plex_type is None:
             return
         playqueue = PQ.get_playqueue_from_type(
             v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type])
         playqueue.clear()
         return
     playqueue = PQ.get_playqueue_from_type(
         v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[xml[0].attrib['type']])
     PQ.update_playqueue_from_PMS(playqueue, data['playQueueID'])
Пример #2
0
 def _PMS_play(self):
     """
     For using direct paths: Initiates playback using the PMS
     """
     playqueue = PQ.get_playqueue_from_type(
         v.KODI_PLAYLIST_TYPE_FROM_KODI_TYPE[self.kodi_type])
     playqueue.clear()
     state.CONTEXT_MENU_PLAY = True
     handle = ('plugin://%s/?plex_id=%s&plex_type=%s&mode=play' %
               (v.ADDON_TYPE[self.plex_type], self.plex_id, self.plex_type))
     executebuiltin('RunPlugin(%s)' % handle)
Пример #3
0
 def _process_playlist(self, data):
     # Get the playqueue ID
     _, container_key, query = ParseContainerKey(data['containerKey'])
     try:
         playqueue = PQ.get_playqueue_from_type(
             v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[data['type']])
     except KeyError:
         # E.g. Plex web does not supply the media type
         # Still need to figure out the type (video vs. music vs. pix)
         xml = GetPlexMetadata(data['key'])
         try:
             xml[0].attrib
         except (AttributeError, IndexError, TypeError):
             LOG.error('Could not download Plex metadata')
             return
         api = API(xml[0])
         playqueue = PQ.get_playqueue_from_type(
             v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.plex_type()])
     PQ.update_playqueue_from_PMS(playqueue,
                                  playqueue_id=container_key,
                                  repeat=query.get('repeat'),
                                  offset=data.get('offset'),
                                  transient_token=data.get('token'))
 def _PMS_play(self):
     """
     For using direct paths: Initiates playback using the PMS
     """
     playqueue = PQ.get_playqueue_from_type(
         v.KODI_PLAYLIST_TYPE_FROM_KODI_TYPE[self.kodi_type])
     playqueue.clear()
     state.CONTEXT_MENU_PLAY = True
     params = {
         'mode': 'play',
         'plex_id': self.plex_id,
         'plex_type': self.plex_type
     }
     from urllib import urlencode
     handle = ("plugin://plugin.video.plexkodiconnect/movies?%s"
               % urlencode(params))
     executebuiltin('RunPlugin(%s)' % handle)
Пример #5
0
def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True):
    """
    Hit this function for addon path playback, Plex trailers, etc.
    Will setup playback first, then on second call complete playback.

    Will set Playback_Successful() with potentially a PKC_ListItem() attached
    (to be consumed by setResolvedURL in default.py)

    If trailers or additional (movie-)parts are added, default.py is released
    and a completely new player instance is called with a new playlist. This
    circumvents most issues with Kodi & playqueues

    Set resolve to False if you do not want setResolvedUrl to be called on
    the first pass - e.g. if you're calling this function from the original
    service.py Python instance
    """
    LOG.info('playback_triage called with plex_id %s, plex_type %s, path %s',
             plex_id, plex_type, path)
    if not state.AUTHENTICATED:
        LOG.error('Not yet authenticated for PMS, abort starting playback')
        if resolve is True:
            # Release default.py
            pickle_me(Playback_Successful())
        # "Unauthorized for PMS"
        dialog('notification', lang(29999), lang(30017))
        return
    playqueue = PQ.get_playqueue_from_type(
        v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type])
    pos = js.get_position(playqueue.playlistid)
    # Can return -1 (as in "no playlist")
    pos = pos if pos != -1 else 0
    LOG.debug('playQueue position: %s for %s', pos, playqueue)
    # Have we already initiated playback?
    try:
        playqueue.items[pos]
    except IndexError:
        # Release our default.py before starting our own Kodi player instance
        if resolve is True:
            state.PKC_CAUSED_STOP = True
            result = Playback_Successful()
            result.listitem = PKC_ListItem(path='PKC_Dummy_Path_Which_Fails')
            pickle_me(result)
        playback_init(plex_id, plex_type, playqueue)
    else:
        # kick off playback on second pass
        conclude_playback(playqueue, pos)
Пример #6
0
 def _process_streams(self, data):
     """
     Plex Companion client adjusted audio or subtitle stream
     """
     playqueue = PQ.get_playqueue_from_type(
         v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[data['type']])
     pos = js.get_position(playqueue.playlistid)
     if 'audioStreamID' in data:
         index = playqueue.items[pos].kodi_stream_index(
             data['audioStreamID'], 'audio')
         self.player.setAudioStream(index)
     elif 'subtitleStreamID' in data:
         if data['subtitleStreamID'] == '0':
             self.player.showSubtitles(False)
         else:
             index = playqueue.items[pos].kodi_stream_index(
                 data['subtitleStreamID'], 'subtitle')
             self.player.setSubtitleStream(index)
     else:
         LOG.error('Unknown setStreams command: %s', data)
Пример #7
0
 def _process_alexa(self, data):
     xml = GetPlexMetadata(data['key'])
     try:
         xml[0].attrib
     except (AttributeError, IndexError, TypeError):
         LOG.error('Could not download Plex metadata for: %s', data)
         return
     api = API(xml[0])
     if api.plex_type() == v.PLEX_TYPE_ALBUM:
         LOG.debug('Plex music album detected')
         PQ.init_playqueue_from_plex_children(
             api.plex_id(), transient_token=data.get('token'))
     elif data['containerKey'].startswith('/playQueues/'):
         _, container_key, _ = ParseContainerKey(data['containerKey'])
         xml = DownloadChunks('{server}/playQueues/%s?' % container_key)
         if xml is None:
             # "Play error"
             dialog('notification',
                    lang(29999),
                    lang(30128),
                    icon='{error}')
             return
         playqueue = PQ.get_playqueue_from_type(
             v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.plex_type()])
         playqueue.clear()
         get_playlist_details_from_xml(playqueue, xml)
         playqueue.plex_transient_token = data.get('token')
         if data.get('offset') != '0':
             offset = float(data['offset']) / 1000.0
         else:
             offset = None
         play_xml(playqueue, xml, offset)
     else:
         state.PLEX_TRANSIENT_TOKEN = data.get('token')
         if data.get('offset') != '0':
             state.RESUMABLE = True
             state.RESUME_PLAYBACK = True
         playback_triage(api.plex_id(), api.plex_type(), resolve=False)
Пример #8
0
def process_indirect(key, offset, resolve=True):
    """
    Called e.g. for Plex "Play later" - Plex items where we need to fetch an
    additional xml for the actual playurl. In the PMS metadata, indirect="1" is
    set.

    Will release default.py with setResolvedUrl

    Set resolve to False if playback should be kicked off directly, not via
    setResolvedUrl
    """
    LOG.info('process_indirect called with key: %s, offset: %s', key, offset)
    result = Playback_Successful()
    if key.startswith('http') or key.startswith('{server}'):
        xml = DU().downloadUrl(key)
    elif key.startswith('/system/services'):
        xml = DU().downloadUrl('http://node.plexapp.com:32400%s' % key)
    else:
        xml = DU().downloadUrl('{server}%s' % key)
    try:
        xml[0].attrib
    except (TypeError, IndexError, AttributeError):
        LOG.error('Could not download PMS metadata')
        if resolve is True:
            # Release default.py
            pickle_me(result)
        return
    if offset != '0':
        offset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(offset))
        # Todo: implement offset
    api = API(xml[0])
    listitem = PKC_ListItem()
    api.CreateListItemFromPlexItem(listitem)
    playqueue = PQ.get_playqueue_from_type(
        v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()])
    playqueue.clear()
    item = PL.Playlist_Item()
    item.xml = xml[0]
    item.offset = int(offset)
    item.plex_type = v.PLEX_TYPE_CLIP
    item.playmethod = 'DirectStream'
    # Need to get yet another xml to get the final playback url
    xml = DU().downloadUrl('http://node.plexapp.com:32400%s' %
                           xml[0][0][0].attrib['key'])
    try:
        xml[0].attrib
    except (TypeError, IndexError, AttributeError):
        LOG.error('Could not download last xml for playurl')
        if resolve is True:
            # Release default.py
            pickle_me(result)
        return
    playurl = xml[0].attrib['key']
    item.file = playurl
    listitem.setPath(tryEncode(playurl))
    playqueue.items.append(item)
    if resolve is True:
        result.listitem = listitem
        pickle_me(result)
    else:
        thread = Thread(target=Player().play,
                        args={
                            'item': tryEncode(playurl),
                            'listitem': listitem
                        })
        thread.setDaemon(True)
        LOG.info('Done initializing PKC playback, starting Kodi player')
        thread.start()