class GTKGStreamerWindow(object): with WindowServiceProxy(port=59000) as w: video_mode_map = w.get_video_mode_map() video_mode_keys = sorted(video_mode_map.keys()) device_key, devices = w.get_video_source_configs() if not video_mode_keys: raise DeviceNotFound def __init__(self): window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_title("Mpeg2-Player") window.set_default_size(640, 500) window.connect("destroy", self.on_destroy) vbox = gtk.VBox() window.add(vbox) hbox = gtk.HBox() vbox.pack_start(hbox, expand=False) video_mode_enum = Enum.named('video_mode').valued(*self.video_mode_keys) form = Form.of( video_mode_enum.using(default=self.video_mode_keys[0]), Filepath.named('output_path').using(default=''), Integer.named('bitrate').using(default=150, validators=[ValueAtLeast( minimum=25)], properties={'step': 25, 'label': 'Bitrate (KB/s)', }), String.named('transform_string').using(default='1,0,0,0,1,0,0,0,1'), Boolean.named('draw_cairo').using(default=False), ) self.video_mode_form_view = create_form_view(form) for field in ['video_mode', 'output_path', 'bitrate', 'transform_string', 'draw_cairo']: setattr(self, '%s_field' % field, self.video_mode_form_view.form\ .fields[field]) self.video_mode_field.proxy.connect('changed', self._on_mode_changed) self.video_source = None hbox.add(self.video_mode_form_view.widget) self.button = gtk.Button("Start") hbox.pack_start(self.button, False) self.button.connect("clicked", self.start_stop) self.aframe = gtk.AspectFrame(xalign=0.5, yalign=1.0, ratio=4.0 / 3.0, obey_child=False) self.pipeline = None self._proxy = None vbox.pack_start(self.aframe, expand=True) self.movie_view = GtkVideoView() self.movie_window = self.movie_view.widget self.aframe.add(self.movie_window) window.show_all() self.window = window @property def transform_str(self): transform_string = self.video_mode_form_view.form\ .fields['transform_string'].element.value data = [float(v) for v in transform_string.split(',')] if len(data) != 9: print ''' Transform string must be 9 comma-separated floats'''.strip() return '1,0,0,0,1,0,0,0,1' return ','.join(['{}'.format(v) for v in data]) @property def draw_cairo(self): return self.video_mode_form_view.form.fields['draw_cairo'].element.value @property def bitrate(self): return (self.video_mode_form_view.form.fields['bitrate'].element.value << 13) @property def output_path(self): return self.video_mode_form_view.form.fields['output_path'].element.value @property def video_settings(self): return self.video_mode_form_view.form.fields['video_mode'].element.value def _on_mode_changed(self, *args): self.video_settings = self.video_mode_form_view.form.fields[ 'video_mode'].element.value @video_settings.setter def video_settings(self, value): self._video_settings = value def get_video_device_and_caps_str(self): selected_mode = self.video_mode_map[self.video_settings] caps_str = GstVideoSourceManager.get_caps_string(selected_mode) return (str(selected_mode['device']), caps_str) def start_stop(self, w): if self.button.get_label() == "Start": self.start() else: self.stop() def start(self): if not self.output_path: error('Please select a valid output filepath.') return self.movie_window.set_size_request(640, 480) self.aframe.show_all() # Use GStreamer WindowServiceProxy to control GStreamer video # pipeline. Behind the scenes, it runs GStreamer in a separate # process (subprocess.Popen), exposed through a JSON-RPC # interface. # There are issues with the GTK gui freezing when the # GStreamer pipeline is started here directly. from pygst_utils.elements.draw_queue import get_example_draw_queue if self.draw_cairo: print 'using draw_queue' x, y, width, height = self.movie_window.get_allocation() draw_queue = get_example_draw_queue(width, height) else: print 'NOT using draw_queue' draw_queue = None self._proxy = WindowServiceProxy(port=59000) try: self._proxy.window_xid(self.movie_view.window_xid) device, caps_str = self.get_video_device_and_caps_str() self._proxy.create(device, caps_str, record_path=self.output_path, bitrate=self.bitrate, draw_queue=draw_queue, with_warp=True, with_scale=True) self._proxy.set_warp_transform(self.transform_str) self._proxy.start() self._proxy.scale(width, height) except (Exception, ), why: print why self.stop() return self.video_mode_field.proxy.widget.set_button_sensitivity(gtk.SENSITIVITY_OFF) self.transform_string_field.widget.set_sensitive(False) self.output_path_field.widget.set_sensitive(False) self.bitrate_field.widget.set_sensitive(False) self.button.set_label("Stop")