Merge pull request #1674 from croneter/py3-fix-socketserver

Fix Plex Companion not working by fixing some issues with PKC's http.server's BaseHTTPRequestHandler
This commit is contained in:
croneter 2021-10-20 14:55:58 +02:00 committed by GitHub
commit 937265dfc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 194 additions and 99 deletions

View file

@ -29,7 +29,6 @@ def getXArgsDeviceInfo(options=None, include_token=True):
""" """
xargs = { xargs = {
'Accept': '*/*', 'Accept': '*/*',
'Connection': 'keep-alive',
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",
# "Access-Control-Allow-Origin": "*", # "Access-Control-Allow-Origin": "*",
'Accept-Language': xbmc.getLanguage(xbmc.ISO_639_1), 'Accept-Language': xbmc.getLanguage(xbmc.ISO_639_1),
@ -42,6 +41,8 @@ def getXArgsDeviceInfo(options=None, include_token=True):
'X-Plex-Version': v.ADDON_VERSION, 'X-Plex-Version': v.ADDON_VERSION,
'X-Plex-Client-Identifier': getDeviceId(), 'X-Plex-Client-Identifier': getDeviceId(),
'X-Plex-Provides': 'client,controller,player,pubsub-player', 'X-Plex-Provides': 'client,controller,player,pubsub-player',
'X-Plex-Protocol': '1.0',
'Cache-Control': 'no-cache'
} }
if include_token and utils.window('pms_token'): if include_token and utils.window('pms_token'):
xargs['X-Plex-Token'] = utils.window('pms_token') xargs['X-Plex-Token'] = utils.window('pms_token')

View file

@ -429,6 +429,15 @@ def get_current_audio_stream_index(playerid):
'properties': ['currentaudiostream']})['result']['currentaudiostream']['index'] 'properties': ['currentaudiostream']})['result']['currentaudiostream']['index']
def get_current_video_stream_index(playerid):
"""
Returns the currently active video stream index [int]
"""
return JsonRPC('Player.GetProperties').execute({
'playerid': playerid,
'properties': ['currentvideostream']})['result']['currentvideostream']['index']
def get_current_subtitle_stream_index(playerid): def get_current_subtitle_stream_index(playerid):
""" """
Returns the currently active subtitle stream index [int] or None if there Returns the currently active subtitle stream index [int] or None if there

View file

@ -390,6 +390,8 @@ class KodiMonitor(xbmc.Monitor):
if not self._switched_to_plex_streams: if not self._switched_to_plex_streams:
# We need to switch to the Plex streams ONCE upon playback start # We need to switch to the Plex streams ONCE upon playback start
# after onavchange has been fired # after onavchange has been fired
item.init_kodi_streams()
item.switch_to_plex_stream('video')
if utils.settings('audioStreamPick') == '0': if utils.settings('audioStreamPick') == '0':
item.switch_to_plex_stream('audio') item.switch_to_plex_stream('audio')
if utils.settings('subtitleStreamPick') == '0': if utils.settings('subtitleStreamPick') == '0':

View file

