예제 #1
0
    def getTrailer(embyServer, itemId, itemObj, allowDirectPlay=True):
        # prefer local trailers if direct play is allowed
        if allowDirectPlay and itemObj.get(
                constants.PROPERTY_ITEM_LOCAL_TRAILER_COUNT, 0):
            localTrailers = Library.GetLocalTrailers(embyServer, itemId)
            if not localTrailers:
                log('failed to retrieve local trailers for item with ID {}'.
                    format(itemId))
            else:
                localTrailerUrl = Api.getPlaybackUrl(
                    embyServer,
                    itemId,
                    localTrailers[0],
                    allowDirectPlay=allowDirectPlay)
                if localTrailerUrl:
                    return localTrailerUrl

        # otherwise use the first remote trailer
        if constants.PROPERTY_ITEM_REMOTE_TRAILERS in itemObj:
            remoteTrailers = itemObj.get(
                constants.PROPERTY_ITEM_REMOTE_TRAILERS)
            if remoteTrailers:
                return remoteTrailers[0].get(
                    constants.PROPERTY_ITEM_REMOTE_TRAILERS_URL, None)

        return None
예제 #2
0
def settingOptionsFillerViews(handle, options):
    # retrieve the media provider
    mediaProvider = xbmcmediaimport.getProvider(handle)
    if not mediaProvider:
        log('cannot retrieve media provider', xbmc.LOGERROR)
        return

    # retrieve the media import
    mediaImport = xbmcmediaimport.getImport(handle)
    if not mediaImport:
        log('cannot retrieve media import', xbmc.LOGERROR)
        return

    # prepare the media provider settings
    if not mediaProvider.prepareSettings():
        log('cannot prepare media provider settings', xbmc.LOGERROR)
        return

    embyServer = Server(mediaProvider)
    if not embyServer.Authenticate():
        log('failed to authenticate on media provider {}'.format(mediaProvider2str(mediaProvider)), xbmc.LOGERROR)
        return

    libraryViews = Library.GetViews(embyServer, mediaImport.getMediaTypes())
    views = []
    for libraryView in libraryViews:
        views.append((libraryView.name, libraryView.id))

    # get the import's settings
    settings = mediaImport.getSettings()

    # pass the list of views back to Kodi
    settings.setStringOptions(emby.constants.SETTING_IMPORT_VIEWS_SPECIFIC, views)
예제 #3
0
    def _addExternalSubtitles(self):
        if not self._item:
            return

        # get the item's details to look for external subtitles
        itemObj = Library.GetItem(self._server, self._itemId)
        if not itemObj:
            Player.log('cannot retrieve details of "{}" ({}) from media provider {}' \
                .format(self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING)
            return

        # extract the media source ID
        if not PROPERTY_ITEM_MEDIA_SOURCES in itemObj or not itemObj[
                PROPERTY_ITEM_MEDIA_SOURCES]:
            Player.log('cannot add external subtitles for "{}" ({}) from media provider {} ' \
                'because it doesn\'t have a media source' \
                .format(self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)), xbmc.LOGDEBUG)
            return

        mediaSourceId = itemObj.get(PROPERTY_ITEM_MEDIA_SOURCES)[0].get(
            PROPERTY_ITEM_MEDIA_SOURCES_ID)

        # look for external subtitles
        for stream in itemObj.get(PROPERTY_ITEM_MEDIA_STREAMS):
            if stream.get(PROPERTY_ITEM_MEDIA_STREAM_TYPE
                          ) != 'Subtitle' or not stream.get(
                              PROPERTY_ITEM_MEDIA_STREAM_IS_EXTERNAL):
                continue

            # get the index of the subtitle
            index = stream.get(PROPERTY_ITEM_MEDIA_STREAM_INDEX)

            # determine the language and name
            name = stream.get(
                PROPERTY_ITEM_MEDIA_STREAM_DISPLAY_TITLE
            ) if PROPERTY_ITEM_MEDIA_STREAM_DISPLAY_TITLE in stream else ''
            language = stream.get(
                PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE
            ) if PROPERTY_ITEM_MEDIA_STREAM_LANGUAGE in stream else ''

            # determine the stream URL
            if PROPERTY_ITEM_MEDIA_STREAM_DELIVERY_URL in stream and \
                stream.get(PROPERTY_ITEM_MEDIA_STREAM_DELIVERY_URL).upper().startswith('/{}'.format(URL_VIDEOS)):
                url = self._server.BuildStreamDeliveryUrl(
                    stream.get(PROPERTY_ITEM_MEDIA_STREAM_DELIVERY_URL))
            else:
                url = self._server.BuildSubtitleStreamUrl(
                    self._itemId, mediaSourceId, index,
                    stream.get(PROPERTY_ITEM_MEDIA_STREAM_CODEC))

            if not url:
                Player.log('cannot add external subtitle at index {} for "{}" ({}) from media provider {}' \
                .format(index, self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)), xbmc.LOGWARNING)
                continue

            self.addSubtitle(url, name, language,
                             False)  # TODO(Montellese): activate?
            Player.log('external subtitle "{}" [{}] at index {} added for "{}" ({}) from media provider {}' \
                .format(name, language, index, self._item.getLabel(), self._file, mediaProvider2str(self._mediaProvider)))
