New contextmenu: force playback from PMS

- Visible if using direct paths
- You will be able to correctly play videos with several parts, media
streams or versions
- Fixes #78
This commit is contained in:
tomkat83 2016-11-06 12:15:41 +01:00
parent 00299b58b2
commit bcc46e4ea1
6 changed files with 78 additions and 55 deletions

View file

@ -269,6 +269,7 @@
<string id="30412">Force transcode</string> <string id="30412">Force transcode</string>
<string id="30413">Enable Plex context menu in Kodi</string> <string id="30413">Enable Plex context menu in Kodi</string>
<string id="30414">Could not delete the Plex item. Is item deletion enabled on the Plex Media Server?</string> <string id="30414">Could not delete the Plex item. Is item deletion enabled on the Plex Media Server?</string>
<string id="30415">Start playback via PMS</string>
<!-- add-on settings --> <!-- add-on settings -->
<string id="30500">Verify Host SSL Certificate (more secure)</string> <string id="30500">Verify Host SSL Certificate (more secure)</string>

View file

@ -299,6 +299,7 @@
<string id="30412">Transkodieren erzwingen</string> <string id="30412">Transkodieren erzwingen</string>
<string id="30413">Plex Kontextmenu in Kodi aktivieren</string> <string id="30413">Plex Kontextmenu in Kodi aktivieren</string>
<string id="30414">Konnte das Element nicht löschen. Ist diese Option auf dem Plex Medien Server aktiviert?</string> <string id="30414">Konnte das Element nicht löschen. Ist diese Option auf dem Plex Medien Server aktiviert?</string>
<string id="30415">Wiedergabe via PMS starten</string>
<string id="33033">Kodi wird jetzt neu gestartet um die Änderungen anzuwenden.</string> <string id="33033">Kodi wird jetzt neu gestartet um die Änderungen anzuwenden.</string>

View file

@ -17,8 +17,49 @@ addonName = 'PlexKodiConnect'
############################################################################### ###############################################################################
# Multiply Plex time by this factor to receive Kodi time
PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0 PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0
# Possible output of Kodi's ListItem.DBTYPE for all video items
KODI_VIDEOTYPES = (
'video',
'movie',
'set',
'tvshow',
'season',
'episode',
'musicvideo'
)
# Possible output of Kodi's ListItem.DBTYPE for all audio items
KODI_AUDIOTYPES = (
'music',
'song',
'album',
'artist'
)
ITEMTYPE_FROM_PLEXTYPE = {
'movie': 'Movies',
'season': 'TVShows',
'episode': 'TVShows',
'show': 'TVShows',
'artist': 'Music',
'album': 'Music',
'track': 'Music',
'song': 'Music'
}
KODITYPE_FROM_PLEXTYPE = {
'movie': 'movie',
'episode': 'episode',
'track': 'song',
'artist': 'artist',
'album': 'album',
'XXXXXX': 'musicvideo',
'XXXXXXX': 'genre'
}
def ConvertPlexToKodiTime(plexTime): def ConvertPlexToKodiTime(plexTime):
""" """
@ -29,44 +70,6 @@ def ConvertPlexToKodiTime(plexTime):
return int(float(plexTime) * PLEX_TO_KODI_TIMEFACTOR) return int(float(plexTime) * PLEX_TO_KODI_TIMEFACTOR)
def GetItemClassFromType(itemType):
classes = {
'movie': 'Movies',
'season': 'TVShows',
'episode': 'TVShows',
'show': 'TVShows',
'artist': 'Music',
'album': 'Music',
'track': 'Music',
'song': 'Music'
}
return classes[itemType]
def GetItemClassFromNumber(itemType):
classes = {
1: 'Movies',
4: 'TVShows',
}
return classes[itemType]
def GetKodiTypeFromPlex(plexItemType):
"""
As used in playlist.item here: http://kodi.wiki/view/JSON-RPC_API
"""
classes = {
'movie': 'movie',
'episode': 'episode',
'track': 'song',
'artist': 'artist',
'album': 'album',
'XXXXXX': 'musicvideo',
'XXXXXXX': 'genre'
}
return classes[plexItemType.lower()]
def GetPlexKeyNumber(plexKey): def GetPlexKeyNumber(plexKey):
""" """
Deconstructs e.g. '/library/metadata/xxxx' to the tuple Deconstructs e.g. '/library/metadata/xxxx' to the tuple

View file

