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:
angelblue05 2015-05-16 01:31:08 -05:00
parent 6aeabc2e3f
commit 79e4bd8a6a
6 changed files with 152 additions and 58 deletions

View file

@ -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)

View file

@ -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')

View file

@ -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"))

View file

@ -66,14 +66,13 @@ class Player( xbmc.Player ):
addonSettings = xbmcaddon.Addon(id='plugin.video.emby')
self.logMsg("emby Service -> played_information : " + str(self.played_information))
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))
runtime = data.get("runtime")
currentPosition = data.get("currentPosition")
item_id = data.get("item_id")
@ -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,28 +122,16 @@ 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")
@ -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)
if seekTime != "":
PlaybackUtils().seekToPosition(int(seekTime))
# 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 (not item_id) or (len(item_id) == 0):
self.logMsg("onPlayBackStarted: No info for current playing file", 0)
return
if seekTime:
PlaybackUtils().seekToPosition(int(seekTime))
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")
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

View file

@ -99,8 +99,14 @@ class WebSocketThread(threading.Thread):
messageType = result.get("MessageType")
data = result.get("Data")
if(messageType != None and messageType == "Play" and data != None):
WINDOW = xbmcgui.Window( 10000 )
playedItemId = WINDOW.getProperty('played_itemId')
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")
commandsPlayback = [
'Mute','Unmute','SetVolume',
'SetAudioStreamIndex'
]
elif data.get("Name") == "SendString":
message = data.get("Arguments")
string = message[u'String']
xbmcgui.Dialog().notification("Emby server", string)
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):

View file

@ -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)")