예제 #4
0
def refreshMetadata(item, itemId, mediaProvider):
    # create an Emby server instance
    embyServer = Server(mediaProvider)

    # trigger a metadata refresh on the Emby server
    Library.RefreshItemMetadata(embyServer, itemId)
    log('[context/refresh] triggered metadata refresh for {} on {}'.format(
        listItem2str(item, itemId), mediaProvider2str(mediaProvider)))
예제 #5
0
    def _GetItemDetails(self, itemId):
        # retrieve all details of the item
        itemObj = Library.GetItem(self._server, itemId)
        if not itemObj:
            ProviderObserver.log(
                'cannot retrieve details of updated item with id "{}" from {}'.
                format(itemId,
                       mediaProvider2str(self._mediaProvider)), xbmc.LOGERROR)
            return None

        return kodi.Api.toFileItem(
            self._server,
            itemObj,
            allowDirectPlay=self._settings.getBool(
                SETTING_PROVIDER_PLAYBACK_ALLOW_DIRECT_PLAY))
예제 #6
0
def getMatchingLibraryViews(embyServer, mediaTypes, selectedViews):
    if not embyServer:
        raise ValueError('invalid emby server')
    if not mediaTypes:
        raise ValueError('invalid mediaTypes')

    libraryViews = Library.GetViews(embyServer, mediaTypes)

    matchingLibraryViews = []
    if not selectedViews:
        matchingLibraryViews = libraryViews
    else:
        matchingLibraryViews = [ libraryView for libraryView in libraryViews if libraryView.id in selectedViews ]

    return matchingLibraryViews
예제 #7
0
def getLibraryViews(embyServer, mediaTypes):
    if not embyServer:
        raise ValueError('invalid emby server')
    if not mediaTypes:
        raise ValueError('invalid mediaTypes')

    # check whether to include mixed libraries
    includeMixed = False
    for mediaType in mediaTypes:
        (_, _, mixed, _) = kodi.Api.getEmbyMediaType(mediaType)
        if mixed:
            includeMixed = True
            break

    return Library.GetViews(embyServer, mediaTypes, includeMixed=includeMixed)
예제 #8
0
def synchronizeItem(item,
                    itemId,
                    mediaProvider,
                    embyServer,
                    allowDirectPlay=True):
    # retrieve all details of the item
    itemObj = Library.GetItem(embyServer, itemId)
    if not itemObj:
        log(
            '[context/sync] cannot retrieve details of {} from {}'.format(
                listItem2str(item, itemId), mediaProvider2str(mediaProvider)),
            xbmc.LOGERROR)
        return None

    return kodi.Api.toFileItem(embyServer,
                               itemObj,
                               allowDirectPlay=allowDirectPlay)