@ -179,9 +179,11 @@ class PlaylistItem(object):
# Get the Plex audio and subtitle streams in the same order as Kodi # Get the Plex audio and subtitle streams in the same order as Kodi
# uses them (Kodi uses indexes to activate them, not ids like Plex) # uses them (Kodi uses indexes to activate them, not ids like Plex)
self._streams_have_been_processed = False self._streams_have_been_processed = False
self._video_streams = None
self._audio_streams = None self._audio_streams = None
self._subtitle_streams = None self._subtitle_streams = None
# Which Kodi streams are active? # Which Kodi streams are active?
self.current_kodi_video_stream = None
self.current_kodi_audio_stream = None self.current_kodi_audio_stream = None
# False means "deactivated", None means "we do not have a Kodi # False means "deactivated", None means "we do not have a Kodi
# equivalent for this Plex subtitle" # equivalent for this Plex subtitle"
@ -201,6 +203,12 @@ class PlaylistItem(object):
def uri(self): def uri(self):
return self._uri return self._uri
@property
def video_streams(self):
if not self._streams_have_been_processed:
self._process_streams()
return self._video_streams
@property @property
def audio_streams(self): def audio_streams(self):
if not self._streams_have_been_processed: if not self._streams_have_been_processed:
@ -213,6 +221,18 @@ class PlaylistItem(object):
self._process_streams() self._process_streams()
return self._subtitle_streams return self._subtitle_streams
@property
def current_plex_video_stream(self):
return self.plex_stream_index(self.current_kodi_video_stream, 'video')
@property
def current_plex_audio_stream(self):
return self.plex_stream_index(self.current_kodi_audio_stream, 'audio')
@property
def current_plex_sub_stream(self):
return self.plex_stream_index(self.current_kodi_sub_stream, 'subtitle')
def __repr__(self): def __repr__(self):
return ("{{" return ("{{"
"'id': {self.id}, " "'id': {self.id}, "
@ -244,6 +264,13 @@ class PlaylistItem(object):
# the same in Kodi and Plex # the same in Kodi and Plex
self._audio_streams = [x for x in self.api.plex_media_streams() self._audio_streams = [x for x in self.api.plex_media_streams()
if x.get('streamType') == '2'] if x.get('streamType') == '2']
# Same for video streams
self._video_streams = [x for x in self.api.plex_media_streams()
if x.get('streamType') == '1']
if len(self._video_streams) == 1:
# Add a selected = "1" attribute to let our logic stand!
# Missing if there is only 1 video stream present
self._video_streams[0].set('selected', '1')
self._streams_have_been_processed = True self._streams_have_been_processed = True
def _get_iterator(self, stream_type): def _get_iterator(self, stream_type):
@ -251,6 +278,17 @@ class PlaylistItem(object):
return self.audio_streams return self.audio_streams
elif stream_type == 'subtitle': elif stream_type == 'subtitle':
return self.subtitle_streams return self.subtitle_streams
elif stream_type == 'video':
return self.video_streams
def init_kodi_streams(self):
"""
Initializes all streams after Kodi has started playing this video
"""
self.current_kodi_video_stream = js.get_current_video_stream_index(v.KODI_VIDEO_PLAYER_ID)
self.current_kodi_audio_stream = js.get_current_audio_stream_index(v.KODI_VIDEO_PLAYER_ID)
self.current_kodi_sub_stream = False if not js.get_subtitle_enabled(v.KODI_VIDEO_PLAYER_ID) \
else js.get_current_subtitle_stream_index(v.KODI_VIDEO_PLAYER_ID)
def plex_stream_index(self, kodi_stream_index, stream_type): def plex_stream_index(self, kodi_stream_index, stream_type):
""" """
@ -261,6 +299,8 @@ class PlaylistItem(object):
""" """
if stream_type == 'audio': if stream_type == 'audio':
return int(self.audio_streams[kodi_stream_index].get('id')) return int(self.audio_streams[kodi_stream_index].get('id'))
elif stream_type == 'video':
return int(self.video_streams[kodi_stream_index].get('id'))
elif stream_type == 'subtitle': elif stream_type == 'subtitle':
try: try:
return int(self.subtitle_streams[kodi_stream_index].get('id')) return int(self.subtitle_streams[kodi_stream_index].get('id'))
@ -324,10 +364,39 @@ class PlaylistItem(object):
PF.change_audio_stream(plex_stream_index, self.api.part_id()) PF.change_audio_stream(plex_stream_index, self.api.part_id())
self.current_kodi_audio_stream = kodi_stream_index self.current_kodi_audio_stream = kodi_stream_index
def on_kodi_video_stream_change(self, kodi_stream_index):
"""
Call this method if Kodi changed its video stream and you want Plex to
know. kodi_stream_index [int]
"""
plex_stream_index = int(self.video_streams[kodi_stream_index].get('id'))
LOG.debug('Changing Plex video stream to %s, Kodi index %s',
plex_stream_index, kodi_stream_index)
PF.change_video_stream(plex_stream_index, self.api.part_id())
self.current_kodi_video_stream = kodi_stream_index
def switch_to_plex_streams(self): def switch_to_plex_streams(self):
self.switch_to_plex_stream('video')
self.switch_to_plex_stream('audio') self.switch_to_plex_stream('audio')
self.switch_to_plex_stream('subtitle') self.switch_to_plex_stream('subtitle')
@staticmethod
def _set_kodi_stream_if_different(kodi_index, typus):
if typus == 'video':
current = js.get_current_video_stream_index(v.KODI_VIDEO_PLAYER_ID)
if current != kodi_index:
LOG.debug('Switching video stream')
app.APP.player.setVideoStream(kodi_index)
else:
LOG.debug('Not switching video stream (no change)')
elif typus == 'audio':
current = js.get_current_audio_stream_index(v.KODI_VIDEO_PLAYER_ID)
if current != kodi_index:
LOG.debug('Switching audio stream')
app.APP.player.setAudioStream(kodi_index)
else:
LOG.debug('Not switching audio stream (no change)')
def switch_to_plex_stream(self, typus): def switch_to_plex_stream(self, typus):
try: try:
plex_index, language_tag = self.active_plex_stream_index(typus) plex_index, language_tag = self.active_plex_stream_index(typus)
@ -351,22 +420,34 @@ class PlaylistItem(object):
# If we're choosing an "illegal" index, this function does # If we're choosing an "illegal" index, this function does
# need seem to fail nor log any errors # need seem to fail nor log any errors
if typus == 'audio': if typus == 'audio':
app.APP.player.setAudioStream(kodi_index) self._set_kodi_stream_if_different(kodi_index, 'audio')
else: elif typus == 'subtitle':
app.APP.player.setSubtitleStream(kodi_index) app.APP.player.setSubtitleStream(kodi_index)
app.APP.player.showSubtitles(True) app.APP.player.showSubtitles(True)
elif typus == 'video':
self._set_kodi_stream_if_different(kodi_index, 'video')
if typus == 'audio': if typus == 'audio':
self.current_kodi_audio_stream = kodi_index self.current_kodi_audio_stream = kodi_index
else: elif typus == 'subtitle':
self.current_kodi_sub_stream = kodi_index self.current_kodi_sub_stream = kodi_index
elif typus == 'video':
self.current_kodi_video_stream = kodi_index
def on_av_change(self, playerid): def on_av_change(self, playerid):
"""
Call this method if Kodi reports an "AV-Change"
(event "Player.OnAVChange")
"""
kodi_video_stream = js.get_current_video_stream_index(playerid)
kodi_audio_stream = js.get_current_audio_stream_index(playerid) kodi_audio_stream = js.get_current_audio_stream_index(playerid)
sub_enabled = js.get_subtitle_enabled(playerid) sub_enabled = js.get_subtitle_enabled(playerid)
kodi_sub_stream = js.get_current_subtitle_stream_index(playerid) kodi_sub_stream = js.get_current_subtitle_stream_index(playerid)
# Audio # Audio
if kodi_audio_stream != self.current_kodi_audio_stream: if kodi_audio_stream != self.current_kodi_audio_stream:
self.on_kodi_audio_stream_change(kodi_audio_stream) self.on_kodi_audio_stream_change(kodi_audio_stream)
# Video
if kodi_video_stream != self.current_kodi_video_stream:
self.on_kodi_video_stream_change(kodi_audio_stream)
# Subtitles - CURRENTLY BROKEN ON THE KODI SIDE! # Subtitles - CURRENTLY BROKEN ON THE KODI SIDE!
# current_kodi_sub_stream may also be zero # current_kodi_sub_stream may also be zero
subs_off = (None, False) subs_off = (None, False)
@ -376,6 +457,32 @@ class PlaylistItem(object):
and kodi_sub_stream != self.current_kodi_sub_stream)): and kodi_sub_stream != self.current_kodi_sub_stream)):
self.on_kodi_subtitle_stream_change(kodi_sub_stream, sub_enabled) self.on_kodi_subtitle_stream_change(kodi_sub_stream, sub_enabled)
def on_plex_stream_change(self, plex_data):
"""
Call this method if Plex Companion wants to change streams
"""
if 'audioStreamID' in plex_data:
plex_index = int(plex_data['audioStreamID'])
kodi_index = self.kodi_stream_index(plex_index, 'audio')
self._set_kodi_stream_if_different(kodi_index, 'audio')
self.current_kodi_audio_stream = kodi_index
if 'videoStreamID' in plex_data:
plex_index = int(plex_data['videoStreamID'])
kodi_index = self.kodi_stream_index(plex_index, 'video')
self._set_kodi_stream_if_different(kodi_index, 'video')
self.current_kodi_video_stream = kodi_index
if 'subtitleStreamID' in plex_data:
plex_index = int(plex_data['subtitleStreamID'])
if plex_index == 0:
app.APP.player.showSubtitles(False)
kodi_index = False
else:
kodi_index = self.kodi_stream_index(plex_index, 'subtitle')
if kodi_index:
app.APP.player.setSubtitleStream(kodi_index)
app.APP.player.showSubtitles(True)
self.current_kodi_sub_stream = kodi_index
def playlist_item_from_kodi(kodi_item): def playlist_item_from_kodi(kodi_item):
""" """

