def __init__(self, src_type=None, src_options={}, codecs=get_codecs(), codec_options={}, volume=1.0): if not src_type: from xpra.sound.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices)==0: log.warn("could not detect any pulseaudio monitor devices") log.warn(" a test source will be used instead") src_type = "audiotestsrc" default_src_options = {"wave":2, "freq":100, "volume":0.4} else: monitor_device = monitor_devices.items()[0][0] log.info("using pulseaudio source device:") log.info(" '%s'", monitor_device) src_type = "pulsesrc" default_src_options = {"device" : monitor_device} src_options = default_src_options if src_type not in get_source_plugins(): raise InitExit(1, "invalid source plugin '%s', valid options are: %s" % (src_type, ",".join(get_source_plugins()))) matching = [x for x in CODEC_ORDER if (x in codecs and x in get_codecs())] log("SoundSource(..) found matching codecs %s", matching) if not matching: raise InitExit(1, "no matching codecs between arguments '%s' and supported list '%s'" % (csv(codecs), csv(get_codecs().keys()))) codec = matching[0] encoder, fmt = get_encoder_formatter(codec) SoundPipeline.__init__(self, codec) self.src_type = src_type source_str = plugin_str(src_type, src_options) #FIXME: this is ugly and relies on the fact that we don't pass any codec options to work! encoder_str = plugin_str(encoder, codec_options or ENCODER_DEFAULT_OPTIONS.get(encoder, {})) fmt_str = plugin_str(fmt, MUXER_DEFAULT_OPTIONS.get(fmt, {})) pipeline_els = [source_str] if encoder in ENCODER_NEEDS_AUDIOCONVERT or src_type in SOURCE_NEEDS_AUDIOCONVERT: pipeline_els += ["audioconvert"] pipeline_els.append("volume name=volume volume=%s" % volume) pipeline_els += [encoder_str, fmt_str, APPSINK] self.setup_pipeline_and_bus(pipeline_els) self.volume = self.pipeline.get_by_name("volume") self.sink = self.pipeline.get_by_name("sink") try: if get_gst_version()<(1,0): self.sink.set_property("enable-last-buffer", False) else: self.sink.set_property("enable-last-sample", False) except Exception as e: log("failed to disable last buffer: %s", e) self.caps = None self.skipped_caps = set() if JITTER>0: self.jitter_queue = Queue() try: #Gst 1.0: self.sink.connect("new-sample", self.on_new_sample) self.sink.connect("new-preroll", self.on_new_preroll1) except: #Gst 0.10: self.sink.connect("new-buffer", self.on_new_buffer) self.sink.connect("new-preroll", self.on_new_preroll0)
def start_sending_sound(codec, 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 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.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, 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() soundlog("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() soundlog("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) soundlog("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_devices.items()[0][0] if len(monitor_devices)>1: default_sink = get_default_sink() default_monitor = default_sink+".monitor" log.warn("found more than one monitor device: %s", monitor_devices) if default_monitor in monitor_devices: log.warn("using monitor of default sink: %s", monitor_devices.get(default_monitor)) monitor_device = default_monitor else: log.warn("using first device: %s", monitor_devices.items()[0][1]) #make sure it is not muted: set_source_mute(monitor_device, mute=False) 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 get_pulse_defaults(remote): """ choose the device to use """ 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.warn("pulseaudio is not available!") 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") log.info("using Pulseaudio device '%s'", monitor_device_name) #make sure it is not muted: set_source_mute(monitor_device, mute=False) return {"device": monitor_device}
def get_pulse_defaults(remote): """ choose the device to use """ 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.warn("pulseaudio is not available!") 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") log.info("using Pulseaudio device '%s'", monitor_device_name) #make sure it is not muted: set_source_mute(monitor_device, mute=False) return {"device" : monitor_device}
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 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 main(): import os.path if len(sys.argv) not in (2, 3): print("usage: %s filename [codec]" % sys.argv[0]) sys.exit(1) return filename = sys.argv[1] if os.path.exists(filename): print("file %s already exists" % filename) sys.exit(2) return if len(sys.argv) == 3: codec = sys.argv[2] if codec not in CODECS: print("invalid codec: %s, codecs supported: %s" % (codec, CODECS)) sys.exit(2) return else: codec = MP3 print("using default codec: %s" % codec) from threading import Lock import logging logging.basicConfig(format="%(asctime)s %(message)s") logging.root.setLevel(logging.INFO) f = open(filename, "wb") from xpra.sound.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices) == 0: log.warn( "could not detect any pulseaudio monitor devices - will use a test source" ) ss = SoundSource("audiotestsrc", src_options={ "wave": 2, "freq": 100, "volume": 0.4 }, codec=codec) else: monitor_device = monitor_devices.items()[0][0] log.info("using pulseaudio source device: %s", monitor_device) ss = SoundSource("pulsesrc", {"device": monitor_device}, codec, {}) lock = Lock() def new_buffer(ss, data, metadata): log.info("new buffer: %s bytes, metadata=%s" % (len(data), metadata)) try: lock.acquire() if f: f.write(data) finally: lock.release() ss.connect("new-buffer", new_buffer) ss.start() import signal def deadly_signal(*args): gobject.idle_add(gtk.main_quit) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) import gtk gtk.main() f.flush() log.info("wrote %s bytes to %s", f.tell(), filename) try: lock.acquire() f.close() f = None finally: lock.release()
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
def main(): from xpra.platform import init, clean init("Sound-Play") try: import os.path if len(sys.argv) not in (2, 3): print("usage: %s filename [codec]" % sys.argv[0]) return 1 filename = sys.argv[1] if os.path.exists(filename): print("file %s already exists" % filename) return 2 codec = None if len(sys.argv)==3: codec = sys.argv[2] if codec not in CODECS: print("invalid codec: %s, codecs supported: %s" % (codec, CODECS)) return 2 else: parts = filename.split(".") if len(parts)>1: extension = parts[-1] if extension.lower() in CODECS: codec = extension.lower() print("guessed codec %s from file extension %s" % (codec, extension)) if codec is None: codec = MP3 print("using default codec: %s" % codec) log.enable_debug() from threading import Lock f = open(filename, "wb") from xpra.sound.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices)==0: log.warn("could not detect any pulseaudio monitor devices - will use a test source") ss = SoundSource("audiotestsrc", src_options={"wave":2, "freq":100, "volume":0.4}, codec=codec) else: monitor_device = monitor_devices.items()[0][0] log.info("using pulseaudio source device: %s", monitor_device) ss = SoundSource("pulsesrc", {"device" : monitor_device}, codec) lock = Lock() def new_buffer(ss, data, metadata): log.info("new buffer: %s bytes, metadata=%s" % (len(data), metadata)) try: lock.acquire() if f: f.write(data) finally: lock.release() ss.connect("new-buffer", new_buffer) ss.start() gobject_mainloop = gobject.MainLoop() gobject.threads_init() import signal def deadly_signal(*args): gobject.idle_add(gobject_mainloop.quit) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) gobject_mainloop.run() f.flush() log.info("wrote %s bytes to %s", f.tell(), filename) try: lock.acquire() f.close() f = None finally: lock.release() return 0 finally: clean()
def main(): import os.path if len(sys.argv) not in (2, 3): print("usage: %s filename [codec]" % sys.argv[0]) sys.exit(1) return filename = sys.argv[1] if os.path.exists(filename): print("file %s already exists" % filename) sys.exit(2) return if len(sys.argv)==3: codec = sys.argv[2] if codec not in CODECS: print("invalid codec: %s, codecs supported: %s" % (codec, CODECS)) sys.exit(2) return else: codec = MP3 print("using default codec: %s" % codec) from threading import Lock import logging logging.basicConfig(format="%(asctime)s %(message)s") logging.root.setLevel(logging.INFO) f = open(filename, "wb") from xpra.sound.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices)==0: log.warn("could not detect any pulseaudio monitor devices - will use a test source") ss = SoundSource("audiotestsrc", src_options={"wave":2, "freq":100, "volume":0.4}, codec=codec) else: monitor_device = monitor_devices.items()[0][0] log.info("using pulseaudio source device: %s", monitor_device) ss = SoundSource("pulsesrc", {"device" : monitor_device}, codec, {}) lock = Lock() def new_buffer(ss, data, metadata): log.info("new buffer: %s bytes, metadata=%s" % (len(data), metadata)) try: lock.acquire() if f: f.write(data) finally: lock.release() ss.connect("new-buffer", new_buffer) ss.start() import signal def deadly_signal(*args): gobject.idle_add(gtk.main_quit) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) import gtk gtk.main() f.flush() log.info("wrote %s bytes to %s", f.tell(), filename) try: lock.acquire() f.close() f = None finally: lock.release()
def __init__(self, src_type=None, src_options={}, codecs=CODECS, codec_options={}, volume=1.0): if not src_type: from xpra.sound.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices)==0: log.warn("could not detect any pulseaudio monitor devices - will use a test source") src_type = "audiotestsrc" default_src_options = {"wave":2, "freq":100, "volume":0.4} else: monitor_device = monitor_devices.items()[0][0] log.info("using pulseaudio source device: %s", monitor_device) src_type = "pulsesrc" default_src_options = {"device" : monitor_device} src_options = default_src_options src_options.update(src_options) assert src_type in get_source_plugins(), "invalid source plugin '%s'" % src_type matching = [x for x in CODEC_ORDER if (x in codecs and x in CODECS)] log("SoundSource(..) found matching codecs %s", matching) assert len(matching)>0, "no matching codecs between arguments %s and supported list %s" % (codecs, CODECS) codec = matching[0] encoder, fmt = get_encoder_formatter(codec) SoundPipeline.__init__(self, codec) self.src_type = src_type source_str = plugin_str(src_type, src_options) encoder_str = plugin_str(encoder, codec_options) fmt_str = plugin_str(fmt, MUXER_DEFAULT_OPTIONS.get(fmt, {})) pipeline_els = [source_str] if AUDIOCONVERT: pipeline_els += ["audioconvert"] if AUDIORESAMPLE: pipeline_els += [ "audioresample", "audio/x-raw-int,rate=44100,channels=2"] pipeline_els.append("volume name=volume volume=%s" % volume) if QUEUE_TIME>0: queue_el = ["queue", "name=queue", "max-size-buffers=0", "max-size-bytes=0", "max-size-time=%s" % QUEUE_TIME, "leaky=%s" % QUEUE_LEAK] pipeline_els.append(" ".join(queue_el)) pipeline_els += [encoder_str, fmt_str, "appsink name=sink"] self.setup_pipeline_and_bus(pipeline_els) self.volume = self.pipeline.get_by_name("volume") self.sink = self.pipeline.get_by_name("sink") self.sink.set_property("emit-signals", True) self.sink.set_property("max-buffers", 10) #0? self.sink.set_property("drop", False) self.sink.set_property("sync", True) #False? self.sink.set_property("qos", False) try: #Gst 1.0: self.sink.connect("new-sample", self.on_new_sample) self.sink.connect("new-preroll", self.on_new_preroll1) except: #Gst 0.10: self.sink.connect("new-buffer", self.on_new_buffer) self.sink.connect("new-preroll", self.on_new_preroll0)
def get_pulse_defaults(want_monitor_device, remote): """ choose the device to use """ 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.warn("pulseaudio is not available!") 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("Error: sound is disabled to prevent a sound loop") log.error(" identical Pulseaudio server '%s'", pa_server) 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("Error: sound is disabled to prevent a sound loop") log.error(" identical Pulseaudio ID '%s'", pa_id) return None device_type_str = ["input", "monitor"][want_monitor_device] devices = get_pa_device_options(want_monitor_device, not want_monitor_device) log("found pulseaudio %s devices: %s", device_type_str, devices) if len(devices)==0: log.error("Error: sound forwarding is disabled") log.error(" could not detect any Pulseaudio %s devices", device_type_str) return None if len(devices)>1 and INPUT_DEVICE_NAME: devices = dict((k,v) for k,v in devices.items() if k.find(INPUT_DEVICE_NAME)>=0 or v.find(INPUT_DEVICE_NAME)>0) if len(devices)==0: log.warn("Warning: Pulseaudio %s device name filter '%s'", device_type_str, INPUT_DEVICE_NAME) log.warn(" did not match any devices") return None elif len(devices)>1: log.warn("Warning: Pulseaudio %s device name filter '%s'", device_type_str, INPUT_DEVICE_NAME) log.warn(" matched %i devices", len(devices)) #default to first one: device, device_name = devices.items()[0] if len(devices)>1 and want_monitor_device: default_sink = get_default_sink() default_monitor = default_sink+".monitor" global WARNED_MULTIPLE_DEVICES if not WARNED_MULTIPLE_DEVICES: WARNED_MULTIPLE_DEVICES = True if not INPUT_DEVICE_NAME: #warned already log.warn("Warning: found more than one audio monitor device:") for k,v in devices.items(): log.warn(" * %s", v) log.warn(" %s", k) if not INPUT_DEVICE_NAME: #used already! log.warn(" use the environment variable XPRA_INPUT_DEVICE_NAME to select a specific one") if default_monitor in devices: device = default_monitor device_name = devices.get(default_monitor) if not WARNED_MULTIPLE_DEVICES: log.warn("using monitor of default sink: %s", device_name) else: if not WARNED_MULTIPLE_DEVICES: log.warn("using the first device") log.info("using pulseaudio device:") log.info(" '%s'", device_name) #make sure it is not muted: set_source_mute(device, mute=False) return {"device" : device}
def __init__(self, src_type=None, src_options={}, codecs=CODECS, codec_options={}, volume=1.0): if not src_type: from xpra.sound.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) if len(monitor_devices) == 0: log.warn( "could not detect any pulseaudio monitor devices - will use a test source" ) src_type = "audiotestsrc" default_src_options = {"wave": 2, "freq": 100, "volume": 0.4} else: monitor_device = monitor_devices.items()[0][0] log.info("using pulseaudio source device: %s", monitor_device) src_type = "pulsesrc" default_src_options = {"device": monitor_device} src_options = default_src_options src_options.update(src_options) assert src_type in get_source_plugins( ), "invalid source plugin '%s'" % src_type matching = [x for x in CODEC_ORDER if (x in codecs and x in CODECS)] log("SoundSource(..) found matching codecs %s", matching) assert len( matching ) > 0, "no matching codecs between arguments %s and supported list %s" % ( codecs, CODECS) codec = matching[0] encoder, fmt = get_encoder_formatter(codec) SoundPipeline.__init__(self, codec) self.src_type = src_type source_str = plugin_str(src_type, src_options) encoder_str = plugin_str(encoder, codec_options) fmt_str = plugin_str(fmt, MUXER_DEFAULT_OPTIONS.get(fmt, {})) pipeline_els = [source_str] if AUDIOCONVERT: pipeline_els += ["audioconvert"] if AUDIORESAMPLE: pipeline_els += [ "audioresample", "audio/x-raw-int,rate=44100,channels=2" ] pipeline_els.append("volume name=volume volume=%s" % volume) if QUEUE_TIME > 0: queue_el = [ "queue", "name=queue", "max-size-buffers=0", "max-size-bytes=0", "max-size-time=%s" % QUEUE_TIME, "leaky=%s" % QUEUE_LEAK ] pipeline_els.append(" ".join(queue_el)) pipeline_els += [encoder_str, fmt_str, "appsink name=sink"] self.setup_pipeline_and_bus(pipeline_els) self.volume = self.pipeline.get_by_name("volume") self.sink = self.pipeline.get_by_name("sink") self.sink.set_property("emit-signals", True) self.sink.set_property("max-buffers", 10) #0? self.sink.set_property("drop", False) self.sink.set_property("sync", True) #False? self.sink.set_property("qos", False) try: #Gst 1.0: self.sink.connect("new-sample", self.on_new_sample) self.sink.connect("new-preroll", self.on_new_preroll1) except: #Gst 0.10: self.sink.connect("new-buffer", self.on_new_buffer) self.sink.connect("new-preroll", self.on_new_preroll0)
def get_pulse_defaults(want_monitor_device, remote): """ choose the device to use """ 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.warn("pulseaudio is not available!") 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("Error: sound is disabled to prevent a sound loop") log.error(" identical Pulseaudio server '%s'", pa_server) 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("Error: sound is disabled to prevent a sound loop") log.error(" identical Pulseaudio ID '%s'", pa_id) return None device_type_str = ["input", "monitor"][want_monitor_device] devices = get_pa_device_options(want_monitor_device, not want_monitor_device) log("found pulseaudio %s devices: %s", device_type_str, devices) if len(devices) == 0: log.error("Error: sound forwarding is disabled") log.error(" could not detect any Pulseaudio %s devices", device_type_str) return None if len(devices) > 1 and INPUT_DEVICE_NAME: devices = dict( (k, v) for k, v in devices.items() if k.find(INPUT_DEVICE_NAME) >= 0 or v.find(INPUT_DEVICE_NAME) > 0) if len(devices) == 0: log.warn("Warning: Pulseaudio %s device name filter '%s'", device_type_str, INPUT_DEVICE_NAME) log.warn(" did not match any devices") return None elif len(devices) > 1: log.warn("Warning: Pulseaudio %s device name filter '%s'", device_type_str, INPUT_DEVICE_NAME) log.warn(" matched %i devices", len(devices)) #default to first one: device, device_name = devices.items()[0] if len(devices) > 1 and want_monitor_device: default_sink = get_default_sink() default_monitor = default_sink + ".monitor" global WARNED_MULTIPLE_DEVICES if not WARNED_MULTIPLE_DEVICES: WARNED_MULTIPLE_DEVICES = True if not INPUT_DEVICE_NAME: #warned already log.warn("Warning: found more than one audio monitor device:") for k, v in devices.items(): log.warn(" * %s", v) log.warn(" %s", k) if not INPUT_DEVICE_NAME: #used already! log.warn( " use the environment variable XPRA_INPUT_DEVICE_NAME to select a specific one" ) if default_monitor in devices: device = default_monitor device_name = devices.get(default_monitor) if not WARNED_MULTIPLE_DEVICES: log.warn("using monitor of default sink: %s", device_name) else: if not WARNED_MULTIPLE_DEVICES: log.warn("using the first device") log.info("using pulseaudio device:") log.info(" '%s'", device_name) #make sure it is not muted: set_source_mute(device, mute=False) return {"device": device}