def get_widgets_tree(): """ Returns a L{gtk.glade.XML} object. Keep in mind that gtk.glade automatically caches XML trees. So don't try any complex tricks to reuse XML trees if you have to create the same UI multiple times. The correct thing to do is simply to instantiate the XML multiple times with the same parameters. """ # Set the Glade file glade_file = os.path.join(configure.GLADE_DIR, 'scenic.glade') if os.path.isfile(glade_file): glade_path = glade_file else: text = _( "Error : Could not find the Glade file %(filename)s. Exitting." ) % { "filename": glade_file } print(text) def _exit_cb(unused_result): print("Exiting") if reactor.running: reactor.stop() # Recursive imports in Python are really badly managed. # I hope this will be fixed in Python 3.0 from scenic import dialogs dialogs.ErrorDialog.create(text, parent=None).addCallback(_exit_cb) # FIXME: raise error or what? Exitting for now sys.exit(1) return gtk.glade.XML(glade_path, domain=configure.APPNAME)
def on_stopped(self): show_error_dialog = False details = "" if len(self.error_messages) != 0: show_error_dialog = True log.error("Error messages from the preview : %s" % (self.error_messages)) details += _("Errors from local preview:") + "\n" for line in self.error_messages: details += " * " + line + "\n" if len(self.warnings) != 0: details += _("Warnings from local preview:") + "\n" for line in self.warnings: details += " * " + line + "\n" if show_error_dialog: msg = _("Some errors occured while looking at the local preview.") self.app.gui.show_error_dialog(msg, details=details)
def get_widgets_tree(): """ Returns a L{gtk.glade.XML} object. Keep in mind that gtk.glade automatically caches XML trees. So don't try any complex tricks to reuse XML trees if you have to create the same UI multiple times. The correct thing to do is simply to instantiate the XML multiple times with the same parameters. """ # Set the Glade file glade_file = os.path.join(configure.GLADE_DIR, 'scenic.glade') if os.path.isfile(glade_file): glade_path = glade_file else: text = _("Error : Could not find the Glade file %(filename)s. Exitting.") % {"filename": glade_file} print(text) def _exit_cb(unused_result): print("Exiting") if reactor.running: reactor.stop() # Recursive imports in Python are really badly managed. # I hope this will be fixed in Python 3.0 from scenic import dialogs dialogs.ErrorDialog.create(text, parent=None).addCallback(_exit_cb) # FIXME: raise error or what? Exitting for now sys.exit(1) return gtk.glade.XML(glade_path, domain=configure.APPNAME)
def on_stopped(self): """ When the state changes to stopped, * check for errors and display them to the user. """ msg = "" details = "" show_error_dialog = False #TODO: internationalize log.info("All streamers are stopped.") if len(self.error_messages["send"]) != 0: show_error_dialog = True log.error("Error messages from the sender for this session: %s" % (self.error_messages["send"])) details += _("Errors from local sender:") + "\n" for line in self.error_messages["send"]: details += " * " + line + "\n" if len(self.warnings["send"]) != 0: details += _("Warnings from local sender:") + "\n" for line in self.warnings["send"]: details += " * " + line + "\n" if len(self.error_messages["receive"]) != 0: show_error_dialog = True log.error("Error messages from the receiver for this session: %s" % (self.error_messages["receive"])) details += _("Errors from local receiver:") + "\n" for line in self.error_messages["receive"]: details += " * " + line + "\n" if len(self.warnings["receive"]) != 0: details += _("Warnings from local receiver:") + "\n" for line in self.warnings["receive"]: details += " * " + line + "\n" if show_error_dialog: msg = _( "Some errors occured during the audio/video streaming session." ) self.app.gui.show_error_dialog(msg, details=details) # TODO: should we set all our process managers to None # set all to None: self.sender = None self.receiver = None self.extra_sender = None self.extra_receiver = None self.midi_receiver = None self.midi_sender = None log.debug("Done stopping steaming")
def on_stopped(self): """ When the state changes to stopped, * check for errors and display them to the user. """ msg = "" details = "" show_error_dialog = False #TODO: internationalize log.info("All streamers are stopped.") if len(self.error_messages["send"]) != 0: show_error_dialog = True log.error("Error messages from the sender for this session: %s" % (self.error_messages["send"])) details += _("Errors from local sender:") + "\n" for line in self.error_messages["send"]: details += " * " + line + "\n" if len(self.warnings["send"]) != 0: details += _("Warnings from local sender:") + "\n" for line in self.warnings["send"]: details += " * " + line + "\n" if len(self.error_messages["receive"]) != 0: show_error_dialog = True log.error("Error messages from the receiver for this session: %s" % (self.error_messages["receive"])) details += _("Errors from local receiver:") + "\n" for line in self.error_messages["receive"]: details += " * " + line + "\n" if len(self.warnings["receive"]) != 0: details += _("Warnings from local receiver:") + "\n" for line in self.warnings["receive"]: details += " * " + line + "\n" if show_error_dialog: msg = _("Some errors occured during the audio/video streaming session.") self.app.gui.show_error_dialog(msg, details=details) # TODO: should we set all our process managers to None # set all to None: self.sender = None self.receiver = None self.extra_sender = None self.extra_receiver = None self.midi_receiver = None self.midi_sender = None log.debug("Done stopping steaming")
def _create_command(self): """ Looks in the settings, and returns a bash command to run for the preview. The preview is only for video, no sound. @rtype: str """ width, height = self.app.config.video_capture_size.split("x") aspect_ratio = self.app.config.video_aspect_ratio numchannels = self.app.config.audio_channels vumeter_id = self.app.gui.audio_levels_input_socket_id audio_buffer = self.app.config.audio_input_buffer jack_autoconnect = self.app.config.audio_jack_enable_autoconnect window_title = _("Local preview") x_window_id = None if not self.app.config.preview_in_window: if self.app.gui.preview_socket.get_id() == 0L: log.error("XID of the preview drawing area is 0L!") else: x_window_id = self.app.gui.preview_socket.get_id() command = "milhouse --videosource %s --localvideo --window-title \"%s\" --width %s --height %s --aspect-ratio %s" % (self.app.config.video_source, window_title, width, height, aspect_ratio, ) if self.app.devices["jackd_is_running"] and numchannels > 0: command += " --localaudio --audiosource %s --numchannels %s --vumeter-id %s --audio-buffer %s" % (self.app.config.audio_source, numchannels, vumeter_id, audio_buffer) if not jack_autoconnect: command += " --disable-jack-autoconnect" #else: # warning_message = "You should consider starting jackd." if x_window_id is not None: command += " --x-window-id %d" % (x_window_id) else: command += " --videodisplay %s" % (self.app.config.video_display) # xid does not work if DISPLAY is set to an other display. if self.app.config.video_source != "videotestsrc": dev = self.app.parse_v4l2_device_name(self.app.config.video_device) if dev is None: log.error("v4l2 device is not found ! %s" % (self.app.config.video_device)) #FIXME: handle this video_device = dev["name"] command += " --videodevice %s" % (video_device) return command
def _gather_config_to_stream(self, addr): """ Gathers all settings in a big dict. Useful for feedback to the user. """ contact_name = addr contact = self.app._get_contact_by_addr(addr) if contact is not None: contact_name = contact["name"] remote_config = self.app.remote_config # FIXME: should the remote config be passed as a param to this method? send_width, send_height = self.app.config.video_capture_size.split("x") receive_width, receive_height = remote_config["video"]["capture_size"].split("x") # MIDI midi_send_enabled = self.app.config.midi_send_enabled and remote_config["midi"]["recv_enabled"] midi_recv_enabled = self.app.config.midi_recv_enabled and remote_config["midi"]["send_enabled"] midi_input_device = self.app.config.midi_input_device midi_output_device = self.app.config.midi_output_device audio_jitterbuffer = self.app.config.audio_jitterbuffer if self.app.config.audio_video_synchronized and self.app.config.video_recv_enabled: audio_jitterbuffer = self.app.config.video_jitterbuffer log.debug("remote_config: %s" % (remote_config)) self.session_details = { "peer": { "address": addr, "name": contact_name, }, # ----------------- send --------------- "send": { "video": { # Decided by both: "enabled": self.app.config.video_send_enabled and remote_config["video"]["recv_enabled"], # Decided locally: "source": self.app.config.video_source, "device": self.app.config.video_device, "width": int(send_width), # int "height": int(send_height), # int "aspect-ratio": self.app.config.video_aspect_ratio, # Decided by remote peer: "port": remote_config["video"]["port"], "bitrate": remote_config["video"]["bitrate"], "codec": remote_config["video"]["codec"], }, "audio": { # Decided by both: "enabled": self.app.config.audio_send_enabled and remote_config["audio"]["recv_enabled"], # Decided locally: "source": self.app.config.audio_source, "vumeter-id": self.app.gui.audio_levels_input_socket_id, "buffer": self.app.config.audio_input_buffer, "jack_autoconnect": self.app.config.audio_jack_enable_autoconnect, # Decided by remote peer: "numchannels": remote_config["audio"]["numchannels"], "codec": remote_config["audio"]["codec"], "port": remote_config["audio"]["port"], "synchronized": remote_config["audio"]["synchronized"], }, "midi": { "enabled": midi_send_enabled, "input_device": midi_input_device, "port": remote_config["midi"]["port"] } }, # -------------------- recv ------------ "receive": { "video": { # Decided by both: "enabled": self.app.config.video_recv_enabled and remote_config["video"]["send_enabled"], # decided locally: "sink": self.app.config.video_sink, "port": str(self.app.recv_video_port), #decided by the app "codec": self.app.config.video_codec, "deinterlace": self.app.config.video_deinterlace, # bool "window-title": "\"From %s\"" % (contact_name), #TODO: i18n "jitterbuffer": self.app.config.video_jitterbuffer, "fullscreen": self.app.config.video_fullscreen, # bool "display": self.app.config.video_display, "bitrate": self.app.config.video_bitrate, # float # Decided by remote peer: "aspect-ratio": remote_config["video"]["aspect_ratio"], "width": int(receive_width), # int "height": int(receive_height), # int }, "audio": { # Decided by both: "enabled": self.app.config.audio_recv_enabled and remote_config["audio"]["send_enabled"], # decided locally: "numchannels": self.app.config.audio_channels, # int "vumeter-id": self.app.gui.audio_levels_output_socket_id, "codec": self.app.config.audio_codec, "port": self.app.recv_audio_port, "sink": self.app.config.audio_sink, "buffer": self.app.config.audio_output_buffer, "synchronized": self.app.config.audio_video_synchronized, "jitterbuffer": audio_jitterbuffer, "jack_autoconnect": self.app.config.audio_jack_enable_autoconnect, }, "midi": { "enabled": midi_recv_enabled, "jitterbuffer": self.app.config.midi_jitterbuffer, "output_device": midi_output_device, "port": str(self.app.recv_midi_port), } } } if self.session_details["send"]["video"]["source"] != "v4l2src": self.session_details["send"]["video"]["device"] = None if self.session_details["send"]["video"]["codec"] == "theora": self.session_details["send"]["video"]["bitrate"] = None # limit to max numchannels if in raw # ...according to remote's max if self.session_details["receive"]["audio"]["codec"] == "raw": if self.session_details["receive"]["audio"]["numchannels"] > remote_config["audio"]["max_channels_in_raw"]: num = remote_config["audio"]["max_channels_in_raw"] self.session_details["receive"]["audio"]["numchannels"] = num msg = _("Limiting the number of audio channels being received to %(number)d since the remote peer only supports up to that many.\nDecrease it to get rid of this message.") % {"number": num} log.warning(msg) self.app.gui.show_error_dialog(msg) # ...according to local's max if self.session_details["send"]["audio"]["codec"] == "raw": if self.session_details["send"]["audio"]["numchannels"] > self.app.max_channels_in_raw: num = self.app.max_channels_in_raw self.session_details["send"]["audio"]["numchannels"] = num msg = _("Limiting the number of audio channels being sent to %(number)d since we only support up to that many.\nDecrease it to get rid of this message.") % {"number": num} details = _("Update your jackaudiosrc Gstreamer element.") log.warning(msg) log.warning(details) self.app.gui.show_error_dialog(msg, details=details) log.debug(str(self.session_details))
def _gather_config_to_stream(self, addr): """ Gathers all settings in a big dict. Useful for feedback to the user. """ contact_name = addr contact = self.app._get_contact_by_addr(addr) if contact is not None: contact_name = contact["name"] remote_config = self.app.remote_config # FIXME: should the remote config be passed as a param to this method? send_width, send_height = self.app.config.video_capture_size.split("x") receive_width, receive_height = remote_config["video"][ "capture_size"].split("x") # MIDI midi_send_enabled = self.app.config.midi_send_enabled and remote_config[ "midi"]["recv_enabled"] midi_recv_enabled = self.app.config.midi_recv_enabled and remote_config[ "midi"]["send_enabled"] midi_input_device = self.app.config.midi_input_device midi_output_device = self.app.config.midi_output_device audio_jitterbuffer = self.app.config.audio_jitterbuffer if self.app.config.audio_video_synchronized and self.app.config.video_recv_enabled: audio_jitterbuffer = self.app.config.video_jitterbuffer log.debug("remote_config: %s" % (remote_config)) self.session_details = { "peer": { "address": addr, "name": contact_name, }, # ----------------- send --------------- "send": { "video": { # Decided by both: "enabled": self.app.config.video_send_enabled and remote_config["video"]["recv_enabled"], # Decided locally: "source": self.app.config.video_source, "device": self.app.config.video_device, "width": int(send_width), # int "height": int(send_height), # int "aspect-ratio": self.app.config.video_aspect_ratio, # Decided by remote peer: "port": remote_config["video"]["port"], "bitrate": remote_config["video"]["bitrate"], "codec": remote_config["video"]["codec"], }, "audio": { # Decided by both: "enabled": self.app.config.audio_send_enabled and remote_config["audio"]["recv_enabled"], # Decided locally: "source": self.app.config.audio_source, "vumeter-id": self.app.gui.audio_levels_input_socket_id, "buffer": self.app.config.audio_input_buffer, "jack_autoconnect": self.app.config.audio_jack_enable_autoconnect, # Decided by remote peer: "numchannels": remote_config["audio"]["numchannels"], "codec": remote_config["audio"]["codec"], "port": remote_config["audio"]["port"], "synchronized": remote_config["audio"]["synchronized"], }, "midi": { "enabled": midi_send_enabled, "input_device": midi_input_device, "port": remote_config["midi"]["port"] } }, # -------------------- recv ------------ "receive": { "video": { # Decided by both: "enabled": self.app.config.video_recv_enabled and remote_config["video"]["send_enabled"], # decided locally: "sink": self.app.config.video_sink, "port": str(self.app.recv_video_port), #decided by the app "codec": self.app.config.video_codec, "deinterlace": self.app.config.video_deinterlace, # bool "window-title": "\"From %s\"" % (contact_name), #TODO: i18n "jitterbuffer": self.app.config.video_jitterbuffer, "fullscreen": self.app.config.video_fullscreen, # bool "display": self.app.config.video_display, "bitrate": self.app.config.video_bitrate, # float # Decided by remote peer: "aspect-ratio": remote_config["video"]["aspect_ratio"], "width": int(receive_width), # int "height": int(receive_height), # int }, "audio": { # Decided by both: "enabled": self.app.config.audio_recv_enabled and remote_config["audio"]["send_enabled"], # decided locally: "numchannels": self.app.config.audio_channels, # int "vumeter-id": self.app.gui.audio_levels_output_socket_id, "codec": self.app.config.audio_codec, "port": self.app.recv_audio_port, "sink": self.app.config.audio_sink, "buffer": self.app.config.audio_output_buffer, "synchronized": self.app.config.audio_video_synchronized, "jitterbuffer": audio_jitterbuffer, "jack_autoconnect": self.app.config.audio_jack_enable_autoconnect, }, "midi": { "enabled": midi_recv_enabled, "jitterbuffer": self.app.config.midi_jitterbuffer, "output_device": midi_output_device, "port": str(self.app.recv_midi_port), } } } if self.session_details["send"]["video"]["source"] != "v4l2src": self.session_details["send"]["video"]["device"] = None if self.session_details["send"]["video"]["codec"] == "theora": self.session_details["send"]["video"]["bitrate"] = None # limit to max numchannels if in raw # ...according to remote's max if self.session_details["receive"]["audio"]["codec"] == "raw": if self.session_details["receive"]["audio"][ "numchannels"] > remote_config["audio"][ "max_channels_in_raw"]: num = remote_config["audio"]["max_channels_in_raw"] self.session_details["receive"]["audio"]["numchannels"] = num msg = _( "Limiting the number of audio channels being received to %(number)d since the remote peer only supports up to that many.\nDecrease it to get rid of this message." ) % { "number": num } log.warning(msg) self.app.gui.show_error_dialog(msg) # ...according to local's max if self.session_details["send"]["audio"]["codec"] == "raw": if self.session_details["send"]["audio"][ "numchannels"] > self.app.max_channels_in_raw: num = self.app.max_channels_in_raw self.session_details["send"]["audio"]["numchannels"] = num msg = _( "Limiting the number of audio channels being sent to %(number)d since we only support up to that many.\nDecrease it to get rid of this message." ) % { "number": num } details = _("Update your jackaudiosrc Gstreamer element.") log.warning(msg) log.warning(details) self.app.gui.show_error_dialog(msg, details=details) log.debug(str(self.session_details))