Exemple #1
0
 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)
Exemple #2
0
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
Exemple #3
0
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}
Exemple #4
0
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}
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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()
Exemple #8
0
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
Exemple #9
0
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()
Exemple #10
0
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()
Exemple #11
0
 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)
Exemple #12
0
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}
Exemple #13
0
 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)
Exemple #14
0
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}