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 __init__(self, src_type=None, src_options={}, codecs=get_codecs(), codec_options={}, volume=1.0): if not src_type: try: from xpra.sound.pulseaudio.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) except ImportError as e: log.warn("Warning: pulseaudio is not available!") log.warn(" %s", e) 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) self.queue = None self.caps = None self.volume = None self.sink = None self.src = None self.src_type = src_type self.buffer_latency = False self.jitter_queue = None self.file = None SoundPipeline.__init__(self, codec) src_options["name"] = "src" 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 get_encoder_default_options(encoder)) fmt_str = plugin_str(fmt, MUXER_DEFAULT_OPTIONS.get(fmt, {})) pipeline_els = [source_str] if SOURCE_QUEUE_TIME>0: queue_el = ["queue", "name=queue", "min-threshold-time=0", "max-size-buffers=0", "max-size-bytes=0", "max-size-time=%s" % (SOURCE_QUEUE_TIME*MS_TO_NS), "leaky=%s" % GST_QUEUE_LEAK_DOWNSTREAM] pipeline_els += [" ".join(queue_el)] 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] if not self.setup_pipeline_and_bus(pipeline_els): return self.volume = self.pipeline.get_by_name("volume") self.sink = self.pipeline.get_by_name("sink") if SOURCE_QUEUE_TIME>0: self.queue = self.pipeline.get_by_name("queue") if self.queue: try: self.queue.set_property("silent", True) except Exception as e: log("cannot make queue silent: %s", e) 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.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) self.src = self.pipeline.get_by_name("src") try: for x in ("actual-buffer-time", "actual-latency-time"): #don't comment this out, it is used to verify the attributes are present: gstlog("initial %s: %s", x, self.src.get_property(x)) self.buffer_latency = True except Exception as e: log.info("source %s does not support 'buffer-time' or 'latency-time':", self.src_type) log.info(" %s", e) else: #if the env vars have been set, try to honour the settings: global BUFFER_TIME, LATENCY_TIME if BUFFER_TIME>0: if BUFFER_TIME<LATENCY_TIME: log.warn("Warning: latency (%ims) must be lower than the buffer time (%ims)", LATENCY_TIME, BUFFER_TIME) else: log("latency tuning for %s, will try to set buffer-time=%i, latency-time=%i", src_type, BUFFER_TIME, LATENCY_TIME) def settime(attr, v): try: cval = self.src.get_property(attr) gstlog("default: %s=%i", attr, cval//1000) if v>=0: self.src.set_property(attr, v*1000) gstlog("overriding with: %s=%i", attr, v) except Exception as e: log.warn("source %s does not support '%s': %s", self.src_type, attr, e) settime("buffer-time", BUFFER_TIME) settime("latency-time", LATENCY_TIME) gen = generation.increase() if SAVE_TO_FILE is not None: parts = codec.split("+") if len(parts)>1: filename = SAVE_TO_FILE+str(gen)+"-"+parts[0]+".%s" % parts[1] else: filename = SAVE_TO_FILE+str(gen)+".%s" % codec self.file = open(filename, 'wb') log.info("saving %s stream to %s", codec, filename)
def main(): from xpra.platform import program_context with program_context("Xpra-Sound-Source"): import os.path if "-v" in sys.argv: log.enable_debug() sys.argv.remove("-v") if len(sys.argv) not in (2, 3): log.error("usage: %s filename [codec] [--encoder=rencode]", sys.argv[0]) return 1 filename = sys.argv[1] if filename=="-": from xpra.os_util import disable_stdout_buffering disable_stdout_buffering() elif os.path.exists(filename): log.error("file %s already exists", filename) return 1 codec = None codecs = get_codecs() if len(sys.argv)==3: codec = sys.argv[2] if codec not in codecs: log.error("invalid codec: %s, codecs supported: %s", codec, codecs) return 1 else: parts = filename.split(".") if len(parts)>1: extension = parts[-1] if extension.lower() in codecs: codec = extension.lower() log.info("guessed codec %s from file extension %s", codec, extension) if codec is None: codec = MP3 log.info("using default codec: %s", codec) #in case we're running against pulseaudio, #try to setup the env: try: from xpra.platform.paths import get_icon_filename f = get_icon_filename("xpra.png") from xpra.sound.pulseaudio.pulseaudio_util import add_audio_tagging_env add_audio_tagging_env(icon_path=f) except Exception as e: log.warn("failed to setup pulseaudio tagging: %s", e) from threading import Lock if filename=="-": f = sys.stdout else: f = open(filename, "wb") ss = SoundSource(codecs=[codec]) lock = Lock() def new_buffer(ss, data, metadata): log.info("new buffer: %s bytes (%s), metadata=%s", len(data), type(data), metadata) with lock: if f: f.write(data) f.flush() from xpra.gtk_common.gobject_compat import import_glib glib = import_glib() glib_mainloop = glib.MainLoop() ss.connect("new-buffer", new_buffer) ss.start() import signal def deadly_signal(sig, frame): log.warn("got deadly signal %s", SIGNAMES.get(sig, sig)) glib.idle_add(ss.stop) glib.idle_add(glib_mainloop.quit) def force_quit(sig, frame): sys.exit() signal.signal(signal.SIGINT, force_quit) signal.signal(signal.SIGTERM, force_quit) from xpra.gtk_common.gobject_compat import is_gtk3 if not is_gtk3(): signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) try: glib_mainloop.run() except Exception as e: log.error("main loop error: %s", e) ss.stop() f.flush() if f!=sys.stdout: log.info("wrote %s bytes to %s", f.tell(), filename) with lock: f.close() f = None return 0
def __init__(self, sink_type=None, sink_options={}, codecs=get_codecs(), codec_options={}, volume=1.0): if not sink_type: sink_type = DEFAULT_SINK if sink_type not in SINKS: raise InitExit(1, "invalid sink: %s" % sink_type) matching = [x for x in CODEC_ORDER if (x in codecs and x in get_codecs())] log("SoundSink(..) 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] decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type self.levels = deque(maxlen=100) decoder_str = plugin_str(decoder, codec_options) pipeline_els = [] appsrc_el = ["appsrc", "do-timestamp=1", "name=src", "emit-signals=0", "block=0", "is-live=0", "stream-type=stream", "format=%s" % GST_FORMAT_BUFFERS] pipeline_els.append(" ".join(appsrc_el)) pipeline_els.append(parser) pipeline_els.append(decoder_str) pipeline_els.append("audioconvert") pipeline_els.append("audioresample") pipeline_els.append("volume name=volume volume=%s" % volume) queue_el = ["queue", "name=queue", "min-threshold-time=0", "max-size-buffers=0", "max-size-bytes=0", "max-size-time=%s" % QUEUE_TIME, "leaky=%s" % QUEUE_LEAK] if QUEUE_SILENT: queue_el.append("silent=%s" % QUEUE_SILENT) pipeline_els.append(" ".join(queue_el)) sink_attributes = SINK_SHARED_DEFAULT_ATTRIBUTES.copy() from xpra.sound.gstreamer_util import gst_major_version, get_gst_version #anything older than this may cause problems (ie: centos 6.x) #because the attributes may not exist if get_gst_version()>=(0, 10, 36): sink_attributes.update(SINK_DEFAULT_ATTRIBUTES.get(gst_major_version, {}).get(sink_type, {})) sink_attributes.update(sink_options) sink_str = plugin_str(sink_type, sink_attributes) pipeline_els.append(sink_str) self.setup_pipeline_and_bus(pipeline_els) self.volume = self.pipeline.get_by_name("volume") self.src = self.pipeline.get_by_name("src") self.queue = self.pipeline.get_by_name("queue") self.overruns = 0 self.underruns = 0 self.overrun_events = deque(maxlen=100) self.underrun_events = deque(maxlen=100) self.queue_state = "starting" self.last_underrun = 0 self.last_overrun = 0 self.last_max_update = time.time() self.level_lock = Lock() if QUEUE_SILENT==0: self.queue.connect("overrun", self.queue_overrun) self.queue.connect("underrun", self.queue_underrun) self.queue.connect("running", self.queue_running) self.queue.connect("pushing", self.queue_pushing)
def main(): from xpra.platform import init, clean init("Sound-Record") try: from xpra.gtk_common.gobject_compat import import_glib glib = import_glib() args = sys.argv log.enable_debug() import os.path if len(args) not in (2, 3): print("usage: %s [-v|--verbose] filename [codec]" % sys.argv[0]) return 1 filename = args[1] if not os.path.exists(filename): print("file %s does not exist" % filename) return 2 codecs = get_codecs() if len(args)==3: codec = args[2] if codec not in codecs: print("invalid codec: %s" % codec) print("only supported: %s" % str(codecs.keys())) return 2 codecs = [codec] else: codec = None 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: print("assuming this is an mp3 file...") codec = MP3 codecs = [codec] log.enable_debug() with open(filename, "rb") as f: data = f.read() print("loaded %s bytes from %s" % (len(data), filename)) #force no leak since we push all the data at once global QUEUE_LEAK, QUEUE_SILENT QUEUE_LEAK = GST_QUEUE_NO_LEAK QUEUE_SILENT = 1 ss = SoundSink(codecs=codecs) def eos(*args): print("eos") glib.idle_add(glib_mainloop.quit) ss.connect("eos", eos) ss.start() glib_mainloop = glib.MainLoop() import signal def deadly_signal(*args): glib.idle_add(ss.stop) glib.idle_add(glib_mainloop.quit) def force_quit(sig, frame): sys.exit() signal.signal(signal.SIGINT, force_quit) signal.signal(signal.SIGTERM, force_quit) from xpra.gtk_common.gobject_compat import is_gtk3 if not is_gtk3(): signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) def check_for_end(*args): qtime = ss.queue.get_property("current-level-time")//MS_TO_NS if qtime<=0: log.info("underrun (end of stream)") thread.start_new_thread(ss.stop, ()) glib.timeout_add(500, glib_mainloop.quit) return False return True glib.timeout_add(1000, check_for_end) glib.idle_add(ss.add_data, data) glib_mainloop.run() return 0 finally: clean()
def main(): from xpra.platform import init, clean init("Xpra-Sound-Source") try: import os.path if "-v" in sys.argv: log.enable_debug() sys.argv.remove("-v") if len(sys.argv) not in (2, 3): log.error("usage: %s filename [codec] [--encoder=rencode]", sys.argv[0]) return 1 filename = sys.argv[1] if filename=="-": from xpra.os_util import disable_stdout_buffering disable_stdout_buffering() elif os.path.exists(filename): log.error("file %s already exists", filename) return 1 codec = None codecs = get_codecs() if len(sys.argv)==3: codec = sys.argv[2] if codec not in codecs: log.error("invalid codec: %s, codecs supported: %s", codec, codecs) return 1 else: parts = filename.split(".") if len(parts)>1: extension = parts[-1] if extension.lower() in codecs: codec = extension.lower() log.info("guessed codec %s from file extension %s", codec, extension) if codec is None: codec = MP3 log.info("using default codec: %s", codec) #in case we're running against pulseaudio, #try to setup the env: try: from xpra.platform.paths import get_icon_filename f = get_icon_filename("xpra.png") from xpra.sound.pulseaudio_util import add_audio_tagging_env add_audio_tagging_env(icon_path=f) except Exception as e: log.warn("failed to setup pulseaudio tagging: %s", e) from threading import Lock if filename=="-": f = sys.stdout else: f = open(filename, "wb") ss = SoundSource(codecs=[codec]) lock = Lock() def new_buffer(ss, data, metadata): log.info("new buffer: %s bytes (%s), metadata=%s", len(data), type(data), metadata) with lock: if f: f.write(data) f.flush() from xpra.gtk_common.gobject_compat import import_glib glib = import_glib() glib_mainloop = glib.MainLoop() ss.connect("new-buffer", new_buffer) ss.start() import signal def deadly_signal(sig, frame): log.warn("got deadly signal %s", SIGNAMES.get(sig, sig)) glib.idle_add(ss.stop) glib.idle_add(glib_mainloop.quit) def force_quit(sig, frame): sys.exit() signal.signal(signal.SIGINT, force_quit) signal.signal(signal.SIGTERM, force_quit) from xpra.gtk_common.gobject_compat import is_gtk3 if not is_gtk3(): signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) try: glib_mainloop.run() except Exception as e: log.error("main loop error: %s", e) ss.stop() f.flush() if f!=sys.stdout: log.info("wrote %s bytes to %s", f.tell(), filename) with lock: f.close() f = None return 0 finally: clean()
def __init__(self, src_type=None, src_options={}, codecs=get_codecs(), codec_options={}, volume=1.0): if not src_type: try: from xpra.sound.pulseaudio.pulseaudio_util import get_pa_device_options monitor_devices = get_pa_device_options(True, False) log.info("found pulseaudio monitor devices: %s", monitor_devices) except ImportError as e: log.warn("Warning: pulseaudio is not available!") log.warn(" %s", e) 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) self.queue = None self.caps = None self.volume = None self.sink = None self.src = None self.src_type = src_type self.buffer_latency = False self.jitter_queue = None self.file = None SoundPipeline.__init__(self, codec) src_options["name"] = "src" 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 get_encoder_default_options(encoder)) fmt_str = plugin_str(fmt, MUXER_DEFAULT_OPTIONS.get(fmt, {})) pipeline_els = [source_str] if SOURCE_QUEUE_TIME > 0: queue_el = [ "queue", "name=queue", "min-threshold-time=0", "max-size-buffers=0", "max-size-bytes=0", "max-size-time=%s" % (SOURCE_QUEUE_TIME * MS_TO_NS), "leaky=%s" % GST_QUEUE_LEAK_DOWNSTREAM ] pipeline_els += [" ".join(queue_el)] 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] if not self.setup_pipeline_and_bus(pipeline_els): return self.volume = self.pipeline.get_by_name("volume") self.sink = self.pipeline.get_by_name("sink") if SOURCE_QUEUE_TIME > 0: self.queue = self.pipeline.get_by_name("queue") if self.queue: try: self.queue.set_property("silent", True) except Exception as e: log("cannot make queue silent: %s", e) 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.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) self.src = self.pipeline.get_by_name("src") try: for x in ("actual-buffer-time", "actual-latency-time"): #don't comment this out, it is used to verify the attributes are present: gstlog("initial %s: %s", x, self.src.get_property(x)) self.buffer_latency = True except Exception as e: log.info( "source %s does not support 'buffer-time' or 'latency-time':", self.src_type) log.info(" %s", e) else: #if the env vars have been set, try to honour the settings: global BUFFER_TIME, LATENCY_TIME if BUFFER_TIME > 0: if BUFFER_TIME < LATENCY_TIME: log.warn( "Warning: latency (%ims) must be lower than the buffer time (%ims)", LATENCY_TIME, BUFFER_TIME) else: log( "latency tuning for %s, will try to set buffer-time=%i, latency-time=%i", src_type, BUFFER_TIME, LATENCY_TIME) def settime(attr, v): try: cval = self.src.get_property(attr) gstlog("default: %s=%i", attr, cval // 1000) if v >= 0: self.src.set_property(attr, v * 1000) gstlog("overriding with: %s=%i", attr, v) except Exception as e: log.warn("source %s does not support '%s': %s", self.src_type, attr, e) settime("buffer-time", BUFFER_TIME) settime("latency-time", LATENCY_TIME) gen = generation.increase() if SAVE_TO_FILE is not None: parts = codec.split("+") if len(parts) > 1: filename = SAVE_TO_FILE + str( gen) + "-" + parts[0] + ".%s" % parts[1] else: filename = SAVE_TO_FILE + str(gen) + ".%s" % codec self.file = open(filename, 'wb') log.info("saving %s stream to %s", codec, filename)
def __init__(self, sink_type=None, sink_options={}, codecs=get_codecs(), codec_options={}, volume=1.0): if not sink_type: sink_type = DEFAULT_SINK if sink_type not in SINKS: raise InitExit(1, "invalid sink: %s" % sink_type) matching = [x for x in CODEC_ORDER if (x in codecs and x in get_codecs())] log("SoundSink(..) 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] decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type self.levels = deque(maxlen=100) self.volume = None self.src = None self.queue = None self.normal_volume = volume self.target_volume = volume self.volume_timer = 0 self.overruns = 0 self.underruns = 0 self.overrun_events = deque(maxlen=100) self.queue_state = "starting" self.last_data = None self.last_underrun = 0 self.last_overrun = 0 self.last_max_update = time.time() self.level_lock = Lock() decoder_str = plugin_str(decoder, codec_options) pipeline_els = [] appsrc_el = ["appsrc", "do-timestamp=1", "name=src", "emit-signals=0", "block=0", "is-live=0", "stream-type=%s" % STREAM_TYPE, "format=%s" % BUFFER_FORMAT] pipeline_els.append(" ".join(appsrc_el)) pipeline_els.append(parser) pipeline_els.append(decoder_str) pipeline_els.append("audioconvert") pipeline_els.append("audioresample") pipeline_els.append("volume name=volume volume=0") if QUEUE_TIME>0: pipeline_els.append(" ".join(["queue", "name=queue", "min-threshold-time=0", "max-size-buffers=0", "max-size-bytes=0", "max-size-time=%s" % QUEUE_TIME, "leaky=%s" % QUEUE_LEAK])) sink_attributes = SINK_SHARED_DEFAULT_ATTRIBUTES.copy() from xpra.sound.gstreamer_util import gst_major_version, get_gst_version #anything older than this may cause problems (ie: centos 6.x) #because the attributes may not exist if get_gst_version()>=(0, 10, 36): sink_attributes.update(SINK_DEFAULT_ATTRIBUTES.get(gst_major_version, {}).get(sink_type, {})) get_options_cb = DEFAULT_SINK_PLUGIN_OPTIONS.get(sink_type.replace("sink", "")) if get_options_cb: v = get_options_cb() log("%s()=%s", get_options_cb, v) sink_attributes.update(v) sink_attributes.update(sink_options) sink_str = plugin_str(sink_type, sink_attributes) pipeline_els.append(sink_str) if not self.setup_pipeline_and_bus(pipeline_els): return self.volume = self.pipeline.get_by_name("volume") self.src = self.pipeline.get_by_name("src") self.queue = self.pipeline.get_by_name("queue") if get_gst_version()<(1, ): self.add_data = self.add_data0 else: self.add_data = self.add_data1 if self.queue: if not QUEUE_SILENT: if get_gst_version()<(1, ): self.queue.connect("overrun", self.queue_overrun0) self.queue.connect("underrun", self.queue_underrun0) self.queue.connect("running", self.queue_running0) self.queue.connect("pushing", self.queue_pushing0) else: self.queue.connect("overrun", self.queue_overrun1) self.queue.connect("underrun", self.queue_underrun1) self.queue.connect("running", self.queue_running1) self.queue.connect("pushing", self.queue_pushing1) else: #older versions may not have the "silent" attribute, #in which case we will emit the signals for nothing try: self.queue.set_property("silent", False) except Exception as e: log("cannot silence the queue %s: %s", self.queue, e)