@ -7,8 +7,7 @@ import logging
import xbmc import xbmc
import xbmcaddon import xbmcaddon
import PlexAPI import PlexFunctions as PF
from PlexFunctions import GetPlexMetadata, delete_item_from_pms
import embydb_functions as embydb import embydb_functions as embydb
from utils import window, settings, dialog, language as lang, kodiSQL from utils import window, settings, dialog, language as lang, kodiSQL
from dialogs import context from dialogs import context
@ -25,7 +24,8 @@ OPTIONS = {
# 'AddFav': lang(30405), # 'AddFav': lang(30405),
# 'RemoveFav': lang(30406), # 'RemoveFav': lang(30406),
# 'RateSong': lang(30407), # 'RateSong': lang(30407),
'Transcode': lang(30412) 'Transcode': lang(30412),
'PMS_Play': lang(30415) # Use PMS to start playback
} }
############################################################################### ###############################################################################
@ -46,9 +46,6 @@ class ContextMenu(object):
if not self.item_id: if not self.item_id:
return return
self.item = GetPlexMetadata(self.item_id)
self.api = PlexAPI.API(self.item)
if self._select_menu(): if self._select_menu():
self._action_menu() self._action_menu()
@ -61,7 +58,6 @@ class ContextMenu(object):
@classmethod @classmethod
def _get_item_type(cls): def _get_item_type(cls):
item_type = xbmc.getInfoLabel('ListItem.DBTYPE').decode('utf-8') item_type = xbmc.getInfoLabel('ListItem.DBTYPE').decode('utf-8')
if not item_type: if not item_type:
if xbmc.getCondVisibility('Container.Content(albums)'): if xbmc.getCondVisibility('Container.Content(albums)'):
item_type = "album" item_type = "album"
@ -73,7 +69,6 @@ class ContextMenu(object):
item_type = "picture" item_type = "picture"
else: else:
log.info("item_type is unknown") log.info("item_type is unknown")
return item_type return item_type
@classmethod @classmethod
@ -92,6 +87,11 @@ class ContextMenu(object):
# Display select dialog # Display select dialog
options = [] options = []
# if user uses direct paths, give option to initiate playback via PMS
if (window('useDirectPaths') == 'true' and
self.item_type in PF.KODI_VIDEOTYPES):
options.append(OPTIONS['PMS_Play'])
# if self.item_type in ("movie", "episode", "song"): # if self.item_type in ("movie", "episode", "song"):
# options.append(OPTIONS['Transcode']) # options.append(OPTIONS['Transcode'])
@ -116,10 +116,11 @@ class ContextMenu(object):
# Addon settings # Addon settings
options.append(OPTIONS['Addon']) options.append(OPTIONS['Addon'])
addon = xbmcaddon.Addon('plugin.video.plexkodiconnect') context_menu = context.ContextMenu(
context_menu = context.ContextMenu("script-emby-context.xml", "script-emby-context.xml",
addon.getAddonInfo('path'), xbmcaddon.Addon(
"default", "1080i") 'plugin.video.plexkodiconnect').getAddonInfo('path'),
"default", "1080i")
context_menu.set_options(options) context_menu.set_options(options)
context_menu.doModal() context_menu.doModal()
@ -135,6 +136,9 @@ class ContextMenu(object):
if selected == OPTIONS['Transcode']: if selected == OPTIONS['Transcode']:
pass pass
elif selected == OPTIONS['PMS_Play']:
self._PMS_play()
elif selected == OPTIONS['Refresh']: elif selected == OPTIONS['Refresh']:
self.emby.refreshItem(self.item_id) self.emby.refreshItem(self.item_id)
@ -192,5 +196,20 @@ class ContextMenu(object):
if delete: if delete:
log.info("Deleting Plex item with id %s", self.item_id) log.info("Deleting Plex item with id %s", self.item_id)
if delete_item_from_pms(self.item_id) is False: if PF.delete_item_from_pms(self.item_id) is False:
dialog(type_="ok", heading="{plex}", line1=lang(30414)) dialog(type_="ok", heading="{plex}", line1=lang(30414))
def _PMS_play(self):
"""
For using direct paths: Initiates playback using the PMS
"""
params = {
'filename': '/library/metadata/%s' % self.item_id,
'id': self.item_id,
'dbid': self.kodi_id,
'mode': "play"
}
from urllib import urlencode
handle = ("plugin://plugin.video.plexkodiconnect.movies?%s"
% urlencode(params))
xbmc.executebuiltin('RunPlugin(%s)' % handle)

View file

@ -1623,7 +1623,7 @@ class LibrarySync(Thread):
# Now tell Kodi where we are # Now tell Kodi where we are
for item in items: for item in items:
itemFkt = getattr(itemtypes, itemFkt = getattr(itemtypes,
PF.GetItemClassFromType(item['kodi_type'])) PF.ITEMTYPE_FROM_PLEXTYPE[item['kodi_type']])
with itemFkt() as Fkt: with itemFkt() as Fkt:
Fkt.updatePlaystate(item) Fkt.updatePlaystate(item)

View file

@ -3,7 +3,6 @@
############################################################################### ###############################################################################
import logging import logging
import json
import sys import sys
from urllib import urlencode from urllib import urlencode
@ -123,7 +122,7 @@ class PlaybackUtils():
self.pl.insertintoPlaylist( self.pl.insertintoPlaylist(
self.currentPosition+1, self.currentPosition+1,
dbid, dbid,
PF.GetKodiTypeFromPlex(API.getType())) PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
self.currentPosition += 1 self.currentPosition += 1
############### -- CHECK FOR INTROS ################ ############### -- CHECK FOR INTROS ################
@ -143,7 +142,7 @@ class PlaybackUtils():
log.info("Adding main item to playlist.") log.info("Adding main item to playlist.")
self.pl.addtoPlaylist( self.pl.addtoPlaylist(
dbid, dbid,
PF.GetKodiTypeFromPlex(API.getType())) PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
# Ensure that additional parts are played after the main item # Ensure that additional parts are played after the main item
self.currentPosition += 1 self.currentPosition += 1