1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import pygtk
17 pygtk.require('2.0')
18
19 import gobject
20 gobject.threads_init()
21
22 import pygst
23 pygst.require('0.10')
24 import gst
25 import gst.interfaces
26 import gtk
27
28
29
30
31
32
33
34
36
37
39 self.playing = False
40 bin = gst.Bin('my-bin')
41 self.textoverlay = gst.element_factory_make('textoverlay')
42 bin.add(self.textoverlay)
43 pad = self.textoverlay.get_pad("video_sink")
44 ghostpad = gst.GhostPad("sink", pad)
45 bin.add_pad(ghostpad)
46 color = gst.element_factory_make('ffmpegcolorspace')
47 bin.add(color)
48 scale = gst.element_factory_make('videoscale')
49 bin.add(scale)
50 self.videosink = gst.element_factory_make('autovideosink')
51 bin.add(self.videosink)
52 gst.element_link_many(self.textoverlay, color, scale, self.videosink)
53 self.player = gst.element_factory_make("playbin", "player")
54 self.player.set_property("video-sink", bin)
55 self.videowidget = videowidget
56
57 bus = self.player.get_bus()
58 bus.enable_sync_message_emission()
59 bus.add_signal_watch()
60 bus.connect('sync-message::element', self.on_sync_message)
61 bus.connect('message', self.on_message)
62 self.cur_frame = 0
63 self.rate = 1.0
64
66 if message.structure is None:
67 return
68 if message.structure.get_name() == 'prepare-xwindow-id':
69 self.videowidget.set_sink(message.src)
70 message.src.set_property('force-aspect-ratio', True)
71
73 t = message.type
74 if t == gst.MESSAGE_ERROR:
75 err, debug = message.parse_error()
76 print "Error: %s" % err, debug
77 self.playing = False
78 elif t == gst.MESSAGE_EOS:
79 self.playing = False
80
82 """
83 Here we will fast forward the stream for as many times
84 as this is called
85 """
86 if self.rate < 8.0:
87 self.rate = self.rate*2.0
88 event = gst.event_new_seek(self.rate, gst.FORMAT_TIME,
89 gst.SEEK_FLAG_FLUSH,
90 gst.SEEK_TYPE_SET, self.query_position()[0],
91 gst.SEEK_TYPE_NONE, 0)
92
93 res = self.player.send_event(event)
94 if res:
95 gst.info("fast forwarding at rate: %f" % self.rate)
96 self.player.set_new_stream_time(0L)
97 else:
98 gst.error("change rate to %f failed" % self.rate)
99 return
100
102 """
103 Here we will slow motion the stream for as many times
104 as this is called
105 """
106 self.rate = self.rate/2.0
107 event = gst.event_new_seek(self.rate, gst.FORMAT_TIME,
108 gst.SEEK_FLAG_FLUSH,
109 gst.SEEK_TYPE_SET, self.query_position()[0],
110 gst.SEEK_TYPE_NONE, 0)
111
112 res = self.player.send_event(event)
113 if res:
114 gst.info("slowing playback to rate: %f" % self.rate)
115 self.player.set_new_stream_time(0L)
116 else:
117 gst.error("change rate to %f failed" % self.rate)
118
119 return
120
122 """
123 Get the playing rate at the moment
124 """
125 return self.rate
126
127
128
129
131 self.player.set_state(gst.STATE_NULL)
132 self.player.set_property('uri', location)
133
134
135
136
137
138 - def set_subtitle_text(self, text, font=None):
139 if font:
140 self.textoverlay.set_property('subtitle-font-desc', font)
141 self.textoverlay.set_property('text', text)
142 return
143
144
145
147 return self.player.get_property('uri')
148
150 "Returns a (position, duration) tuple"
151 try:
152 position, format = self.player.query_position(gst.FORMAT_TIME)
153 except:
154 position = gst.CLOCK_TIME_NONE
155
156 try:
157 duration, format = self.player.query_duration(gst.FORMAT_TIME)
158 except:
159 duration = gst.CLOCK_TIME_NONE
160
161 return (position, duration)
162
164 "Query the frame position"
165 if position != gst.CLOCK_TIME_NONE:
166 pad = self.videosink.get_pad('sink')
167 caps = pad.get_negotiated_caps()
168 if caps is not None:
169 framerate = caps[0]['framerate']
170 position = float(position)/float(1000000000)
171 self.cur_frame = (float(position)*float(
172 framerate.num))/float(framerate.denom)
173 return self.cur_frame
174
175
176
177
178 - def seek(self, location):
179 gst.debug("seeking to %r" % location)
180 event = gst.event_new_seek(self.rate, gst.FORMAT_TIME,
181 gst.SEEK_FLAG_FLUSH,
182 gst.SEEK_TYPE_SET, location,
183 gst.SEEK_TYPE_NONE, 0)
184
185 res = self.player.send_event(event)
186 if res:
187 gst.info("setting new stream time to 0")
188 self.player.set_new_stream_time(0L)
189 else:
190 gst.error("seek to %r failed" % location)
191
192
193
195 gst.info("pausing player")
196 self.player.set_state(gst.STATE_PAUSED)
197 self.playing = False
198
199
200
202 """
203 Change the stream state to playing or simply
204 change its playing rate to normal rate
205 """
206 if self.rate != 1.0:
207 self.rate = 1.0
208 event = gst.event_new_seek(self.rate, gst.FORMAT_TIME,
209 gst.SEEK_FLAG_FLUSH,
210 gst.SEEK_TYPE_SET, self.query_position()[0],
211 gst.SEEK_TYPE_NONE, 0)
212
213 res = self.player.send_event(event)
214 if res:
215 gst.info("slowing playback to rate: %f" % self.rate)
216 self.player.set_new_stream_time(0L)
217 else:
218 gst.error("change rate to %f failed" % self.rate)
219 else:
220 gst.info("playing player")
221 self.player.set_state(gst.STATE_PLAYING)
222 self.playing = True
223 return
224
225
226
228 self.player.set_state(gst.STATE_READY)
229 self.playing = False
230 gst.info("stopped player")
231
232
233
234
235
237 return self.player.get_state(timeout=timeout)
238
239
240
243
244
245
246
247
248
249
250
251
252
253
254
255
281