From 2f3d609f536f79c5c066142d97f5044328cf4632 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 28 Apr 2015 17:23:26 -0500 Subject: [PATCH] Attempt #1 at fixing playback report/resume Cleaning up the code, using websocket to report playback progress. --- resources/lib/DownloadUtils.py | 23 +-- resources/lib/Player.py | 245 +++++++++++++++---------------- resources/lib/Utils.py | 2 + resources/lib/WebSocketClient.py | 159 +++++--------------- service.py | 21 ++- 5 files changed, 181 insertions(+), 269 deletions(-) diff --git a/resources/lib/DownloadUtils.py b/resources/lib/DownloadUtils.py index bc86a84a..92410b2c 100644 --- a/resources/lib/DownloadUtils.py +++ b/resources/lib/DownloadUtils.py @@ -32,16 +32,16 @@ class DownloadUtils(): def __init__(self): self.__dict__ = self._shared_state - self.className = self.__class__.__name__ def logMsg(self, msg, lvl=1): + self.className = self.__class__.__name__ utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl)) def setUsername(self, username): # Reserved for UserClient only self.username = username - self.logMsg("Set username: %s" % username, 1) + self.logMsg("Set username: %s" % username, 2) def setUserId(self, userId): # Reserved for UserClient only @@ -71,8 +71,9 @@ class DownloadUtils(): url = "{server}/mediabrowser/Sessions?DeviceId=%s&format=json" % deviceId result = self.downloadUrl(url) # sessionId result - self.logMsg("Session result: %s" % result, 1) + self.logMsg("Session result: %s" % result, 2) self.sessionId = result[0][u'Id'] + self.WINDOW.setProperty('sessionId%s' % self.username, self.sessionId) # Settings for capabilities playableMediaTypes = "Audio,Video" @@ -129,7 +130,7 @@ class DownloadUtils(): if not authenticate: # If user is not authenticated auth = 'MediaBrowser Client="Kodi", Device="%s", DeviceId="%s", Version="%s"' % (deviceName, deviceId, version) - header = {"Accept-encoding": "gzip", "Accept-Charset": "UTF-8,*", "Authorization": auth} + header = {'Content-type': 'application/json', 'Accept-encoding': 'gzip', 'Accept-Charset': 'UTF-8,*', 'Authorization': auth} self.logMsg("Header: %s" % header, 2) return header @@ -139,7 +140,7 @@ class DownloadUtils(): token = self.token # Attached to the requests session auth = 'MediaBrowser UserId="%s", Client="Kodi", Device="%s", DeviceId="%s", Version="%s"' % (userId, deviceName, deviceId, version) - header = {"Accept-encoding": "gzip", "Accept-Charset": "UTF-8,*", "Authorization": auth, "X-MediaBrowser-Token": token} + header = {'Content-type': 'application/json', 'Accept-encoding': 'gzip', 'Accept-Charset': 'UTF-8,*', 'Authorization': auth, 'X-MediaBrowser-Token': token} self.logMsg("Header: %s" % header, 2) return header @@ -159,16 +160,16 @@ class DownloadUtils(): # Replace for the real values and append api_key url = url.replace("{server}", self.server, 1) url = url.replace("{UserId}", self.userId, 1) - url = "%s&api_key=%s" % (url, self.token) + #url = "%s&api_key=%s" % (url, self.token) self.logMsg("URL: %s" % url, 2) # Prepare request if type == "GET": - r = s.get(url, params=postBody, timeout=timeout) + r = s.get(url, json=postBody, timeout=timeout) elif type == "POST": - r = s.post(url, params=postBody, timeout=timeout) + r = s.post(url, json=postBody, timeout=timeout) elif type == "DELETE": - r = s.delete(url, params=postBody, timeout=timeout) + r = s.delete(url, json=postBody, timeout=timeout) # If user is not authenticated elif not authenticate: @@ -185,9 +186,9 @@ class DownloadUtils(): # Prepare request if type == "GET": - r = requests.get(url, params=postBody, headers=header, timeout=timeout, verify=verifyssl) + r = requests.get(url, json=postBody, headers=header, timeout=timeout, verify=verifyssl) elif type == "POST": - r = requests.post(url, params=postBody, headers=header, timeout=timeout, verify=verifyssl) + r = requests.post(url, json=postBody, headers=header, timeout=timeout, verify=verifyssl) # Process the response try: diff --git a/resources/lib/Player.py b/resources/lib/Player.py index 9d4e3d10..e7526cb2 100644 --- a/resources/lib/Player.py +++ b/resources/lib/Player.py @@ -6,8 +6,10 @@ import os import threading import json import inspect + import KodiMonitor import Utils as utils + from DownloadUtils import DownloadUtils from WebSocketClient import WebSocketThread from PlayUtils import PlayUtils @@ -21,36 +23,34 @@ librarySync = LibrarySync() # service class for playback monitoring class Player( xbmc.Player ): + # Borg - multiple instances, shared state + _shared_state = {} + + xbmcplayer = xbmc.Player() + doUtils = DownloadUtils() + clientInfo = ClientInformation() + ws = WebSocketThread() + + addonName = clientInfo.getAddonName() + addonId = clientInfo.getAddonId() + addon = xbmcaddon.Addon(id=addonId) + + WINDOW = xbmcgui.Window(10000) + logLevel = 0 played_information = {} - downloadUtils = None settings = None playStats = {} def __init__( self, *args ): - self.settings = xbmcaddon.Addon(id='plugin.video.emby') - self.downloadUtils = DownloadUtils() - try: - self.logLevel = int(self.settings.getSetting('logLevel')) - except: - pass - self.printDebug("emby Service -> starting playback monitor service",1) - self.played_information = {} - pass + self.__dict__ = self._shared_state + self.logMsg("Starting playback monitor service", 1) - def printDebug(self, msg, level = 1): - if(self.logLevel >= level): - if(self.logLevel == 2): - try: - xbmc.log("emby " + str(level) + " -> " + inspect.stack()[1][3] + " : " + str(msg)) - except UnicodeEncodeError: - xbmc.log("emby " + str(level) + " -> " + inspect.stack()[1][3] + " : " + str(msg.encode('utf-8'))) - else: - try: - xbmc.log("emby " + str(level) + " -> " + str(msg)) - except UnicodeEncodeError: - xbmc.log("emby " + str(level) + " -> " + str(msg.encode('utf-8'))) + def logMsg(self, msg, lvl=1): + + self.className = self.__class__.__name__ + utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl)) def hasData(self, data): if(data == None or len(data) == 0 or data == "None"): @@ -60,19 +60,19 @@ class Player( xbmc.Player ): def stopAll(self): - WebSocketThread().processPendingActions() + self.ws.processPendingActions() if(len(self.played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.emby') - self.printDebug("emby Service -> played_information : " + str(self.played_information)) + 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 != None): - self.printDebug("emby Service -> item_url : " + item_url) - self.printDebug("emby Service -> item_data : " + str(data)) + 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") @@ -83,11 +83,11 @@ class Player( xbmc.Player ): if(currentPosition != None and self.hasData(runtime)): runtimeTicks = int(runtime) - self.printDebug("emby Service -> runtimeticks:" + str(runtimeTicks)) + self.logMsg("emby Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPosition * 10000000) / runtimeTicks markPlayedAt = float(90) / 100 - self.printDebug("emby Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt)) + self.logMsg("emby Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt)) self.stopPlayback(data) if(refresh_id != None): @@ -96,125 +96,116 @@ class Player( xbmc.Player ): self.played_information.clear() - WINDOW = xbmcgui.Window(10000) - username = WINDOW.getProperty('currUser') - server = WINDOW.getProperty('server%s' % username) # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() - url = "%s/mediabrowser/Videos/ActiveEncodings" % server + url = "{server}/mediabrowser/Videos/ActiveEncodings" url = url + '?DeviceId=' + txt_mac - self.downloadUtils.downloadUrl(url, type="DELETE") + self.doUtils.downloadUrl(url, type="DELETE") def stopPlayback(self, data): - self.printDebug("stopPlayback called") - addonSettings = xbmcaddon.Addon(id='plugin.video.emby') + + 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 = str(int(currentPosition * 10000000)) + positionTicks = int(currentPosition * 10000000) + + url = "{server}/mediabrowser/Sessions/Playing/Stopped" - WINDOW = xbmcgui.Window(10000) - username = WINDOW.getProperty('currUser') - server = WINDOW.getProperty('server%s' % username) + postdata = { + 'QueueableMediaTypes': "Video", + 'CanSeek': True, + 'ItemId': item_id, + 'MediaSourceId': item_id, + 'PlayMethod': playMethod, + 'PositionTicks': positionTicks + } - url = "%s/mediabrowser/Sessions/Playing/Stopped" % server - - url = url + "?itemId=" + item_id + if audioindex: + postdata['AudioStreamIndex'] = audioindex - url = url + "&canSeek=true" - url = url + "&PlayMethod=" + playMethod - url = url + "&QueueableMediaTypes=Video" - url = url + "&MediaSourceId=" + item_id - url = url + "&PositionTicks=" + positionTicks - if(audioindex != None and audioindex!=""): - url = url + "&AudioStreamIndex=" + audioindex + if subtitleindex: + postdata['SubtitleStreamIndex'] = subtitleindex - if(subtitleindex != None and subtitleindex!=""): - url = url + "&SubtitleStreamIndex=" + subtitleindex - - self.downloadUtils.downloadUrl(url, postBody="", type="POST") - + self.doUtils.downloadUrl(url, postBody=postdata, type="POST") def reportPlayback(self): - self.printDebug("reportPlayback Called",2) - - currentFile = xbmc.Player().getPlayingFile() - - #TODO need to change this to use the one in the data map - playTime = xbmc.Player().getTime() + self.logMsg("reportPlayback Called", 2) + xbmcplayer = self.xbmcplayer + + currentFile = xbmcplayer.getPlayingFile() data = self.played_information.get(currentFile) - + # only report playback if emby has initiated the playback (item_id has value) - if(data != None and data.get("item_id") != None): - addonSettings = xbmcaddon.Addon(id='plugin.video.emby') - + if (data is not None) and (data.get("item_id") is not None): + + # Get playback information item_id = data.get("item_id") audioindex = data.get("AudioStreamIndex") subtitleindex = data.get("SubtitleStreamIndex") + playTime = data.get("currentPosition") playMethod = data.get("playmethod") paused = data.get("paused") + + if paused is None: + paused = False - WINDOW = xbmcgui.Window(10000) - username = WINDOW.getProperty('currUser') - server = WINDOW.getProperty('server%s' % username) - - url = "%s/mediabrowser/Sessions/Playing/Progress" % server - - url = url + "?itemId=" + item_id + #url = "{server}/mediabrowser/Sessions/Playing/Progress" + postdata = { + 'QueueableMediaTypes': "Video", + 'CanSeek': True, + 'ItemId': item_id, + 'MediaSourceId': item_id, + 'IsPaused': paused, + 'PlayMethod': playMethod + } - url = url + "&canSeek=true" - url = url + "&PlayMethod=" + playMethod - url = url + "&QueueableMediaTypes=Video" - url = url + "&MediaSourceId=" + item_id - - url = url + "&PositionTicks=" + str(int(playTime * 10000000)) - - if(audioindex != None and audioindex!=""): - url = url + "&AudioStreamIndex=" + audioindex - - if(subtitleindex != None and subtitleindex!=""): - url = url + "&SubtitleStreamIndex=" + subtitleindex - - if(paused == None): - paused = "false" - url = url + "&IsPaused=" + paused - - self.downloadUtils.downloadUrl(url, postBody="", type="POST") + if playTime: + postdata['PositionTicks'] = int(playTime * 10000000) + + if audioindex: + postdata['AudioStreamIndex'] = audioindex + + if subtitleindex: + postdata['SubtitleStreamIndex'] = subtitleindex + + postdata = json.dumps(postdata) + self.logMsg("Report: %s" % postdata) + self.ws.sendProgressUpdate(postdata) def onPlayBackPaused( self ): currentFile = xbmc.Player().getPlayingFile() - self.printDebug("PLAYBACK_PAUSED : " + currentFile,2) + self.logMsg("PLAYBACK_PAUSED : " + currentFile,2) if(self.played_information.get(currentFile) != None): self.played_information[currentFile]["paused"] = "true" self.reportPlayback() def onPlayBackResumed( self ): currentFile = xbmc.Player().getPlayingFile() - self.printDebug("PLAYBACK_RESUMED : " + currentFile,2) + self.logMsg("PLAYBACK_RESUMED : " + currentFile,2) if(self.played_information.get(currentFile) != None): self.played_information[currentFile]["paused"] = "false" self.reportPlayback() def onPlayBackSeek( self, time, seekOffset ): - self.printDebug("PLAYBACK_SEEK",2) + self.logMsg("PLAYBACK_SEEK",2) self.reportPlayback() def onPlayBackStarted( self ): # Will be called when xbmc starts playing a file - WINDOW = xbmcgui.Window( 10000 ) + WINDOW = self.WINDOW + xbmcplayer = self.xbmcplayer self.stopAll() - addonSettings = xbmcaddon.Addon(id='plugin.video.emby') - xbmcplayer = xbmc.Player() if xbmcplayer.isPlaying(): currentFile = xbmcplayer.getPlayingFile() - self.printDebug("emby Service -> onPlayBackStarted : " + currentFile, 0) + self.logMsg("onPlayBackStarted: %s" % currentFile, 0) # we may need to wait until the info is available item_id = WINDOW.getProperty(currentFile + "item_id") @@ -236,33 +227,35 @@ class Player( xbmc.Player ): playMethod = WINDOW.getProperty(currentFile + "playmethod") 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)) - if(item_id == None or len(item_id) == 0): - self.printDebug("emby Service -> onPlayBackStarted : No info for current playing file", 0) + if (not item_id) or (len(item_id) == 0): + self.logMsg("onPlayBackStarted: No info for current playing file", 0) return - username = WINDOW.getProperty('currUser') - server = WINDOW.getProperty('server%s' % username) + url = "{server}/mediabrowser/Sessions/Playing" + postdata = { + 'QueueableMediaTypes': "Video", + 'CanSeek': True, + 'ItemId': item_id, + 'MediaSourceId': item_id, + 'PlayMethod': playMethod + } - url = "%s/mediabrowser/Sessions/Playing" % server + if audioindex: + postdata['AudioStreamIndex'] = audioindex - url = url + "?itemId=" + item_id - - url = url + "&canSeek=true" - url = url + "&PlayMethod=" + playMethod - url = url + "&QueueableMediaTypes=Video" - url = url + "&MediaSourceId=" + item_id + if subtitleindex: + postdata['SubtitleStreamIndex'] = subtitleindex - if(audioindex != None and audioindex!=""): - url = url + "&AudioStreamIndex=" + audioindex - - if(subtitleindex != None and subtitleindex!=""): - url = url + "&SubtitleStreamIndex=" + subtitleindex - - self.printDebug("emby Service -> Sending Post Play Started : " + url, 0) - self.downloadUtils.downloadUrl(url, postBody="", type="POST") + 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 = {} @@ -276,8 +269,8 @@ class Player( xbmc.Player ): data["Type"] = itemType self.played_information[currentFile] = data - self.printDebug("emby Service -> ADDING_FILE : " + currentFile, 0) - self.printDebug("emby Service -> ADDING_FILE : " + str(self.played_information), 0) + self.logMsg("emby Service -> ADDING_FILE : " + currentFile, 0) + self.logMsg("emby Service -> ADDING_FILE : " + str(self.played_information), 0) # log some playback stats if(itemType != None): @@ -302,7 +295,7 @@ class Player( xbmc.Player ): def onPlayBackEnded( self ): # Will be called when xbmc stops playing a file - self.printDebug("emby Service -> onPlayBackEnded") + self.logMsg("onPlayBackEnded", 0) #workaround when strm files are launched through the addon - mark watched when finished playing #TODO --> mark watched when 95% is played of the file @@ -311,12 +304,8 @@ class Player( xbmc.Player ): try: id = WINDOW.getProperty("virtualstrm") type = WINDOW.getProperty("virtualstrmtype") - addon = xbmcaddon.Addon(id='plugin.video.emby') - username = WINDOW.getProperty('currUser') - userid = WINDOW.getProperty('userId%s' % username) - server = WINDOW.getProperty('server%s' % username) - watchedurl = "%s/mediabrowser/Users/%s/PlayedItems/%s" % (server, userid, id) - self.downloadUtils.downloadUrl(watchedurl, postBody="", type="POST") + watchedurl = "{server}/mediabrowser/Users/{UserId}/PlayedItems/%s" % id + self.doUtils.downloadUrl(watchedurl, postBody="", type="POST") librarySync.updatePlayCount(id) except: pass WINDOW.clearProperty("virtualstrm") @@ -325,7 +314,7 @@ class Player( xbmc.Player ): def onPlayBackStopped( self ): # Will be called when user stops xbmc playing a file - self.printDebug("emby Service -> onPlayBackStopped") + self.logMsg("onPlayBackStopped", 0) self.stopAll() @@ -352,8 +341,8 @@ class Player( xbmc.Player ): if userData!=None and userData["Played"]==True: pDialog = xbmcgui.DialogProgress() seasonId = MB3Episode["SeasonId"] - url = "%s/mediabrowser/Users/%s/Items?ParentId=%s&ImageTypeLimit=1&Limit=1&SortBy=SortName&SortOrder=Ascending&Filters=IsUnPlayed&IncludeItemTypes=Episode&IsVirtualUnaired=false&Recursive=true&IsMissing=False&format=json" % (server, userid, seasonId) - jsonData = self.downloadUtils.downloadUrl(url, suppress=False, popup=1 ) + url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&ImageTypeLimit=1&Limit=1&SortBy=SortName&SortOrder=Ascending&Filters=IsUnPlayed&IncludeItemTypes=Episode&IsVirtualUnaired=false&Recursive=true&IsMissing=False&format=json" % seasonId + jsonData = self.doUtils.downloadUrl(url) if(jsonData != ""): seasonData = json.loads(jsonData) if seasonData.get("Items") != None: diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 2d8ee915..4f47b77f 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -30,6 +30,8 @@ language = addonSettings.getLocalizedString def logMsg(title, msg, level = 1): logLevel = int(addonSettings.getSetting("logLevel")) + WINDOW = xbmcgui.Window(10000) + WINDOW.setProperty('logLevel', str(logLevel)) if(logLevel >= level): if(logLevel == 2): # inspect.stack() is expensive try: diff --git a/resources/lib/WebSocketClient.py b/resources/lib/WebSocketClient.py index 6197d6e3..e09e105a 100644 --- a/resources/lib/WebSocketClient.py +++ b/resources/lib/WebSocketClient.py @@ -13,12 +13,13 @@ import socket import websocket import KodiMonitor +import Utils as utils + from ClientInformation import ClientInformation from DownloadUtils import DownloadUtils from PlaybackUtils import PlaybackUtils from LibrarySync import LibrarySync from WriteKodiDB import WriteKodiDB -import Utils as utils pendingUserDataList = [] pendingItemsToRemove = [] @@ -27,79 +28,39 @@ _MODE_BASICPLAY=12 class WebSocketThread(threading.Thread): - logLevel = 0 + _shared_state = {} + + clientInfo = ClientInformation() + KodiMonitor = KodiMonitor.Kodi_Monitor() + addonName = clientInfo.getAddonName() + client = None keepRunning = True def __init__(self, *args): - self.KodiMonitor = KodiMonitor.Kodi_Monitor() - addonSettings = xbmcaddon.Addon(id='plugin.video.emby') - level = addonSettings.getSetting('logLevel') - self.logLevel = 0 - if(level != None): - self.logLevel = int(level) - - xbmc.log("emby WebSocketThread -> Log Level:" + str(self.logLevel)) - + self.__dict__ = self._shared_state threading.Thread.__init__(self, *args) - def logMsg(self, msg, level = 1): - if(self.logLevel >= level): - try: - xbmc.log("emby WebSocketThread -> " + str(msg)) - except UnicodeEncodeError: - try: - xbmc.log("emby WebSocketThread -> " + str(msg.encode('utf-8'))) - except: pass - - ''' - def playbackStarted(self, itemId): - if(self.client != None): - try: - self.logMsg("Sending Playback Started") - messageData = {} - messageData["MessageType"] = "PlaybackStart" - messageData["Data"] = itemId + "|true|audio,video" - messageString = json.dumps(messageData) - self.logMsg("Message Data : " + messageString) - self.client.send(messageString) - except Exception, e: - self.logMsg("Exception : " + str(e), level=0) - else: - self.logMsg("Sending Playback Started NO Object ERROR") + def logMsg(self, msg, lvl=1): - def playbackStopped(self, itemId, ticks): - if(self.client != None): + self.className = self.__class__.__name__ + utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl)) + + def sendProgressUpdate(self, data): + self.logMsg("sendProgressUpdate", 1) + if self.client: try: - self.logMsg("Sending Playback Stopped") - messageData = {} - messageData["MessageType"] = "PlaybackStopped" - messageData["Data"] = itemId + "|" + str(ticks) + # Send progress update + messageData = { + 'MessageType': "ReportPlaybackProgress", + 'Data': data + } messageString = json.dumps(messageData) self.client.send(messageString) + self.logMsg("Message data: %s" % messageString, 2) except Exception, e: - self.logMsg("Exception : " + str(e), level=0) - else: - self.logMsg("Sending Playback Stopped NO Object ERROR") - ''' - - ''' - def sendProgressUpdate(self, itemId, ticks): - if(self.client != None): - try: - self.logMsg("Sending Progress Update") - messageData = {} - messageData["MessageType"] = "PlaybackProgress" - messageData["Data"] = itemId + "|" + str(ticks) + "|false|false" - messageString = json.dumps(messageData) - self.logMsg("Message Data : " + messageString) - self.client.send(messageString) - except Exception, e: - self.logMsg("Exception : " + str(e), level=0) - else: - self.logMsg("Sending Progress Update NO Object ERROR") - ''' + self.logMsg("Exception: %s" % e, 1) def stopClient(self): # stopping the client is tricky, first set keep_running to false and then trigger one @@ -253,69 +214,30 @@ class WebSocketThread(threading.Thread): self.logMsg("Closed") def on_open(self, ws): - - clientInfo = ClientInformation() - machineId = clientInfo.getMachineId() - version = clientInfo.getVersion() - messageData = {} - messageData["MessageType"] = "Identity" - - addonSettings = xbmcaddon.Addon(id='plugin.video.emby') - deviceName = addonSettings.getSetting('deviceName') - deviceName = deviceName.replace("\"", "_") - - messageData["Data"] = "Kodi|" + machineId + "|" + version + "|" + deviceName - messageString = json.dumps(messageData) - self.logMsg("Opened : " + str(messageString)) - ws.send(messageString) - ''' - # Set Capabilities - xbmc.log("postcapabilities_called") - downloadUtils = DownloadUtils() - downloadUtils.startSession()''' - - - def getWebSocketPort(self, host, port): - - userUrl = "http://" + host + ":" + port + "/mediabrowser/System/Info?format=json" - - downloadUtils = DownloadUtils() - jsonData = downloadUtils.downloadUrl(userUrl, suppress=False, popup=1 ) - if(jsonData == ""): - return -1 - - result = json.loads(jsonData) - - wsPort = result.get("WebSocketPortNumber") - if(wsPort != None): - return wsPort - else: - return -1 + pass def run(self): - addonSettings = xbmcaddon.Addon(id='plugin.video.emby') + WINDOW = xbmcgui.Window(10000) + logLevel = int(WINDOW.getProperty('logLevel')) username = WINDOW.getProperty('currUser') server = WINDOW.getProperty('server%s' % username) - host = WINDOW.getProperty('server_%s' % username) - - if(self.logLevel >= 1): + token = WINDOW.getProperty('accessToken%s' % username) + deviceId = ClientInformation().getMachineId() + + if (logLevel == 2): websocket.enableTrace(True) - ''' - wsPort = self.getWebSocketPort(mb3Host, mb3Port); - self.logMsg("WebSocketPortNumber = " + str(wsPort)) - if(wsPort == -1): - self.logMsg("Could not retrieve WebSocket port, can not run WebScoket Client") - return - ''' + + # Get the appropriate prefix for websocket if "https" in server: - webSocketUrl = "wss://%s/mediabrowser" % host + server = server.replace('https', 'wss') else: - webSocketUrl = "ws://%s/mediabrowser" % host - # Make a call to /System/Info. WebSocketPortNumber is the port hosting the web socket. - #webSocketUrl = "ws://" + host + "/mediabrowser" - self.logMsg("WebSocket URL : " + webSocketUrl) - self.client = websocket.WebSocketApp(webSocketUrl, + server = server.replace('http', 'ws') + + websocketUrl = "%s?api_key=%s&deviceId=%s" % (server, token, deviceId) + self.logMsg("websocket URL: %s" % websocketUrl) + + self.client = websocket.WebSocketApp(websocketUrl, on_message = self.on_message, on_error = self.on_error, on_close = self.on_close) @@ -344,5 +266,4 @@ class WebSocketThread(threading.Thread): pendingItemsToRemove = [] if pendingItemsToUpdate != []: self.update_items(pendingItemsToUpdate) - pendingItemsToUpdate = [] - + pendingItemsToUpdate = [] \ No newline at end of file diff --git a/service.py b/service.py index 6b75dbf7..55c8b664 100644 --- a/service.py +++ b/service.py @@ -35,16 +35,15 @@ class Service(): def __init__(self, *args ): self.KodiMonitor = KodiMonitor.Kodi_Monitor() addonName = self.addonName - self.className = self.__class__.__name__ self.logMsg("Starting Monitor", 0) self.logMsg("======== START %s ========" % addonName, 0) self.logMsg("KODI Version: %s" % xbmc.getInfoLabel("System.BuildVersion"), 0) self.logMsg("%s Version: %s" % (addonName, self.clientInfo.getVersion()), 0) - pass def logMsg(self, msg, lvl=1): + self.className = self.__class__.__name__ utils.logMsg("%s %s" % (self.addonName, self.className), str(msg), int(lvl)) def ServiceEntryPoint(self): @@ -77,18 +76,18 @@ class Service(): playTime = xbmc.Player().getTime() totalTime = xbmc.Player().getTotalTime() currentFile = xbmc.Player().getPlayingFile() - + if(player.played_information.get(currentFile) != None): player.played_information[currentFile]["currentPosition"] = playTime # send update td = datetime.today() - lastProgressUpdate secDiff = td.seconds - if(secDiff > 10): + if(secDiff > 3): try: player.reportPlayback() except Exception, msg: - xbmc.log("MB3 Sync Service -> Exception reporting progress : " + msg) + self.logMsg("Exception reporting progress: %s" % msg) pass lastProgressUpdate = datetime.today() # only try autoplay when there's 20 seconds or less remaining and only once! @@ -97,7 +96,7 @@ class Service(): player.autoPlayPlayback() except Exception, e: - xbmc.log("MB3 Sync Service -> Exception in Playback Monitor Service : " + str(e)) + self.logMsg("Exception in Playback Monitor Service: %s" % e) pass else: if (self.newUserClient == None): @@ -113,11 +112,11 @@ class Service(): #full sync if(startupComplete == False): - xbmc.log("Doing_Db_Sync: syncDatabase (Started)") + self.logMsg("Doing_Db_Sync: syncDatabase (Started)") libSync = librarySync.syncDatabase() - xbmc.log("Doing_Db_Sync: syncDatabase (Finished) " + str(libSync)) + self.logMsg("Doing_Db_Sync: syncDatabase (Finished) " + str(libSync)) countSync = librarySync.updatePlayCounts() - xbmc.log("Doing_Db_Sync: updatePlayCounts (Finished) " + str(countSync)) + self.logMsg("Doing_Db_Sync: updatePlayCounts (Finished) " + str(countSync)) # Force refresh newly set thumbnails xbmc.executebuiltin("UpdateLibrary(video)") @@ -130,9 +129,9 @@ class Service(): WebSocketThread().processPendingActions() else: - xbmc.log("Not authenticated yet") + self.logMsg("Not authenticated yet", 0) - utils.logMsg("MB3 Sync Service", "stopping Service",0) + self.logMsg("stopping Service", 0) # If user reset library database. WINDOW = xbmcgui.Window(10000)