Exemplo n.º 1
0
    def __init__(self,
                 sink_type=DEFAULT_SINK,
                 options={},
                 codec=MP3,
                 decoder_options={}):
        assert sink_type in SINKS, "invalid sink: %s" % sink_type
        decoders = get_decoders(codec)
        assert len(decoders) > 0, "no decoders found for %s" % codec
        SoundPipeline.__init__(self, codec)
        self.sink_type = sink_type
        decoder = decoders[0]
        decoder_str = plugin_str(decoder, decoder_options)
        pipeline_els = []
        pipeline_els.append("appsrc name=src")
        pipeline_els.append("mp3parse")
        pipeline_els.append(decoder_str)
        pipeline_els.append("volume name=volume")
        pipeline_els.append("audioconvert")
        pipeline_els.append("audioresample")
        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_TIME > 0:
            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)
Exemplo n.º 2
0
 def __init__(self, sink_type=DEFAULT_SINK, options={}, codec=MP3, decoder_options={}):
     assert sink_type in SINKS, "invalid sink: %s" % sink_type
     decoders = get_decoders(codec)
     assert len(decoders)>0, "no decoders found for %s" % codec
     SoundPipeline.__init__(self, codec)
     self.sink_type = sink_type
     decoder = decoders[0]
     decoder_str = plugin_str(decoder, decoder_options)
     pipeline_els = []
     pipeline_els.append("appsrc name=src")
     pipeline_els.append("mp3parse")
     pipeline_els.append(decoder_str)
     pipeline_els.append("volume name=volume")
     pipeline_els.append("audioconvert")
     pipeline_els.append("audioresample")
     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_TIME>0:
         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)
Exemplo n.º 3
0
 def __init__(self,
              sink_type=None,
              sink_options={},
              codecs=get_decoders(),
              codec_options={},
              volume=1.0):
     if not sink_type:
         sink_type = get_default_sink()
     if sink_type not in get_sink_plugins():
         raise InitExit(1, "invalid sink: %s" % sink_type)
     matching = [
         x for x in CODEC_ORDER if (x in codecs and x in get_decoders())
     ]
     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_decoders().keys())))
     codec = matching[0]
     decoder, parser, stream_compressor = get_decoder_elements(codec)
     SoundPipeline.__init__(self, codec)
     self.container_format = (parser
                              or "").replace("demux",
                                             "").replace("depay", "")
     self.sink_type = sink_type
     self.stream_compressor = stream_compressor
     log("container format=%s, stream_compressor=%s, sink type=%s",
         self.container_format, self.stream_compressor, self.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.refill = True
     self.last_max_update = monotonic_time()
     self.last_min_update = monotonic_time()
     self.level_lock = Lock()
     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))
     if parser:
         pipeline_els.append(parser)
     if decoder:
         decoder_str = plugin_str(decoder, codec_options)
         pipeline_els.append(decoder_str)
     pipeline_els.append("audioconvert")
     pipeline_els.append("audioresample")
     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
         ]))
     pipeline_els.append("volume name=volume volume=0")
     sink_attributes = SINK_SHARED_DEFAULT_ATTRIBUTES.copy()
     #anything older than this may cause problems (ie: centos 6.x)
     #because the attributes may not exist
     sink_attributes.update(SINK_DEFAULT_ATTRIBUTES.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 self.queue:
         if QUEUE_SILENT:
             self.queue.set_property("silent", False)
         else:
             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)
Exemplo n.º 4
0
def main():
    from xpra.platform import program_context
    with program_context("Sound-Record"):
        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
        decoders = get_decoders()
        if len(args) == 3:
            codec = args[2]
            if codec not in decoders:
                print("invalid codec: %s" % codec)
                print("only supported: %s" % str(decoders.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 = True
        ss = SoundSink(codecs=codecs)

        def eos(*args):
            print("eos%s" % (args, ))
            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)

        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
Exemplo n.º 5
0
 def __init__(self, sink_type=None, sink_options={}, codecs=get_decoders(), codec_options={}, volume=1.0):
     if not sink_type:
         sink_type = get_default_sink()
     if sink_type not in get_sink_plugins():
         raise InitExit(1, "invalid sink: %s" % sink_type)
     matching = [x for x in CODEC_ORDER if (x in codecs and x in get_decoders())]
     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_decoders().keys())))
     codec = matching[0]
     decoder, parser, self.stream_compressor = get_decoder_elements(codec)
     SoundPipeline.__init__(self, codec)
     self.container_format = (parser or "").replace("demux", "").replace("depay", "")
     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.last_min_update = time.time()
     self.level_lock = Lock()
     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))
     if parser:
         pipeline_els.append(parser)
     if decoder:
         decoder_str = plugin_str(decoder, codec_options)
         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()
     #anything older than this may cause problems (ie: centos 6.x)
     #because the attributes may not exist
     sink_attributes.update(SINK_DEFAULT_ATTRIBUTES.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 self.queue:
         if QUEUE_SILENT:
             self.queue.set_property("silent", False)
         else:
             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)
Exemplo n.º 6
0
def main():
    from xpra.platform import program_context
    with program_context("Sound-Record"):
        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
        decoders = get_decoders()
        if len(args)==3:
            codec = args[2]
            if codec not in decoders:
                print("invalid codec: %s" % codec)
                print("only supported: %s" % str(decoders.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 = True
        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