예제 #9
0
def updateOnProvider(handle, options):
    # retrieve the media import
    mediaImport = xbmcmediaimport.getImport(handle)
    if not mediaImport:
        log('cannot retrieve media import', xbmc.LOGERROR)
        return

    # retrieve the media provider
    mediaProvider = mediaImport.getProvider()
    if not mediaProvider:
        log('cannot retrieve media provider', xbmc.LOGERROR)
        return

    # prepare and get the media import settings
    importSettings = mediaImport.prepareSettings()
    if not importSettings:
        log('cannot prepare media import settings', xbmc.LOGERROR)
        return

    item = xbmcmediaimport.getUpdatedItem(handle)
    if not item:
        log('cannot retrieve updated item', xbmc.LOGERROR)
        return

    log('updating "{}" ({}) on {}...'.format(item.getLabel(), item.getPath(), mediaProvider2str(mediaProvider)))

    itemVideoInfoTag = item.getVideoInfoTag()
    if not itemVideoInfoTag:
        log('updated item is not a video item', xbmc.LOGERROR)
        return

    # determine the item's identifier
    itemId = kodi.Api.getEmbyItemIdFromVideoInfoTag(itemVideoInfoTag)
    if not itemId:
        log('cannot determine the identifier of the updated item: "{}"'.format(itemVideoInfoTag.getPath()), xbmc.LOGERROR)
        return

    # prepare the media provider settings
    if not mediaProvider.prepareSettings():
        log('cannot prepare media provider settings', xbmc.LOGERROR)
        return

    # create an Emby server instance
    embyServer = Server(mediaProvider)
    if not embyServer.Authenticate():
        log('failed to authenticate on media provider {}'.format(mediaProvider2str(mediaProvider)), xbmc.LOGERROR)
        return

    # retrieve all details of the item
    itemObj = Library.GetItem(embyServer, itemId)
    if not itemObj:
        log('cannot retrieve details of updated item with id {}'.format(itemId), xbmc.LOGERROR)
        return

    if not emby.constants.PROPERTY_ITEM_USER_DATA in itemObj:
        log('cannot update item with id {} because it has no userdata'.format(itemId), xbmc.LOGERROR)
        return

    updateItemPlayed = False
    updatePlaybackPosition = False
    # retrieve playback states from the updated item
    playcount = itemVideoInfoTag.getPlayCount()
    watched = playcount > 0
    lastPlayed = itemVideoInfoTag.getLastPlayed()
    # retrieve playback position from the updated item
    playbackPositionInSeconds = max(0.0, float(item.getProperty('resumetime')))
    playbackPositionInTicks = kodi.Api.secondsToTicks(playbackPositionInSeconds)

    userDataObj = itemObj[emby.constants.PROPERTY_ITEM_USER_DATA]

    # check and update playcout if necessary
    if emby.constants.PROPERTY_ITEM_USER_DATA_PLAY_COUNT in userDataObj:
        # retrieve playcount from the original item
        itemPlayed = userDataObj[emby.constants.PROPERTY_ITEM_USER_DATA_PLAY_COUNT] > 0

        if watched != itemPlayed:
            updateItemPlayed = True

    # check and update playback position if necessary
    if emby.constants.PROPERTY_ITEM_USER_DATA_PLAYBACK_POSITION_TICKS in userDataObj:
        # retrieve playback position from the original item
        itemPlaybackPositionInTicks = userDataObj[emby.constants.PROPERTY_ITEM_USER_DATA_PLAYBACK_POSITION_TICKS]

        if playbackPositionInTicks != itemPlaybackPositionInTicks:
            updatePlaybackPosition = True

    # nothing to do if no playback related properties have been changed
    if not updateItemPlayed and not updatePlaybackPosition:
        log('no playback related properties of "{}" ({}) have changed => nothing to update on {}'.format(item.getLabel(), item.getPath(), mediaProvider2str(mediaProvider)))
        return

    log('updating playback related properties of "{}" ({}) on {}...'.format(item.getLabel(), item.getPath(), mediaProvider2str(mediaProvider)))
    if not UserData.Update(embyServer, itemId, updateItemPlayed, updatePlaybackPosition, watched, playcount, lastPlayed, playbackPositionInTicks):
        log('updating playback related properties of "{}" ({}) on {} failed'.format(item.getLabel(), item.getPath(), mediaProvider2str(mediaProvider)), xbmc.LOGERROR)

    xbmcmediaimport.finishUpdateOnProvider(handle)
예제 #10
0
def play(item, itemId, mediaProvider):
    if item.isFolder():
        log(
            '[context/play] cannot play folder item {}'.format(
                listItem2str(item, itemId)), xbmc.LOGERROR)
        return

    # create an Emby server instance
    embyServer = Server(mediaProvider)

    # retrieve all details of the item
    itemObj = Library.GetItem(embyServer, itemId)
    if not itemObj:
        log(
            '[context/play] cannot retrieve the details of {} from {}'.format(
                listItem2str(item, itemId), mediaProvider2str(mediaProvider)),
            xbmc.LOGERROR)
        return

    # cannot play folders
    if itemObj.get(emby.constants.PROPERTY_ITEM_IS_FOLDER):
        log(
            '[context/play] cannot play folder item {}'.format(
                listItem2str(item, itemId)), xbmc.LOGERROR)
        return

    playChoices = []
    playChoicesUrl = []

    # determine whether Direct Play is allowed
    mediaProviderSettings = mediaProvider.getSettings()
    allowDirectPlay = mediaProviderSettings.getBool(
        emby.constants.SETTING_PROVIDER_PLAYBACK_ALLOW_DIRECT_PLAY)

    # check if the item supports Direct Play and / or Direct Stream
    canDirectPlay = None
    directPlayUrl = None
    if allowDirectPlay:
        (canDirectPlay, directPlayUrl) = kodi.Api.getDirectPlayUrl(itemObj)

        if canDirectPlay and directPlayUrl:
            playChoices.append(localise(32101))
            playChoicesUrl.append(directPlayUrl)

    (canDirectStream,
     directStreamUrl) = kodi.Api.getDirectStreamUrl(embyServer, itemId,
                                                    itemObj)
    if canDirectStream:
        playChoices.append(localise(32102))
        playChoicesUrl.append(directStreamUrl)

    # if there are no options something went wrong
    if not playChoices:
        log(
            '[context/play] cannot play {} from {}'.format(
                listItem2str(item, itemId), mediaProvider2str(mediaProvider)),
            xbmc.LOGERROR)
        return

    # ask the user how to play
    playChoice = Dialog().contextmenu(playChoices)
    if playChoice < 0 or playChoice >= len(playChoices):
        return

    playUrl = playChoicesUrl[playChoice]

    # play the item
    log('[context/play] playing {} using "{}" ({}) from {}'.format(
        listItem2str(item, itemId), playChoices[playChoice], playUrl,
        mediaProvider2str(mediaProvider)))
    # overwrite the dynamic path of the ListItem
    item.setDynamicPath(playUrl)
    xbmc.Player().play(playUrl, item)