Ejemplo n.º 1
0
def refreshMetadata(item: ListItem, itemId: int, mediaProvider: xbmcmediaimport.MediaProvider):
    # create a Plex server instance
    server = Server(mediaProvider)
    if not server.Authenticate():
        contextLog(
            f"failed to connect to Plex Media Server for {mediaProvider2str(mediaProvider)}",
            xbmc.LOGWARNING, entry='refresh')
        return

    plexItemClass = Api.getPlexMediaClassFromListItem(item)

    # get the Plex item with all its details
    plexItem = Api.getPlexItemDetails(server.PlexServer(), itemId, plexItemClass=plexItemClass)
    if not plexItem:
        contextLog(
            f"failed to determine Plex item for {listItem2str(item, itemId)} from {mediaProvider2str(mediaProvider)}",
            xbmc.LOGWARNING, entry='refresh')
        return
    # trigger a metadata refresh on the Plex server
    plexItem.refresh()
    contextLog(
        f"triggered metadata refresh for {listItem2str(item, itemId)} on {mediaProvider2str(mediaProvider)}",
        entry="refresh")
Ejemplo n.º 2
0
def synchronize(item: ListItem, itemId: int, mediaProvider):
    # find the matching media import
    mediaImport = getMediaImport(mediaProvider, item)
    if not mediaImport:
        contextLog(
            f"cannot find the media import of {listItem2str(item, itemId)} from {mediaProvider2str(mediaProvider)}",
            xbmc.LOGERROR, entry='sync')
        return

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

    # create a Plex server instance
    server = Server(mediaProvider)
    if not server.Authenticate():
        contextLog(
            f"failed to connect to Plex Media Server for {mediaProvider2str(mediaProvider)}",
            xbmc.LOGWARNING, entry='sync')
        return

    plexItemClass = Api.getPlexMediaClassFromListItem(item)

    # synchronize the active item
    syncedItem = synchronizeItem(item, itemId, mediaProvider, server.PlexServer(), plexItemClass=plexItemClass,
                                 allowDirectPlay=allowDirectPlay)
    if not syncedItem:
        return
    syncedItems = [(xbmcmediaimport.MediaImportChangesetTypeChanged, syncedItem)]

    if xbmcmediaimport.changeImportedItems(mediaImport, syncedItems):
        contextLog(f"synchronized {listItem2str(item, itemId)} from {mediaProvider2str(mediaProvider)}", entry='sync')
    else:
        contextLog(
            f"failed to synchronize {listItem2str(item, itemId)} from {mediaProvider2str(mediaProvider)}",
            xbmc.LOGWARNING, entry='sync')
Ejemplo n.º 3
0
def play(item, itemId, mediaProvider):
    if item.isFolder():
        contextLog(f"cannot play folder item {listItem2str(item, itemId)}", xbmc.LOGERROR, entry='play')
        return

    # create a Plex server instance
    server = Server(mediaProvider)
    if not server.Authenticate():
        contextLog(
            f"failed to connect to Plex Media Server for {mediaProvider2str(mediaProvider)}",
            xbmc.LOGWARNING, entry='sync')
        return

    plexItemClass = Api.getPlexMediaClassFromListItem(item)

    # cannot play folders
    if plexItemClass in (collection.Collection, video.Show, video.Season):
        contextLog(f"cannot play folder item {listItem2str(item, itemId)}", xbmc.LOGERROR, entry='play')
        return

    # get the Plex item with all its details
    plexItem = Api.getPlexItemDetails(server.PlexServer(), itemId, plexItemClass=plexItemClass)
    if not plexItem:
        contextLog(
            f"failed to determine Plex item for {listItem2str(item, itemId)} from {mediaProvider2str(mediaProvider)}",
            xbmc.LOGWARNING, entry='refresh')
        return

    # cannot play folders
    if not Api.canPlay(plexItem):
        contextLog(f"cannot play item {listItem2str(item, itemId)}", xbmc.LOGERROR, entry='play')
        return

    playChoices = []
    playChoicesUrl = []

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

    # check if the item supports Direct Play
    if allowDirectPlay:
        directPlayUrl = Api.getDirectPlayUrlFromPlexItem(plexItem)
        if directPlayUrl:
            playChoices.append(localize(32103))
            playChoicesUrl.append(directPlayUrl)

    # check if the item supports streaming
    directStreamUrl = Api.getStreamUrlFromPlexItem(plexItem, server.PlexServer())
    if directStreamUrl:
        playChoices.append(localize(32104))
        playChoicesUrl.append(directStreamUrl)

    # check if the item has multiple versions
    multipleVersions = []
    if len(plexItem.media) > 1:
        for mediaStream in plexItem.media:
            url = None
            if allowDirectPlay:
                directPlayUrl = Api.getDirectPlayUrlFromMedia(mediaStream)
                if directPlayUrl:
                    url = directPlayUrl

            if not url:
                url = Api.getStreamUrlFromMedia(mediaStream, server.PlexServer())

            # get the display title of the first videostream
            for mediaPart in mediaStream.parts:
                # get all video streams
                videoStreams = (stream for stream in mediaPart.streams if isinstance(stream, media.VideoStream))
                # extract the first non-empty display resolution
                displayResolution = next(
                    (
                        stream.displayTitle or stream.extendedDisplayTitle
                        for stream in videoStreams
                        if stream.displayTitle or stream.extendedDisplayTitle
                    ),
                    None)
                if displayResolution:
                    break

            # fall back to the basic video resolution of the stream
            if not displayResolution:
                displayResolution = mediaStream.videoResolution

            multipleVersions.append((url, mediaStream.bitrate, displayResolution))

    if len(multipleVersions) > 1:
        playChoices.append(localize(32105))
        playChoicesUrl.append(PLAY_MULTIPLE_VERSIONS_KEY)

    # if there are no options something went wrong
    if not playChoices:
        contextLog(
            f"cannot play {listItem2str(item, itemId)} from {mediaProvider2str(mediaProvider)}",
            xbmc.LOGERROR, entry='play')
        return

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

    playUrl = playChoicesUrl[playChoice]

    # check if the user chose to choose which version to play
    if playUrl == PLAY_MULTIPLE_VERSIONS_KEY:
        playChoices.clear()
        playChoicesUrl.clear()

        # sort the available versions by bitrate (second field)
        multipleVersions.sort(key=lambda version: version[1], reverse=True)

        for version in multipleVersions:
            playChoices.append(
                localize(32106, bitrate=bitrate2str(version[1]), resolution=version[2]))
            playChoicesUrl.append(version[0])

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

        playUrl = playChoicesUrl[playChoice]

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