View file

@ -191,19 +191,7 @@ class PlexCompanion(backgroundthread.KillableThread):
playqueue = PQ.get_playqueue_from_type( playqueue = PQ.get_playqueue_from_type(
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[data['type']]) v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[data['type']])
pos = js.get_position(playqueue.playlistid) pos = js.get_position(playqueue.playlistid)
if 'audioStreamID' in data: playqueue.items[pos].on_plex_stream_change(data)
index = playqueue.items[pos].kodi_stream_index(
data['audioStreamID'], 'audio')
app.APP.player.setAudioStream(index)
elif 'subtitleStreamID' in data:
if data['subtitleStreamID'] == '0':
app.APP.player.showSubtitles(False)
else:
index = playqueue.items[pos].kodi_stream_index(
data['subtitleStreamID'], 'subtitle')
app.APP.player.setSubtitleStream(index)
else:
LOG.error('Unknown setStreams command: %s', data)
@staticmethod @staticmethod
def _process_refresh(data): def _process_refresh(data):
@ -300,7 +288,7 @@ class PlexCompanion(backgroundthread.KillableThread):
start_count = 0 start_count = 0
while True: while True:
try: try:
httpd = listener.ThreadedHTTPServer( httpd = listener.PKCHTTPServer(
client, client,
subscription_manager, subscription_manager,
('', v.COMPANION_PORT), ('', v.COMPANION_PORT),

View file

@ -1148,3 +1148,17 @@ def change_audio_stream(plex_stream_id, part_id):
url = '{server}/library/parts/%s' % part_id url = '{server}/library/parts/%s' % part_id
return DU().downloadUrl(utils.extend_url(url, arguments), return DU().downloadUrl(utils.extend_url(url, arguments),
action_type='PUT') action_type='PUT')
def change_video_stream(plex_stream_id, part_id):
"""
Tell the PMS to display another video stream
- We always do this for ALL parts of a video
"""
arguments = {
'videoStreamID': plex_stream_id,
'allParts': 1
}
url = '{server}/library/parts/%s' % part_id
return DU().downloadUrl(utils.extend_url(url, arguments),
action_type='PUT')

View file

@ -5,8 +5,7 @@ Plex Companion listener
""" """
from logging import getLogger from logging import getLogger
from re import sub from re import sub
from socketserver import ThreadingMixIn from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from http.server import HTTPServer, BaseHTTPRequestHandler
from .. import utils, companion, json_rpc as js, clientinfo, variables as v from .. import utils, companion, json_rpc as js, clientinfo, variables as v
from .. import app from .. import app
@ -45,7 +44,7 @@ class MyHandler(BaseHTTPRequestHandler):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.serverlist = [] self.serverlist = []
BaseHTTPRequestHandler.__init__(self, *args, **kwargs) super().__init__(*args, **kwargs)
def log_message(self, format, *args): def log_message(self, format, *args):
''' '''
@ -62,6 +61,7 @@ class MyHandler(BaseHTTPRequestHandler):
self.answer_request(1) self.answer_request(1)
def do_OPTIONS(self): def do_OPTIONS(self):
LOG.debug("Serving OPTIONS request...")
self.send_response(200) self.send_response(200)
self.send_header('Content-Length', '0') self.send_header('Content-Length', '0')
self.send_header('X-Plex-Client-Identifier', v.PKC_MACHINE_IDENTIFIER) self.send_header('X-Plex-Client-Identifier', v.PKC_MACHINE_IDENTIFIER)
@ -78,24 +78,16 @@ class MyHandler(BaseHTTPRequestHandler):
'x-plex-device-name, x-plex-platform, x-plex-product, accept, ' 'x-plex-device-name, x-plex-platform, x-plex-product, accept, '
'x-plex-device, x-plex-device-screen-resolution') 'x-plex-device, x-plex-device-screen-resolution')
self.end_headers() self.end_headers()
self.wfile.close()
def sendOK(self):
self.send_response(200)
def response(self, body, headers=None, code=200): def response(self, body, headers=None, code=200):
headers = {} if headers is None else headers headers = {} if headers is None else headers
try: self.send_response(code)
self.send_response(code) for key in headers:
for key in headers: self.send_header(key, headers[key])
self.send_header(key, headers[key]) self.send_header('Content-Length', len(body))
self.send_header('Content-Length', len(body)) self.end_headers()
self.send_header('Connection', "close") if body:
self.end_headers()
self.wfile.write(body.encode('utf-8')) self.wfile.write(body.encode('utf-8'))
self.wfile.close()
except Exception:
pass
def answer_request(self, send_data): def answer_request(self, send_data):
self.serverlist = self.server.client.getServerList() self.serverlist = self.server.client.getServerList()
@ -108,23 +100,37 @@ class MyHandler(BaseHTTPRequestHandler):
params = {} params = {}
for key in paramarrays: for key in paramarrays:
params[key] = paramarrays[key][0] params[key] = paramarrays[key][0]
LOG.debug("remote request_path: %s", request_path) LOG.debug("remote request_path: %s, received from %s with headers: %s",
request_path, self.client_address, self.headers.items())
LOG.debug("params received from remote: %s", params) LOG.debug("params received from remote: %s", params)
sub_mgr.update_command_id(self.headers.get( sub_mgr.update_command_id(self.headers.get(
'X-Plex-Client-Identifier', self.client_address[0]), 'X-Plex-Client-Identifier', self.client_address[0]),
params.get('commandID')) params.get('commandID'))
conntype = self.headers.get('Connection', '')
if conntype.lower() == 'keep-alive':
headers = {
'Connection': 'Keep-Alive',
'Keep-Alive': 'timeout=20'
}
else:
headers = {'Connection': 'Close'}
if request_path == "version": if request_path == "version":
self.response( self.response(
"PlexKodiConnect Plex Companion: Running\nVersion: %s" "PlexKodiConnect Plex Companion: Running\nVersion: %s"
% v.ADDON_VERSION) % v.ADDON_VERSION,
headers)
elif request_path == "verify": elif request_path == "verify":
self.response("XBMC JSON connection test:\n" + js.ping()) self.response("XBMC JSON connection test:\n" + js.ping(),
headers)
elif request_path == 'resources': elif request_path == 'resources':
self.response( self.response(
RESOURCES_XML.format( RESOURCES_XML.format(
title=v.DEVICENAME, title=v.DEVICENAME,
machineIdentifier=v.PKC_MACHINE_IDENTIFIER), machineIdentifier=v.PKC_MACHINE_IDENTIFIER),
clientinfo.getXArgsDeviceInfo(include_token=False)) clientinfo.getXArgsDeviceInfo(options=headers,
include_token=False))
elif request_path == 'player/timeline/poll': elif request_path == 'player/timeline/poll':
# Plex web does polling if connected to PKC via Companion # Plex web does polling if connected to PKC via Companion
# Only reply if there is indeed something playing # Only reply if there is indeed something playing
@ -159,7 +165,7 @@ class MyHandler(BaseHTTPRequestHandler):
'Access-Control-Expose-Headers': 'Access-Control-Expose-Headers':
'X-Plex-Client-Identifier', 'X-Plex-Client-Identifier',
'Content-Type': 'text/xml;charset=utf-8' 'Content-Type': 'text/xml;charset=utf-8'
}) }.update(headers))
elif not sub_mgr.stop_sent_to_web: elif not sub_mgr.stop_sent_to_web:
sub_mgr.stop_sent_to_web = True sub_mgr.stop_sent_to_web = True
LOG.debug('Signaling STOP to Plex Web') LOG.debug('Signaling STOP to Plex Web')
@ -173,11 +179,11 @@ class MyHandler(BaseHTTPRequestHandler):
'Access-Control-Expose-Headers': 'Access-Control-Expose-Headers':
'X-Plex-Client-Identifier', 'X-Plex-Client-Identifier',
'Content-Type': 'text/xml;charset=utf-8' 'Content-Type': 'text/xml;charset=utf-8'
}) }.update(headers))
else: else:
# Fail connection with HTTP 500 error - has been open too long # We're not playing anything yet, just reply with a 200
self.response( self.response(
'Need to close this connection on the PKC side', msg,
{ {
'X-Plex-Client-Identifier': v.PKC_MACHINE_IDENTIFIER, 'X-Plex-Client-Identifier': v.PKC_MACHINE_IDENTIFIER,
'X-Plex-Protocol': '1.0', 'X-Plex-Protocol': '1.0',
@ -186,11 +192,12 @@ class MyHandler(BaseHTTPRequestHandler):
'Access-Control-Expose-Headers': 'Access-Control-Expose-Headers':
'X-Plex-Client-Identifier', 'X-Plex-Client-Identifier',
'Content-Type': 'text/xml;charset=utf-8' 'Content-Type': 'text/xml;charset=utf-8'
}, }.update(headers))
code=500)
elif "/subscribe" in request_path: elif "/subscribe" in request_path:
self.response(v.COMPANION_OK_MESSAGE, headers['Content-Type'] = 'text/xml;charset=utf-8'
clientinfo.getXArgsDeviceInfo(include_token=False)) headers = clientinfo.getXArgsDeviceInfo(options=headers,
include_token=False)
self.response(v.COMPANION_OK_MESSAGE, headers)
protocol = params.get('protocol') protocol = params.get('protocol')
host = self.client_address[0] host = self.client_address[0]
port = params.get('port') port = params.get('port')
@ -202,23 +209,23 @@ class MyHandler(BaseHTTPRequestHandler):
uuid, uuid,
command_id) command_id)
elif "/unsubscribe" in request_path: elif "/unsubscribe" in request_path:
self.response(v.COMPANION_OK_MESSAGE, headers['Content-Type'] = 'text/xml;charset=utf-8'
clientinfo.getXArgsDeviceInfo(include_token=False)) headers = clientinfo.getXArgsDeviceInfo(options=headers,
include_token=False)
self.response(v.COMPANION_OK_MESSAGE, headers)
uuid = self.headers.get('X-Plex-Client-Identifier') \ uuid = self.headers.get('X-Plex-Client-Identifier') \
or self.client_address[0] or self.client_address[0]
sub_mgr.remove_subscriber(uuid) sub_mgr.remove_subscriber(uuid)
else: else:
# Throw it to companion.py # Throw it to companion.py
companion.process_command(request_path, params) companion.process_command(request_path, params)
self.response('', clientinfo.getXArgsDeviceInfo(include_token=False)) headers['Content-Type'] = 'text/xml;charset=utf-8'
headers = clientinfo.getXArgsDeviceInfo(options=headers,
include_token=False)
self.response(v.COMPANION_OK_MESSAGE, headers)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): class PKCHTTPServer(ThreadingHTTPServer):
"""
Using ThreadingMixIn Thread magic
"""
daemon_threads = True
def __init__(self, client, subscription_manager, *args, **kwargs): def __init__(self, client, subscription_manager, *args, **kwargs):
""" """
client: Class handle to plexgdm.plexgdm. We can thus ask for an up-to- client: Class handle to plexgdm.plexgdm. We can thus ask for an up-to-
@ -228,4 +235,4 @@ class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
""" """
self.client = client self.client = client
self.subscription_manager = subscription_manager self.subscription_manager = subscription_manager
HTTPServer.__init__(self, *args, **kwargs) super().__init__(*args, **kwargs)

