Plex Companion: correctly tell when we stop playing
This commit is contained in:
parent
6ea203e9a1
commit
fc71fcf1fb
2 changed files with 70 additions and 43 deletions
|
@ -180,6 +180,7 @@ class PlexCompanion(threading.Thread):
|
||||||
message_count += 1
|
message_count += 1
|
||||||
if httpd:
|
if httpd:
|
||||||
if not t.isAlive():
|
if not t.isAlive():
|
||||||
|
# Use threads cause the method will stall
|
||||||
t = threading.Thread(target=httpd.handle_request)
|
t = threading.Thread(target=httpd.handle_request)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,15 @@ class SubscriptionManager:
|
||||||
self.serverlist = []
|
self.serverlist = []
|
||||||
self.subscribers = {}
|
self.subscribers = {}
|
||||||
self.info = {}
|
self.info = {}
|
||||||
self.lastkey = ""
|
self.key = ""
|
||||||
self.containerKey = ""
|
self.containerKey = ""
|
||||||
self.lastratingkey = ""
|
# We need one pass with previous rating key
|
||||||
|
# Tuple: (<type>, <ratingkey>)
|
||||||
|
self.ratingkey = self.lastratingkey = {
|
||||||
|
'video': "",
|
||||||
|
'music': "",
|
||||||
|
'photo': ""
|
||||||
|
}
|
||||||
self.volume = 0
|
self.volume = 0
|
||||||
self.mute = '0'
|
self.mute = '0'
|
||||||
self.server = ""
|
self.server = ""
|
||||||
|
@ -62,65 +68,79 @@ class SubscriptionManager:
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def getTimelineXML(self, playerid, ptype):
|
def getTimelineXML(self, playerid, ptype):
|
||||||
|
"""
|
||||||
|
If playerid is None => player stopped
|
||||||
|
"""
|
||||||
if playerid is not None:
|
if playerid is not None:
|
||||||
info = self.getPlayerProperties(playerid)
|
self.info = self.getPlayerProperties(playerid)
|
||||||
|
|
||||||
# save this info off so the server update can use it too
|
# save this info off so the server update can use it too
|
||||||
self.playerprops[playerid] = info;
|
self.playerprops[playerid] = self.info
|
||||||
state = info['state']
|
state = self.info['state']
|
||||||
time = info['time']
|
time = self.info['time']
|
||||||
else:
|
else:
|
||||||
state = "stopped"
|
state = "stopped"
|
||||||
time = 0
|
time = 0
|
||||||
ret = "\r\n"+' <Timeline state="%s" time="%s" type="%s"' % (state, time, ptype)
|
ret = "\r\n"+' <Timeline state="%s" time="%s" type="%s"' % (state, time, ptype)
|
||||||
if playerid is None:
|
if playerid is None and not self.lastratingkey[ptype]:
|
||||||
|
# We already told everyone that we stopped
|
||||||
ret += ' seekRange="0-0"'
|
ret += ' seekRange="0-0"'
|
||||||
ret += ' />'
|
ret += ' />'
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# pbmc_server = str(WINDOW.getProperty('plexbmc.nowplaying.server'))
|
|
||||||
# userId = str(WINDOW.getProperty('currUserId'))
|
|
||||||
pbmc_server = window('pms_server')
|
pbmc_server = window('pms_server')
|
||||||
if pbmc_server:
|
if pbmc_server:
|
||||||
(self.protocol, self.server, self.port) = \
|
(self.protocol, self.server, self.port) = \
|
||||||
pbmc_server.split(':')
|
pbmc_server.split(':')
|
||||||
self.server = self.server.replace('/', '')
|
self.server = self.server.replace('/', '')
|
||||||
keyid = None
|
keyid = None
|
||||||
count = 0
|
if playerid is not None:
|
||||||
while not keyid:
|
count = 0
|
||||||
if count > 300:
|
while not keyid:
|
||||||
break
|
if count > 300:
|
||||||
keyid = window('Plex_currently_playing_itemid')
|
break
|
||||||
xbmc.sleep(100)
|
keyid = window('Plex_currently_playing_itemid')
|
||||||
count += 1
|
xbmc.sleep(10)
|
||||||
|
count += 1
|
||||||
if keyid:
|
if keyid:
|
||||||
self.lastkey = "/library/metadata/%s"%keyid
|
self.key = "/library/metadata/%s" % keyid
|
||||||
self.lastratingkey = keyid
|
self.lastratingkey[ptype] = self.ratingkey[ptype] = keyid
|
||||||
ret += ' location="%s"' % (self.mainlocation)
|
ret += ' location="%s"' % self.mainlocation
|
||||||
ret += ' key="%s"' % (self.lastkey)
|
ret += ' key="%s"' % self.key
|
||||||
ret += ' ratingKey="%s"' % (self.lastratingkey)
|
ret += ' ratingKey="%s"' % self.ratingkey[ptype]
|
||||||
|
elif self.lastratingkey[ptype]:
|
||||||
|
# Currently not playing a Plex item (maybe stopped)
|
||||||
|
# We need to tell everyone exactly once
|
||||||
|
self.key = "/library/metadata/%s" % self.lastratingkey[ptype]
|
||||||
|
ret += ' location="%s"' % self.mainlocation
|
||||||
|
ret += ' key="%s"' % self.key
|
||||||
|
ret += ' ratingKey="%s"' % self.lastratingkey[ptype]
|
||||||
|
# Done our job of telling we've stopped. Let's do that only once
|
||||||
|
self.lastratingkey[ptype] = ""
|
||||||
|
self.logMsg('Done telling everyone')
|
||||||
serv = self.getServerByHost(self.server)
|
serv = self.getServerByHost(self.server)
|
||||||
if info.get('playQueueID'):
|
if self.info.get('playQueueID'):
|
||||||
self.containerKey = "/playQueues/%s" % info.get('playQueueID')
|
self.containerKey = "/playQueues/%s" % self.info.get('playQueueID')
|
||||||
ret += ' playQueueID="%s"' % info.get('playQueueID')
|
ret += ' playQueueID="%s"' % self.info.get('playQueueID')
|
||||||
ret += ' playQueueVersion="%s"' % info.get('playQueueVersion')
|
ret += ' playQueueVersion="%s"' % self.info.get('playQueueVersion')
|
||||||
ret += ' playQueueItemID="%s"' % (info.get('playQueueItemID'))
|
ret += ' playQueueItemID="%s"' % self.info.get('playQueueItemID')
|
||||||
ret += ' containerKey="%s"' % self.containerKey
|
ret += ' containerKey="%s"' % self.containerKey
|
||||||
elif keyid:
|
elif keyid or self.lastratingkey[ptype]:
|
||||||
self.containerKey = self.lastkey
|
self.containerKey = self.key
|
||||||
ret += ' containerKey="%s"' % (self.containerKey)
|
ret += ' containerKey="%s"' % (self.containerKey)
|
||||||
|
|
||||||
ret += ' duration="%s"' % info['duration']
|
ret += ' duration="%s"' % self.info['duration']
|
||||||
ret += ' seekRange="0-%s"' % info['duration']
|
ret += ' seekRange="0-%s"' % self.info['duration']
|
||||||
ret += ' controllable="%s"' % self.controllable()
|
ret += ' controllable="%s"' % self.controllable()
|
||||||
ret += ' machineIdentifier="%s"' % serv.get('uuid', "")
|
ret += ' machineIdentifier="%s"' % serv.get('uuid', "")
|
||||||
ret += ' protocol="%s"' % serv.get('protocol', "http")
|
ret += ' protocol="%s"' % serv.get('protocol', "http")
|
||||||
ret += ' address="%s"' % serv.get('server', self.server)
|
ret += ' address="%s"' % serv.get('server', self.server)
|
||||||
ret += ' port="%s"' % serv.get('port', self.port)
|
ret += ' port="%s"' % serv.get('port', self.port)
|
||||||
ret += ' guid="%s"' % info['guid']
|
ret += ' guid="%s"' % self.info['guid']
|
||||||
ret += ' volume="%s"' % info['volume']
|
ret += ' volume="%s"' % self.info['volume']
|
||||||
ret += ' shuffle="%s"' % info['shuffle']
|
ret += ' shuffle="%s"' % self.info['shuffle']
|
||||||
ret += ' mute="%s"' % self.mute
|
ret += ' mute="%s"' % self.mute
|
||||||
ret += ' repeat="%s"' % info['repeat']
|
ret += ' repeat="%s"' % self.info['repeat']
|
||||||
# Might need an update in the future
|
# Might need an update in the future
|
||||||
ret += ' subtitleStreamID="-1"'
|
ret += ' subtitleStreamID="-1"'
|
||||||
ret += ' audioStreamID="-1"'
|
ret += ' audioStreamID="-1"'
|
||||||
|
@ -132,7 +152,7 @@ class SubscriptionManager:
|
||||||
if commandID and self.subscribers.get(uuid, False):
|
if commandID and self.subscribers.get(uuid, False):
|
||||||
self.subscribers[uuid].commandID = int(commandID)
|
self.subscribers[uuid].commandID = int(commandID)
|
||||||
|
|
||||||
def notify(self, event = False):
|
def notify(self, event=False):
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
# Don't tell anyone if we don't know a Plex ID and are still playing
|
# Don't tell anyone if we don't know a Plex ID and are still playing
|
||||||
# (e.g. no stop called). Used for e.g. PVR/TV without PKC usage
|
# (e.g. no stop called). Used for e.g. PVR/TV without PKC usage
|
||||||
|
@ -145,12 +165,18 @@ class SubscriptionManager:
|
||||||
if self.subscribers:
|
if self.subscribers:
|
||||||
with threading.RLock():
|
with threading.RLock():
|
||||||
for sub in self.subscribers.values():
|
for sub in self.subscribers.values():
|
||||||
sub.send_update(msg, len(players)==0)
|
sub.send_update(msg, len(players) == 0)
|
||||||
self.notifyServer(players)
|
self.notifyServer(players)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def notifyServer(self, players):
|
def notifyServer(self, players):
|
||||||
for p in players.values():
|
conv = {
|
||||||
|
"video": "video",
|
||||||
|
"audio": "music",
|
||||||
|
"picture": "photo"
|
||||||
|
}
|
||||||
|
for typus, p in players.iteritems():
|
||||||
|
ptype = conv[typus]
|
||||||
info = self.playerprops[p.get('playerid')]
|
info = self.playerprops[p.get('playerid')]
|
||||||
params = {'state': 'stopped'}
|
params = {'state': 'stopped'}
|
||||||
params['containerKey'] = (self.containerKey or "/library/metadata/900000")
|
params['containerKey'] = (self.containerKey or "/library/metadata/900000")
|
||||||
|
@ -158,8 +184,8 @@ class SubscriptionManager:
|
||||||
params['containerKey'] = '/playQueues/' + info['playQueueID']
|
params['containerKey'] = '/playQueues/' + info['playQueueID']
|
||||||
params['playQueueVersion'] = info['playQueueVersion']
|
params['playQueueVersion'] = info['playQueueVersion']
|
||||||
params['playQueueItemID'] = info['playQueueItemID']
|
params['playQueueItemID'] = info['playQueueItemID']
|
||||||
params['key'] = (self.lastkey or "/library/metadata/900000")
|
params['key'] = (self.key or "/library/metadata/900000")
|
||||||
params['ratingKey'] = (self.lastratingkey or "900000")
|
params['ratingKey'] = (self.ratingkey[ptype] or "900000")
|
||||||
params['state'] = info['state']
|
params['state'] = info['state']
|
||||||
params['time'] = info['time']
|
params['time'] = info['time']
|
||||||
params['duration'] = info['duration']
|
params['duration'] = info['duration']
|
||||||
|
|
Loading…
Reference in a new issue