1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import gst
19 import gobject
20
21 from flumotion.common import errors, messages
22 from flumotion.common.i18n import N_, gettexter
23 from flumotion.component import feedcomponent
24 from flumotion.component.common.avproducer import avproducer
25
26 __version__ = "$Rev$"
27 T_ = gettexter()
28
29
31
34
37
39 return self.comp.nbiterations
40
43
44
45
46
47
48
49
50
51
52
53
54
55
56 -class Looper(avproducer.AVProducerBase):
57
58 componentMediumClass = LooperMedium
59
61 self.initial_seek = False
62 self.nbiterations = 0
63 self.fileinformation = None
64 self.timeoutid = 0
65 self.pads_awaiting_block = []
66 self.pads_to_link = []
67 self.bus = None
68 self.uiState.addKey('info-location', '')
69 self.uiState.addKey('info-duration', 0)
70 self.uiState.addKey('info-audio', None)
71 self.uiState.addKey('info-video', None)
72 self.uiState.addKey('num-iterations', 0)
73 self.uiState.addKey('position', 0)
74
88
90 return self.pipeline.get_by_name('vident')
91
93 template = (
94 'filesrc location=%(location)s'
95 ' ! oggdemux name=demux'
96 ' demux. ! queue ! theoradec name=theoradec'
97 ' ! identity name=vident single-segment=true sync=true '
98 ' silent=true'
99 ' ! @feeder:video@'
100 ' demux. ! queue ! vorbisdec name=vorbisdec'
101 ' ! volume name=setvolume'
102 ' ! level name=volumelevel message=true '
103 ' ! identity name=aident single-segment=true sync=true '
104 ' silent=true'
105 ' ! @feeder:audio@'
106 % dict(location=self.filelocation))
107
108 return template
109
118
120
121 def discovered(d, ismedia):
122 self.uiState.set('info-location', self.filelocation)
123 self.uiState.set('info-duration',
124 max(d.audiolength, d.videolength))
125 if d.is_audio:
126 self.uiState.set('info-audio',
127 "%d channel(s) %dHz" % (d.audiochannels,
128 d.audiorate))
129 if d.is_video:
130 self.uiState.set('info-video',
131 "%d x %d at %d/%d fps" % (d.videowidth,
132 d.videoheight,
133 d.videorate.num,
134 d.videorate.denom))
135
136 from gst.extend import discoverer
137 d = discoverer.Discoverer(self.filelocation)
138 d.connect('discovered', discovered)
139 d.discover()
140
142 self.do_seek(False)
143 self.nbiterations += 1
144 self.uiState.set('num-iterations', self.nbiterations)
145
147 for src, sink in self.pads_to_link:
148 src.link(sink)
149 self.do_seek(True)
150 for src, sink in self.pads_to_link:
151 src.set_blocked_async(False, lambda *x: None)
152 self.pads_to_link = []
153 self.nbiterations = 0
154 self.uiState.set('num-iterations', self.nbiterations)
155
168
169 self.oggdemux = pipeline.get_by_name("demux")
170
171 for name in 'aident', 'vident':
172
173 def blocked(x, is_blocked):
174 if not x in self.pads_awaiting_block:
175 return
176 self.pads_awaiting_block.remove(x)
177 if not self.pads_awaiting_block:
178 s = gst.Structure('pads-blocked')
179 m = gst.message_new_application(pipeline, s)
180
181 pipeline.post_message(m)
182
183 e = pipeline.get_by_name(name)
184 src = e.get_pad('src')
185 sink = src.get_peer()
186 src.unlink(sink)
187 src.set_blocked_async(True, blocked)
188 self.pads_awaiting_block.append(src)
189 self.pads_to_link.append((src, sink))
190
191 self.bus = pipeline.get_bus()
192 self.bus.add_signal_watch()
193
194 self.bus.connect('message', on_message)
195
197 """
198 Restarts the looping.
199
200 Returns True if the seeking was accepted,
201 Returns False otherwiser
202 """
203 self.debug("restarting looping")
204 flags = gst.SEEK_FLAG_SEGMENT | (flushing and gst.SEEK_FLAG_FLUSH or 0)
205 return self.oggdemux.seek(1.0, gst.FORMAT_TIME, flags,
206 gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_END, 0)
207
209
210 def check_time():
211 self.log("checking position")
212 try:
213 pos, _ = self.pipeline.query_position(gst.FORMAT_TIME)
214 except:
215 self.debug("position query didn't succeed")
216 else:
217 self.uiState.set('position', pos)
218 return True
219
220 if not self.timeoutid:
221 self.timeoutid = gobject.timeout_add(500, check_time)
222
224 if self.bus:
225 self.bus.remove_signal_watch()
226 self.bus = None
227
228 if self.timeoutid:
229 gobject.source_remove(self.timeoutid)
230 self.timeoutid = 0
231
232 self.nbiterations = 0
233
239