View file

@ -93,12 +93,12 @@ class plexgdm(object):
try: try:
log.debug("Sending registration data: HELLO %s\n%s" log.debug("Sending registration data: HELLO %s\n%s"
% (self.client_header, self.client_data)) % (self.client_header, self.client_data))
self.update_sock.sendto("HELLO %s\n%s" msg = 'HELLO {}\n{}'.format(self.client_header, self.client_data)
% (self.client_header, self.client_data), self.update_sock.sendto(msg.encode('utf-8'),
self.client_register_group) self.client_register_group)
log.debug('(Re-)registering PKC Plex Companion successful') log.debug('(Re-)registering PKC Plex Companion successful')
except Exception: except Exception as exc:
log.error("Unable to send registration message") log.error("Unable to send registration message. Error: %s", exc)
def client_update(self): def client_update(self):
self.update_sock = socket.socket(socket.AF_INET, self.update_sock = socket.socket(socket.AF_INET,

View file

@ -249,27 +249,10 @@ class SubscriptionMgr(object):
answ['token'] = playqueue.plex_transient_token answ['token'] = playqueue.plex_transient_token
# Process audio and subtitle streams # Process audio and subtitle streams
if ptype == v.PLEX_PLAYLIST_TYPE_VIDEO: if ptype == v.PLEX_PLAYLIST_TYPE_VIDEO:
strm_id = self._plex_stream_index(playerid, 'audio') answ['videoStreamID'] = str(item.current_plex_video_stream)
if strm_id: answ['audioStreamID'] = str(item.current_plex_audio_stream)
answ['audioStreamID'] = strm_id # Mind the zero - meaning subs are deactivated
else: answ['subtitleStreamID'] = str(item.current_plex_sub_stream or 0)
LOG.error('We could not select a Plex audiostream')
strm_id = self._plex_stream_index(playerid, 'video')
if strm_id:
answ['videoStreamID'] = strm_id
else:
LOG.error('We could not select a Plex videostream')
if info['subtitleenabled']:
try:
strm_id = self._plex_stream_index(playerid, 'subtitle')
except KeyError:
# subtitleenabled can be True while currentsubtitle can
# still be {}
strm_id = None
if strm_id is not None:
# If None, then the subtitle is only present on Kodi
# side
answ['subtitleStreamID'] = strm_id
return answ return answ
def signal_stop(self): def signal_stop(self):
@ -285,22 +268,6 @@ class SubscriptionMgr(object):
self.last_params, self.last_params,
timeout=0.0001) timeout=0.0001)
def _plex_stream_index(self, playerid, stream_type):
"""
Returns the current Plex stream index [str] for the player playerid
stream_type: 'video', 'audio', 'subtitle'
"""
playqueue = PQ.PLAYQUEUES[playerid]
info = app.PLAYSTATE.player_states[playerid]
position = self._get_correct_position(info, playqueue)
if info[STREAM_DETAILS[stream_type]] == -1:
kodi_stream_index = -1
else:
kodi_stream_index = info[STREAM_DETAILS[stream_type]]['index']
return playqueue.items[position].plex_stream_index(kodi_stream_index,
stream_type)
def update_command_id(self, uuid, command_id): def update_command_id(self, uuid, command_id):
""" """
Updates the Plex Companien client with the machine identifier uuid with Updates the Plex Companien client with the machine identifier uuid with