Fix watched feedback and added General command
Everything in the remote control is supported except for audiostream and subtitleindex. Turns out the watched playcount bug was indeed a feedback, so to prevent this I'm skipping the first message that has the itemId right after marking watched.
This commit is contained in:
parent
6aeabc2e3f
commit
79e4bd8a6a
6 changed files with 152 additions and 58 deletions
|
@ -71,8 +71,18 @@ class DownloadUtils():
|
|||
url = "{server}/mediabrowser/Sessions/Capabilities/Full"
|
||||
data = {
|
||||
'PlayableMediaTypes': "Audio,Video",
|
||||
'SupportedCommands': "Play,Playstate,SendString,DisplayMessage,PlayNext",
|
||||
'SupportsMediaControl': True
|
||||
'SupportsMediaControl': True,
|
||||
'SupportedCommands': (
|
||||
|
||||
"MoveUp,MoveDown,MoveLeft,MoveRight,Select,"
|
||||
"Back,ToggleContextMenu,ToggleFullscreen,ToggleOsdMenu,"
|
||||
"GoHome,PageUp,NextLetter,GoToSearch,"
|
||||
"GoToSettings,PageDown,PreviousLetter,TakeScreenshot,"
|
||||
"VolumeUp,VolumeDown,ToggleMute,SendString,DisplayMessage,"
|
||||
|
||||
"Mute,Unmute,SetVolume,"
|
||||
"Play,Playstate,PlayNext"
|
||||
)
|
||||
}
|
||||
|
||||
self.logMsg("Capabilities URL: %s" % url, 2)
|
||||
|
|
|
@ -42,8 +42,9 @@ class Kodi_Monitor(xbmc.Monitor):
|
|||
item = jsondata.get("item").get("id")
|
||||
type = jsondata.get("item").get("type")
|
||||
prop = WINDOW.getProperty('Played%s%s' % (type,item))
|
||||
processWatched = WINDOW.getProperty('played_skipWatched')
|
||||
|
||||
if (playcount != None) and (prop != "true"):
|
||||
if (playcount != None) and (prop != "true") and (processWatched != "true"):
|
||||
WINDOW.setProperty("Played%s%s" % (type,item), "true")
|
||||
utils.logMsg("MB# Sync","Kodi_Monitor--> VideoLibrary.OnUpdate : " + str(data),2)
|
||||
WriteKodiVideoDB().updatePlayCountFromKodi(item, type, playcount)
|
||||
|
@ -87,6 +88,7 @@ class Kodi_Monitor(xbmc.Monitor):
|
|||
# triggers 3 times in a row.
|
||||
xbmc.sleep(100)
|
||||
self.WINDOW.clearProperty("Played%s%s" % (type,id))
|
||||
self.WINDOW.clearProperty('played_skipWatched')
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -108,10 +108,17 @@ class PlaybackUtils():
|
|||
resume_result = resumeScreen.select(self.language(30105), display_list)
|
||||
if resume_result == 0:
|
||||
WINDOW.setProperty(playurl+"seektime", str(seekTime))
|
||||
elif resume_result < 0:
|
||||
# User cancelled dialog
|
||||
xbmc.log("Emby player -> User cancelled resume dialog.")
|
||||
return
|
||||
else:
|
||||
WINDOW.clearProperty(playurl+"seektime")
|
||||
else:
|
||||
WINDOW.clearProperty(playurl+"seektime")
|
||||
else:
|
||||
# Playback started from library
|
||||
WINDOW.setProperty(playurl+"seektime", str(seekTime))
|
||||
|
||||
if result.get("Type")=="Episode":
|
||||
WINDOW.setProperty(playurl+"refresh_id", result.get("SeriesId"))
|
||||
|
|
|
@ -69,7 +69,6 @@ class Player( xbmc.Player ):
|
|||
|
||||
for item_url in self.played_information:
|
||||
data = self.played_information.get(item_url)
|
||||
|
||||
if (data is not None):
|
||||
self.logMsg("emby Service -> item_url : " + item_url)
|
||||
self.logMsg("emby Service -> item_data : " + str(data))
|
||||
|
@ -81,6 +80,9 @@ class Player( xbmc.Player ):
|
|||
currentFile = data.get("currentfile")
|
||||
type = data.get("Type")
|
||||
|
||||
# Prevent websocket feedback
|
||||
self.WINDOW.setProperty("played_itemId", item_id)
|
||||
|
||||
if(currentPosition != None and self.hasData(runtime)):
|
||||
runtimeTicks = int(runtime)
|
||||
self.logMsg("emby Service -> runtimeticks:" + str(runtimeTicks))
|
||||
|
@ -88,6 +90,10 @@ class Player( xbmc.Player ):
|
|||
markPlayedAt = float(90) / 100
|
||||
|
||||
self.logMsg("emby Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt))
|
||||
if percentComplete < markPlayedAt:
|
||||
# Do not mark as watched
|
||||
self.WINDOW.setProperty('played_skipWatched', 'true')
|
||||
|
||||
self.stopPlayback(data)
|
||||
|
||||
if percentComplete > .80 and data.get("Type") == "Episode" and addonSettings.getSetting("offerDelete")=="true":
|
||||
|
@ -116,29 +122,17 @@ class Player( xbmc.Player ):
|
|||
self.logMsg("stopPlayback called", 2)
|
||||
|
||||
item_id = data.get("item_id")
|
||||
audioindex = data.get("AudioStreamIndex")
|
||||
subtitleindex = data.get("SubtitleStreamIndex")
|
||||
playMethod = data.get("playmethod")
|
||||
currentPosition = data.get("currentPosition")
|
||||
positionTicks = int(currentPosition * 10000000)
|
||||
|
||||
url = "{server}/mediabrowser/Sessions/Playing/Stopped"
|
||||
|
||||
postdata = {
|
||||
'QueueableMediaTypes': "Video",
|
||||
'CanSeek': True,
|
||||
'ItemId': item_id,
|
||||
'MediaSourceId': item_id,
|
||||
'PlayMethod': playMethod,
|
||||
'PositionTicks': positionTicks
|
||||
}
|
||||
|
||||
if audioindex:
|
||||
postdata['AudioStreamIndex'] = audioindex
|
||||
|
||||
if subtitleindex:
|
||||
postdata['SubtitleStreamIndex'] = subtitleindex
|
||||
|
||||
self.doUtils.downloadUrl(url, postBody=postdata, type="POST")
|
||||
|
||||
def reportPlayback(self):
|
||||
|
@ -154,7 +148,7 @@ class Player( xbmc.Player ):
|
|||
data = self.played_information.get(currentFile)
|
||||
|
||||
# only report playback if emby has initiated the playback (item_id has value)
|
||||
if (data is not None) and (data.get("item_id") is not None):
|
||||
if data is not None and data.get("item_id") is not None:
|
||||
|
||||
# Get playback information
|
||||
item_id = data.get("item_id")
|
||||
|
@ -167,14 +161,22 @@ class Player( xbmc.Player ):
|
|||
if paused is None:
|
||||
paused = False
|
||||
|
||||
#url = "{server}/mediabrowser/Sessions/Playing/Progress"
|
||||
# Get playback volume
|
||||
volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}'
|
||||
result = xbmc.executeJSONRPC(volume_query)
|
||||
result = json.loads(result)
|
||||
volume = result.get(u'result').get(u'volume')
|
||||
muted = result.get(u'result').get(u'muted')
|
||||
|
||||
postdata = {
|
||||
'QueueableMediaTypes': "Video",
|
||||
'CanSeek': True,
|
||||
'ItemId': item_id,
|
||||
'MediaSourceId': item_id,
|
||||
'PlayMethod': playMethod,
|
||||
'IsPaused': paused,
|
||||
'PlayMethod': playMethod
|
||||
'VolumeLevel': volume,
|
||||
'IsMuted': muted
|
||||
}
|
||||
|
||||
if playTime:
|
||||
|
@ -243,15 +245,17 @@ class Player( xbmc.Player ):
|
|||
itemType = WINDOW.getProperty(currentFile + "type")
|
||||
seekTime = WINDOW.getProperty(currentFile + "seektime")
|
||||
|
||||
username = WINDOW.getProperty('currUser')
|
||||
sessionId = WINDOW.getProperty('sessionId%s' % username)
|
||||
# Get playback volume
|
||||
volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}'
|
||||
result = xbmc.executeJSONRPC(volume_query)
|
||||
result = json.loads(result)
|
||||
volume = result.get(u'result').get(u'volume')
|
||||
muted = result.get(u'result').get(u'muted')
|
||||
|
||||
if seekTime != "":
|
||||
if seekTime:
|
||||
PlaybackUtils().seekToPosition(int(seekTime))
|
||||
|
||||
if (not item_id) or (len(item_id) == 0):
|
||||
self.logMsg("onPlayBackStarted: No info for current playing file", 0)
|
||||
return
|
||||
else:
|
||||
seekTime = 0
|
||||
|
||||
url = "{server}/mediabrowser/Sessions/Playing"
|
||||
postdata = {
|
||||
|
@ -259,7 +263,10 @@ class Player( xbmc.Player ):
|
|||
'CanSeek': True,
|
||||
'ItemId': item_id,
|
||||
'MediaSourceId': item_id,
|
||||
'PlayMethod': playMethod
|
||||
'PlayMethod': playMethod,
|
||||
'VolumeLevel': volume,
|
||||
'PositionTicks': int(seekTime),
|
||||
'IsMuted': muted
|
||||
}
|
||||
|
||||
if audioindex:
|
||||
|
@ -268,24 +275,24 @@ class Player( xbmc.Player ):
|
|||
if subtitleindex:
|
||||
postdata['SubtitleStreamIndex'] = subtitleindex
|
||||
|
||||
# Post playback to server
|
||||
self.logMsg("Sending POST play started.", 1)
|
||||
#self.logMsg("emby Service -> Sending Post Play Started : " + url, 0)
|
||||
self.doUtils.downloadUrl(url, postBody=postdata, type="POST")
|
||||
|
||||
# save data map for updates and position calls
|
||||
data = {}
|
||||
data["runtime"] = runtime
|
||||
data["item_id"] = item_id
|
||||
data["refresh_id"] = refresh_id
|
||||
data["currentfile"] = currentFile
|
||||
data["AudioStreamIndex"] = audioindex
|
||||
data["SubtitleStreamIndex"] = subtitleindex
|
||||
data["playmethod"] = playMethod
|
||||
data["Type"] = itemType
|
||||
data = {
|
||||
'runtime': runtime,
|
||||
'item_id': item_id,
|
||||
'refresh_id': refresh_id,
|
||||
'currentfile': currentFile,
|
||||
'AudioStreamIndex': audioindex,
|
||||
'SubtitleStreamIndex': subtitleindex,
|
||||
'playmethod': playMethod,
|
||||
'type': itemType,
|
||||
'PositionTicks': int(seekTime)
|
||||
}
|
||||
self.played_information[currentFile] = data
|
||||
|
||||
self.logMsg("emby Service -> ADDING_FILE : " + currentFile, 0)
|
||||
self.logMsg("emby Service -> ADDING_FILE : " + str(self.played_information), 0)
|
||||
self.logMsg("ADDING_FILE: %s" % self.played_information, 1)
|
||||
|
||||
# log some playback stats
|
||||
if(itemType != None):
|
||||
|
@ -303,7 +310,7 @@ class Player( xbmc.Player ):
|
|||
self.playStats[playMethod] = 1
|
||||
|
||||
# reset in progress position
|
||||
self.reportPlayback()
|
||||
#self.reportPlayback()
|
||||
|
||||
def GetPlayStats(self):
|
||||
return self.playStats
|
||||
|
|
|
@ -99,8 +99,14 @@ class WebSocketThread(threading.Thread):
|
|||
|
||||
messageType = result.get("MessageType")
|
||||
data = result.get("Data")
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
playedItemId = WINDOW.getProperty('played_itemId')
|
||||
|
||||
if(messageType != None and messageType == "Play" and data != None):
|
||||
if (playedItemId != '') and (playedItemId in message):
|
||||
# Prevent feedback for watched
|
||||
WINDOW.clearProperty('played_itemId')
|
||||
|
||||
elif(messageType != None and messageType == "Play" and data != None):
|
||||
itemIds = data.get("ItemIds")
|
||||
playCommand = data.get("PlayCommand")
|
||||
|
||||
|
@ -144,7 +150,6 @@ class WebSocketThread(threading.Thread):
|
|||
|
||||
elif(messageType != None and messageType == "UserDataChanged"):
|
||||
# for now just do a full playcount sync
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
self.logMsg("Message : Doing UserDataChanged", 0)
|
||||
userDataList = data.get("UserDataList")
|
||||
self.logMsg("Message : Doing UserDataChanged : UserDataList : " + str(userDataList), 0)
|
||||
|
@ -169,16 +174,77 @@ class WebSocketThread(threading.Thread):
|
|||
|
||||
elif messageType == "GeneralCommand":
|
||||
|
||||
if data.get("Name") == "DisplayMessage":
|
||||
message = data.get("Arguments")
|
||||
header = message[u'Header']
|
||||
text = message[u'Text']
|
||||
xbmcgui.Dialog().notification(header, text)
|
||||
command = data.get("Name")
|
||||
arguments = data.get("Arguments")
|
||||
|
||||
elif data.get("Name") == "SendString":
|
||||
message = data.get("Arguments")
|
||||
string = message[u'String']
|
||||
xbmcgui.Dialog().notification("Emby server", string)
|
||||
commandsPlayback = [
|
||||
'Mute','Unmute','SetVolume',
|
||||
'SetAudioStreamIndex'
|
||||
]
|
||||
|
||||
if command in commandsPlayback:
|
||||
# These commands need to be reported back
|
||||
if command == "Mute":
|
||||
xbmc.executebuiltin('Mute')
|
||||
elif command == "Unmute":
|
||||
xbmc.executebuiltin('Mute')
|
||||
elif command == "SetVolume":
|
||||
volume = arguments[u'Volume']
|
||||
xbmc.executebuiltin('SetVolume(%s[,showvolumebar])' % volume)
|
||||
# Report playback
|
||||
WINDOW.setProperty('commandUpdate', 'true')
|
||||
|
||||
else:
|
||||
# GUI commands
|
||||
if command == "ToggleFullscreen":
|
||||
xbmc.executebuiltin('Action(FullScreen)')
|
||||
elif command == "ToggleOsdMenu":
|
||||
xbmc.executebuiltin('Action(OSD)')
|
||||
elif command == "MoveUp":
|
||||
xbmc.executebuiltin('Action(Up)')
|
||||
elif command == "MoveDown":
|
||||
xbmc.executebuiltin('Action(Down)')
|
||||
elif command == "MoveLeft":
|
||||
xbmc.executebuiltin('Action(Left)')
|
||||
elif command == "MoveRight":
|
||||
xbmc.executebuiltin('Action(Right)')
|
||||
elif command == "Select":
|
||||
xbmc.executebuiltin('Action(Select)')
|
||||
elif command == "Back":
|
||||
xbmc.executebuiltin('Action(back)')
|
||||
elif command == "ToggleContextMenu":
|
||||
xbmc.executebuiltin('Action(ContextMenu)')
|
||||
elif command == "GoHome":
|
||||
xbmc.executebuiltin('ActivateWindow(Home)')
|
||||
elif command == "PageUp":
|
||||
xbmc.executebuiltin('Action(PageUp)')
|
||||
elif command == "NextLetter":
|
||||
xbmc.executebuiltin('Action(NextLetter)')
|
||||
elif command == "GoToSearch":
|
||||
xbmc.executebuiltin('VideoLibrary.Search')
|
||||
elif command == "GoToSettings":
|
||||
xbmc.executebuiltin('ActivateWindow(Settings)')
|
||||
elif command == "PageDown":
|
||||
xbmc.executebuiltin('Action(PageDown)')
|
||||
elif command == "PreviousLetter":
|
||||
xbmc.executebuiltin('Action(PrevLetter)')
|
||||
elif command == "TakeScreenshot":
|
||||
xbmc.executebuiltin('TakeScreenshot')
|
||||
elif command == "ToggleMute":
|
||||
xbmc.executebuiltin('Mute')
|
||||
elif command == "VolumeUp":
|
||||
xbmc.executebuiltin('Action(VolumeUp)')
|
||||
elif command == "VolumeDown":
|
||||
xbmc.executebuiltin('Action(VolumeDown)')
|
||||
elif command == "DisplayMessage":
|
||||
header = arguments[u'Header']
|
||||
text = arguments[u'Text']
|
||||
xbmcgui.Dialog().notification(header, text)
|
||||
elif command == "SendString":
|
||||
string = arguments[u'String']
|
||||
xbmcgui.Dialog().notification("Emby server", string)
|
||||
else:
|
||||
self.logMsg("Unknown command.", 1)
|
||||
|
||||
def remove_items(self, itemsRemoved):
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ class Service():
|
|||
ws.start()
|
||||
|
||||
if xbmc.Player().isPlaying():
|
||||
WINDOW.setProperty("Emby_Service_Timestamp", str(int(time.time())))
|
||||
try:
|
||||
playTime = xbmc.Player().getTime()
|
||||
totalTime = xbmc.Player().getTotalTime()
|
||||
|
@ -131,6 +132,7 @@ class Service():
|
|||
pass
|
||||
|
||||
else:
|
||||
WINDOW.setProperty("Emby_Service_Timestamp", str(int(time.time())))
|
||||
#full sync
|
||||
if (startupComplete == False):
|
||||
self.logMsg("Doing_Db_Sync: syncDatabase (Started)")
|
||||
|
|
Loading…
Reference in a new issue