From 41eedf4d8e2dfedfbdad4e9aef1dba3943623933 Mon Sep 17 00:00:00 2001 From: Massimo Mund Date: Tue, 14 Mar 2017 20:50:49 +0100 Subject: [PATCH 1/2] Filter remote streams by their machine id - Running remote pulseaudio instances always create tunnel streams to the local version of pulseaudio, even they are not in actual use. This breaks our detection mechanism if there are streams running on a specific sink. Therefore filter them by their machine id. --- pulseaudio_dlna/pulseaudio.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/pulseaudio_dlna/pulseaudio.py b/pulseaudio_dlna/pulseaudio.py index 1dd60562..888beef4 100644 --- a/pulseaudio_dlna/pulseaudio.py +++ b/pulseaudio_dlna/pulseaudio.py @@ -38,6 +38,13 @@ logger = logging.getLogger('pulseaudio_dlna.pulseaudio') +try: + with open('/var/lib/dbus/machine-id', 'r') as f: + MACHINE_ID = unicode(f.readline().strip()) +except: + MACHINE_ID = None + logger.warning('Could not determine the pulseaudio machine-id!') + class PulseAudio(object): def __init__(self): @@ -118,9 +125,10 @@ def retry_on_fail(method, tries=5): if retry_on_fail(self.update_playback_streams) and \ retry_on_fail(self.update_sinks): for stream in self.streams: - for sink in self.sinks: - if sink.object_path == stream.device: - sink.streams.append(stream) + if stream.is_local_stream: + for sink in self.sinks: + if sink.object_path == stream.device: + sink.streams.append(stream) else: logger.error( 'Could not update sinks and streams. This normally indicates ' @@ -208,12 +216,14 @@ def new(self, bus, client_path): name_bytes = properties.get('application.name', []) icon_bytes = properties.get('application.icon_name', []) binary_bytes = properties.get('application.process.binary', []) + machine_id_bytes = properties.get('application.process.machine_id', []) return PulseClient( object_path=unicode(client_path), index=unicode(obj.Get('org.PulseAudio.Core1.Client', 'Index')), name=self._convert_bytes_to_unicode(name_bytes), icon=self._convert_bytes_to_unicode(icon_bytes), binary=self._convert_bytes_to_unicode(binary_bytes), + machine_id=self._convert_bytes_to_unicode(machine_id_bytes), ) except dbus.exceptions.DBusException: logger.error( @@ -227,7 +237,7 @@ class PulseClient(object): __shared_state = {} - def __init__(self, object_path, index, name, icon, binary): + def __init__(self, object_path, index, name, icon, binary, machine_id): if object_path not in self.__shared_state: self.__shared_state[object_path] = {} self.__dict__ = self.__shared_state[object_path] @@ -237,6 +247,7 @@ def __init__(self, object_path, index, name, icon, binary): self.name = name or 'unknown' self.icon = icon or 'unknown' self.binary = binary or 'unknown' + self.machine_id = machine_id def __eq__(self, other): return self.object_path == other.object_path @@ -439,6 +450,12 @@ def __init__(self, object_path, index, device, client): self.device = device self.client = client + @property + def is_local_stream(self): + if not MACHINE_ID or self.client.machine_id == MACHINE_ID: + return True + return False + def switch_to_source(self, index): cmd = [ 'pactl', From fa6e79a420b81263a3067eec57947f8340e0467d Mon Sep 17 00:00:00 2001 From: Massimo Mund Date: Wed, 15 Mar 2017 12:39:07 +0100 Subject: [PATCH 2/2] Added some debug information --- pulseaudio_dlna/pulseaudio.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pulseaudio_dlna/pulseaudio.py b/pulseaudio_dlna/pulseaudio.py index 888beef4..72ac0e4c 100644 --- a/pulseaudio_dlna/pulseaudio.py +++ b/pulseaudio_dlna/pulseaudio.py @@ -45,6 +45,8 @@ MACHINE_ID = None logger.warning('Could not determine the pulseaudio machine-id!') +logger.info('MACHINE_ID: {}'.format(MACHINE_ID)) + class PulseAudio(object): def __init__(self): @@ -452,6 +454,8 @@ def __init__(self, object_path, index, device, client): @property def is_local_stream(self): + logger.info('{} | {} = {}'.format( + self.object_path, self.client.machine_id, MACHINE_ID)) if not MACHINE_ID or self.client.machine_id == MACHINE_ID: return True return False @@ -712,7 +716,7 @@ def __handle_sink_update(self, sink_path): return for bridge in self.bridges: - logger.debug('\n{}'.format(bridge)) + logger.info('\n{}'.format(bridge)) if bridge.device.state == bridge.device.PLAYING: if len(bridge.sink.streams) == 0 and ( not self.disable_device_stop and