def __init__(self, sink_type=None, sink_options={}, codecs=CODECS, codec_options={}, volume=1.0): if not sink_type: sink_type = DEFAULT_SINK assert sink_type in SINKS, "invalid sink: %s" % sink_type matching = [x for x in CODEC_ORDER if (x in codecs and x in CODECS)] log("SoundSink(..) found matching codecs %s", matching) assert len(matching) > 0, "no matching codecs between arguments %s and supported list %s" % (codecs, CODECS) codec = matching[0] decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type decoder_str = plugin_str(decoder, codec_options) pipeline_els = [] pipeline_els.append( "appsrc" + " name=src" + " emit-signals=0" + " block=0" + " is-live=0" + " stream-type=stream" + " format=%s" % GST_FORMAT_BUFFERS ) 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=%s" % QUEUE_MIN_TIME, "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 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.queue_state = "starting" 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 __init__(self, sink_type=None, sink_options={}, codecs=CODECS, codec_options={}, volume=1.0): if not sink_type: sink_type = DEFAULT_SINK assert sink_type in SINKS, "invalid sink: %s" % sink_type matching = [x for x in CODEC_ORDER if (x in codecs and x in CODECS)] log("SoundSink(..) found matching codecs %s", matching) assert len(matching)>0, "no matching codecs between arguments %s and supported list %s" % (codecs, CODECS) codec = matching[0] decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type decoder_str = plugin_str(decoder, codec_options) pipeline_els = [] pipeline_els.append("appsrc"+ " name=src"+ " emit-signals=0"+ " block=0"+ " is-live=0"+ " stream-type=stream"+ " format=%s" % GST_FORMAT_BUFFERS) 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=%s" % QUEUE_MIN_TIME, "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 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.queue_state = "starting" 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 __init__(self, sink_type=DEFAULT_SINK, options={}, codec=MP3, decoder_options={}): assert sink_type in SINKS, "invalid sink: %s" % sink_type decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type decoder_str = plugin_str(decoder, decoder_options) pipeline_els = [] pipeline_els.append("appsrc name=src") pipeline_els.append(parser) pipeline_els.append(decoder_str) if VOLUME: pipeline_els.append("volume name=volume") pipeline_els.append("audioconvert") pipeline_els.append("audioresample") if QUEUE: if QUEUE_TIME > 0: pipeline_els.append( "queue name=queue max-size-time=%s leaky=%s" % (QUEUE_TIME, QUEUE_LEAK)) else: pipeline_els.append("queue leaky=%s" % QUEUE_LEAK) pipeline_els.append(sink_type) self.setup_pipeline_and_bus(pipeline_els) self.volume = self.pipeline.get_by_name("volume") self.src = self.pipeline.get_by_name("src") self.src.set_property('emit-signals', True) self.src.set_property('stream-type', 'stream') self.src.set_property('block', False) self.src.set_property('format', 4) self.src.set_property('is-live', True) if QUEUE: self.queue = self.pipeline.get_by_name("queue") def overrun(*args): debug("sound sink queue overrun") def underrun(*args): debug("sound sink queue underrun") self.queue.connect("overrun", overrun) self.queue.connect("underrun", underrun) else: self.queue = None self.src.connect("need-data", self.need_data) self.src.connect("enough-data", self.on_enough_data)
def __init__(self, sink_type=DEFAULT_SINK, options={}, codec=MP3, decoder_options={}): assert sink_type in SINKS, "invalid sink: %s" % sink_type decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type decoder_str = plugin_str(decoder, decoder_options) pipeline_els = [] pipeline_els.append("appsrc"+ " name=src"+ " max-bytes=32768"+ " emit-signals=0"+ " block=0"+ " is-live=0"+ " stream-type=stream"+ " format=4") pipeline_els.append(parser) pipeline_els.append(decoder_str) pipeline_els.append("audioconvert") pipeline_els.append("audioresample") queue_el = ["queue", "name=queue", "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)) pipeline_els.append(sink_type) self.setup_pipeline_and_bus(pipeline_els) self.src = self.pipeline.get_by_name("src") self.queue = self.pipeline.get_by_name("queue") self.overruns = 0 self.queue_state = "starting" 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) if FAKE_OVERRUN>0: def fake_overrun(*args): self.emit("overrun", 500) gobject.timeout_add(FAKE_OVERRUN*1000, fake_overrun)
def __init__(self, sink_type=DEFAULT_SINK, options={}, codec=MP3, decoder_options={}): assert sink_type in SINKS, "invalid sink: %s" % sink_type decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.add_signals(self.__generic_signals__) self.sink_type = sink_type decoder_str = plugin_str(decoder, decoder_options) pipeline_els = [] pipeline_els.append("appsrc"+ " name=src"+ " max-bytes=32768"+ " emit-signals=0"+ " block=0"+ " is-live=0"+ " stream-type=stream"+ " format=4") pipeline_els.append(parser) pipeline_els.append(decoder_str) pipeline_els.append("audioconvert") pipeline_els.append("audioresample") queue_el = "queue" + \ " name=queue"+ \ " 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(queue_el) pipeline_els.append(sink_type) self.setup_pipeline_and_bus(pipeline_els) self.src = self.pipeline.get_by_name("src") self.queue = self.pipeline.get_by_name("queue") self.overruns = 0 self.queue_state = "starting" 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 __init__(self, sink_type=DEFAULT_SINK, options={}, codec=MP3, decoder_options={}): assert sink_type in SINKS, "invalid sink: %s" % sink_type decoder, parser = get_decoder_parser(codec) SoundPipeline.__init__(self, codec) self.sink_type = sink_type decoder_str = plugin_str(decoder, decoder_options) pipeline_els = [] pipeline_els.append("appsrc name=src") pipeline_els.append(parser) pipeline_els.append(decoder_str) if VOLUME: pipeline_els.append("volume name=volume") pipeline_els.append("audioconvert") pipeline_els.append("audioresample") if QUEUE: if QUEUE_TIME>0: pipeline_els.append("queue name=queue max-size-time=%s leaky=%s" % (QUEUE_TIME, QUEUE_LEAK)) else: pipeline_els.append("queue leaky=%s" % QUEUE_LEAK) pipeline_els.append(sink_type) self.setup_pipeline_and_bus(pipeline_els) self.volume = self.pipeline.get_by_name("volume") self.src = self.pipeline.get_by_name("src") self.src.set_property('emit-signals', True) self.src.set_property('stream-type', 'stream') self.src.set_property('block', False) self.src.set_property('format', 4) self.src.set_property('is-live', True) if QUEUE: self.queue = self.pipeline.get_by_name("queue") def overrun(*args): debug("sound sink queue overrun") def underrun(*args): debug("sound sink queue underrun") self.queue.connect("overrun", overrun) self.queue.connect("underrun", underrun) else: self.queue = None self.src.connect("need-data", self.need_data) self.src.connect("enough-data", self.on_enough_data)
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 __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)