def sound_data(self, codec, data, metadata, packet_metadata=()): log("sound_data(%s, %s, %s, %s) sound sink=%s", codec, len(data or []), metadata, packet_metadata, self.sound_sink) if self.is_closed(): return if self.sound_sink is not None and codec != self.sound_sink.codec: log.info("sound codec changed from %s to %s", self.sound_sink.codec, codec) self.sound_sink.cleanup() self.sound_sink = None if metadata.get("end-of-stream"): log("client sent end-of-stream, closing sound pipeline") self.stop_receiving_sound() return if not self.sound_sink: if not self.audio_loop_check("microphone"): #make a fake object so we don't fire the audio loop check warning repeatedly from xpra.util import AdHocStruct self.sound_sink = AdHocStruct() self.sound_sink.codec = codec def noop(*_args): pass self.sound_sink.add_data = noop self.sound_sink.cleanup = noop return try: def sound_sink_error(*args): log("sound_sink_error%s", args) log.warn("stopping sound input because of error") self.stop_receiving_sound() from xpra.sound.wrapper import start_receiving_sound ss = start_receiving_sound(codec) if not ss: return self.sound_sink = ss log("sound_data(..) created sound sink: %s", self.sound_sink) ss.connect("error", sound_sink_error) ss.start() log("sound_data(..) sound sink started") except Exception: log.error("failed to setup sound", exc_info=True) return if packet_metadata: if not self.sound_properties.boolget("bundle-metadata"): for x in packet_metadata: self.sound_sink.add_data(x) packet_metadata = () self.sound_sink.add_data(data, metadata, packet_metadata)
def sound_data(self, codec, data, metadata, packet_metadata=()): log("sound_data(%s, %s, %s, %s) sound sink=%s", codec, len(data or []), metadata, packet_metadata, self.sound_sink) if self.is_closed(): return if self.sound_sink is not None and codec != self.sound_sink.codec: log.info("sound codec changed from %s to %s", self.sound_sink.codec, codec) self.sound_sink.cleanup() self.sound_sink = None if metadata.get("end-of-stream"): log("client sent end-of-stream, closing sound pipeline") self.stop_receiving_sound() return if not self.sound_sink: if not self.audio_loop_check("microphone"): #make a fake object so we don't fire the audio loop check warning repeatedly class FakeSink: def __init__(self, codec): self.codec = codec def add_data(self, *args): log("FakeSink.add_data%s ignored", args) def cleanup(self, *args): log("FakeSink.cleanup%s ignored", args) self.sound_sink = FakeSink(codec) return try: def sound_sink_error(*args): log("sound_sink_error%s", args) log.warn( "Warning: stopping sound input because of an error") self.stop_receiving_sound() from xpra.sound.wrapper import start_receiving_sound ss = start_receiving_sound(codec) if not ss: return self.sound_sink = ss log("sound_data(..) created sound sink: %s", self.sound_sink) ss.connect("error", sound_sink_error) ss.start() log("sound_data(..) sound sink started") except Exception: log.error("Error: failed to start receiving %r", codec, exc_info=True) return self.sound_sink.add_data(data, metadata, packet_metadata)
def start_sound_sink(self, codec): log("start_sound_sink(%s)", codec) assert self.sound_sink is None, "sound sink already exists!" try: log("starting %s sound sink", codec) from xpra.sound.wrapper import start_receiving_sound ss = start_receiving_sound(codec) if not ss: return False ss.sequence = self.sound_sink_sequence self.sound_sink = ss ss.connect("state-changed", self.sound_sink_state_changed) ss.connect("error", self.sound_sink_error) ss.connect("exit", self.sound_sink_exit) ss.connect(CONNECTION_LOST, self.sound_process_stopped) ss.start() log("%s sound sink started", codec) return True except Exception as e: log.error("Error: failed to start sound sink", exc_info=True) self.sound_sink_error(self.sound_sink, e) return False