def start_sending_sound(remote_decoders, local_decoders, remote_pulseaudio_server, remote_pulseaudio_id): try: matching_codecs = [x for x in remote_decoders if x in local_decoders] ordered_codecs = [x for x in CODEC_ORDER if x in matching_codecs] if len(ordered_codecs) == 0: log.error( "no matching codecs between remote (%s) and local (%s) - sound disabled", remote_decoders, local_decoders) return None codec = ordered_codecs[0] log.info("using sound codec %s", codec) from xpra.sound.src import SoundSource if SOUND_TEST_MODE: sound_source = SoundSource("audiotestsrc", { "wave": 2, "freq": 110, "volume": 0.4 }, codec, {}) log.info("using test sound source") else: from xpra.sound.pulseaudio_util import has_pa, get_pa_device_options from xpra.sound.pulseaudio_util import get_pulse_server, get_pulse_id if not has_pa(): log.error("pulseaudio not supported - sound disabled") return None pa_server = get_pulse_server() log( "start sound, remote pulseaudio server=%s, local pulseaudio server=%s", remote_pulseaudio_server, pa_server) if remote_pulseaudio_server and ( remote_pulseaudio_server == pa_server or len(pa_server) > 16 and remote_pulseaudio_server.endswith(pa_server)): log.error( "identical pulseaudio server, refusing to create a sound loop - sound disabled" ) return None pa_id = get_pulse_id() log("start sound, client id=%s, server id=%s", remote_pulseaudio_id, pa_id) if remote_pulseaudio_id and remote_pulseaudio_id == pa_id: log.error( "identical pulseaudio ID, refusing to create a sound loop - sound disabled" ) return None monitor_devices = get_pa_device_options(True, False) log("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices) == 0: log.error( "could not detect any pulseaudio monitor devices - sound forwarding is disabled" ) return None if len(monitor_devices) > 1: log.warn("found more than one monitor device: %s", monitor_devices) log.warn("using: %s", monitor_devices.items()[0][1]) monitor_device = monitor_devices.items()[0][0] sound_source = SoundSource("pulsesrc", {"device": monitor_device}, codec, {}) log.info("starting sound using pulseaudio device %s", monitor_device) return sound_source except Exception, e: log.error("error setting up sound: %s", e, exc_info=True) return None
def __init__(self, *pipeline_args): from xpra.sound.src import SoundSource sound_pipeline = SoundSource(*pipeline_args) sound_subprocess.__init__(self, sound_pipeline, [], ["new-stream", "new-buffer"]) self.large_packets = ["new-buffer"]
def start_sending_sound(codec, volume, remote_decoders, local_decoders, remote_pulseaudio_server, remote_pulseaudio_id): assert has_gst try: matching_codecs = [x for x in remote_decoders if x in local_decoders] ordered_codecs = [x for x in CODEC_ORDER if x in matching_codecs] if len(ordered_codecs) == 0: log.error( "no matching codecs between remote (%s) and local (%s) - sound disabled", remote_decoders, local_decoders) return None if codec is not None and codec not in matching_codecs: log.warn("invalid codec specified: %s", codec) codec = None if codec is None: codec = ordered_codecs[0] log("using sound codec %s", codec) from xpra.sound.src import SoundSource if SOUND_TEST_MODE: sound_source = SoundSource("audiotestsrc", { "wave": 2, "freq": 110, "volume": 0.4 }, codec, volume, {}) log.info("using test sound source") else: from xpra.sound.pulseaudio_util import has_pa, get_pa_device_options, get_default_sink from xpra.sound.pulseaudio_util import get_pulse_server, get_pulse_id, set_source_mute if not has_pa(): log.error("pulseaudio not supported - sound disabled") return None pa_server = get_pulse_server() log( "start sound, remote pulseaudio server=%s, local pulseaudio server=%s", remote_pulseaudio_server, pa_server) #only worth comparing if we have a real server string #one that starts with {UUID}unix:/.. if pa_server and pa_server.startswith("{") and \ remote_pulseaudio_server and remote_pulseaudio_server==pa_server: log.error( "identical pulseaudio server, refusing to create a sound loop - sound disabled" ) return None pa_id = get_pulse_id() log("start sound, client id=%s, server id=%s", remote_pulseaudio_id, pa_id) if remote_pulseaudio_id and remote_pulseaudio_id == pa_id: log.error( "identical pulseaudio ID, refusing to create a sound loop - sound disabled" ) return None monitor_devices = get_pa_device_options(True, False) log("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices) == 0: log.error( "could not detect any pulseaudio monitor devices - sound forwarding is disabled" ) return None #default to first one: monitor_device, monitor_device_name = monitor_devices.items()[0] if len(monitor_devices) > 1: default_sink = get_default_sink() default_monitor = default_sink + ".monitor" global WARNED_MULTIPLE_DEVICES if not WARNED_MULTIPLE_DEVICES: WARNED_MULTIPLE_DEVICES = True log.warn("found more than one audio monitor device:") for k, v in monitor_devices.items(): log.warn(" * %s (\"%s\")", v, k) if default_monitor in monitor_devices: monitor_device = default_monitor monitor_device_name = monitor_devices.get(default_monitor) if not WARNED_MULTIPLE_DEVICES: log.warn("using monitor of default sink: %s", monitor_device_name) else: if not WARNED_MULTIPLE_DEVICES: log.warn("using the first device") #make sure it is not muted: set_source_mute(monitor_device, mute=False) sound_source = SoundSource("pulsesrc", {"device": monitor_device}, codec, volume, {}) log.info("starting sound capture using pulseaudio device: %s", monitor_device_name) return sound_source except: e = sys.exc_info()[1] log.error("error setting up sound: %s", e, exc_info=True) return None