Move files from gst-python into the "subprojects/gst-python//" subdir
[platform/upstream/gstreamer.git] / subprojects / gst-python / old_examples / switch.py
1 #!/usr/bin/env python
2 # -*- Mode: Python -*-
3 # vi:si:et:sw=4:sts=4:ts=4
4
5 import pygtk
6 pygtk.require('2.0')
7
8 import sys
9
10 import gobject
11 gobject.threads_init()
12
13 import pygst
14 pygst.require('0.10')
15 import gst
16 import gst.interfaces
17 import gtk
18 gtk.gdk.threads_init()
19
20 class SwitchTest:
21     def __init__(self, videowidget):
22         self.playing = False
23         pipestr = ('videotestsrc pattern=0 ! queue ! s.sink0'
24                    ' videotestsrc pattern=1 ! queue ! s.sink1'
25                    ' input-selector name=s ! autovideosink')
26         self.pipeline = gst.parse_launch(pipestr)
27         self.videowidget = videowidget
28
29         bus = self.pipeline.get_bus()
30         bus.enable_sync_message_emission()
31         bus.add_signal_watch()
32         bus.connect('sync-message::element', self.on_sync_message)
33         bus.connect('message', self.on_message)
34
35     def on_sync_message(self, bus, message):
36         if message.structure is None:
37             return
38         if message.structure.get_name() == 'prepare-xwindow-id':
39             # Sync with the X server before giving the X-id to the sink
40             gtk.gdk.threads_enter()
41             gtk.gdk.display_get_default().sync()
42             self.videowidget.set_sink(message.src)
43             message.src.set_property('force-aspect-ratio', True)
44             gtk.gdk.threads_leave()
45             
46     def on_message(self, bus, message):
47         t = message.type
48         if t == gst.MESSAGE_ERROR:
49             err, debug = message.parse_error()
50             print "Error: %s" % err, debug
51             if self.on_eos:
52                 self.on_eos()
53             self.playing = False
54         elif t == gst.MESSAGE_EOS:
55             if self.on_eos:
56                 self.on_eos()
57             self.playing = False
58
59     def play(self):
60         self.playing = True
61         gst.info("playing player")
62         self.pipeline.set_state(gst.STATE_PLAYING)
63         
64     def stop(self):
65         self.pipeline.set_state(gst.STATE_NULL)
66         gst.info("stopped player")
67         self.playing = False
68
69     def get_state(self, timeout=1):
70         return self.pipeline.get_state(timeout=timeout)
71
72     def is_playing(self):
73         return self.playing
74     
75     def switch(self, padname):
76         switch = self.pipeline.get_by_name('s')
77         stop_time = switch.emit('block')
78         newpad = switch.get_static_pad(padname)
79         start_time = newpad.get_property('running-time')
80         
81         gst.warning('stop time = %d' % (stop_time,))
82         gst.warning('stop time = %s' % (gst.TIME_ARGS(stop_time),))
83
84         gst.warning('start time = %d' % (start_time,))
85         gst.warning('start time = %s' % (gst.TIME_ARGS(start_time),))
86
87         gst.warning('switching from %r to %r'
88                     % (switch.get_property('active-pad'), padname))
89         switch.emit('switch', newpad, stop_time, start_time)
90
91 class VideoWidget(gtk.DrawingArea):
92     def __init__(self):
93         gtk.DrawingArea.__init__(self)
94         self.imagesink = None
95         self.unset_flags(gtk.DOUBLE_BUFFERED)
96
97     def do_expose_event(self, event):
98         if self.imagesink:
99             self.imagesink.expose()
100             return False
101         else:
102             return True
103
104     def set_sink(self, sink):
105         assert self.window.xid
106         self.imagesink = sink
107         self.imagesink.set_xwindow_id(self.window.xid)
108
109 class SwitchWindow(gtk.Window):
110     UPDATE_INTERVAL = 500
111     def __init__(self):
112         gtk.Window.__init__(self)
113         self.set_default_size(410, 325)
114
115         self.create_ui()
116         self.player = SwitchTest(self.videowidget)
117         self.populate_combobox()
118
119         self.update_id = -1
120         self.changed_id = -1
121         self.seek_timeout_id = -1
122
123         self.p_position = gst.CLOCK_TIME_NONE
124         self.p_duration = gst.CLOCK_TIME_NONE
125
126         def on_delete_event():
127             self.player.stop()
128             gtk.main_quit()
129         self.connect('delete-event', lambda *x: on_delete_event())
130
131     def load_file(self, location):
132         self.player.set_location(location)
133                                   
134     def play(self):
135         self.player.play()
136         
137     def populate_combobox(self):
138         switch = self.player.pipeline.get_by_name('s')
139         for i, pad in enumerate([p for p in switch.pads()
140                                  if p.get_direction() == gst.PAD_SINK]):
141             self.combobox.append_text(pad.get_name())
142             if switch.get_property('active-pad') == pad.get_name():
143                 self.combobox.set_active(i)
144         if self.combobox.get_active() == -1:
145             self.combobox.set_active(0)
146
147     def combobox_changed(self):
148         model = self.combobox.get_model()
149         row = model[self.combobox.get_active()]
150         padname, = row
151         self.player.switch(padname)
152
153     def create_ui(self):
154         vbox = gtk.VBox()
155         self.add(vbox)
156
157         self.videowidget = VideoWidget()
158         vbox.pack_start(self.videowidget)
159         
160         hbox = gtk.HBox()
161         vbox.pack_start(hbox, fill=False, expand=False)
162         
163         self.combobox = combobox = gtk.combo_box_new_text()
164         combobox.show()
165         hbox.pack_start(combobox)
166
167         self.combobox.connect('changed',
168                               lambda *x: self.combobox_changed())
169
170         self.videowidget.connect_after('realize',
171                                        lambda *x: self.play())
172
173 def main(args):
174     def usage():
175         sys.stderr.write("usage: %s\n" % args[0])
176         return 1
177
178     # Need to register our derived widget types for implicit event
179     # handlers to get called.
180     gobject.type_register(SwitchWindow)
181     gobject.type_register(VideoWidget)
182
183     if len(args) != 1:
184         return usage()
185
186     w = SwitchWindow()
187     w.show_all()
188     gtk.main()
189     return 0
190
191 if __name__ == '__main__':
192     sys.exit(main(sys.argv))