<span style="font-family: courier new,monospace;">Hi all,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Sorry if this is the wrong place to ask questions about code written with the Python bindings... there doesn't seem to be a python-gst mailing list, so I figured I'd give this a shot.
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">I'm new to gstreamer and trying to write some code that will slurp a stream off the web into a file, and transcode it to MP3 if not already in that format. The application is to automatically convert it to a form that most portable audio players can understand.
<br><br>I have some working code, but not exactly sure "why" it works ;-) Basically, what I do is I set up a gnomevfssrc ! typefind pipeline, and connect the have-type signal of the typefind element. Then I start the pipeline playing. When the have-type signal is received, I pause the pipeline, and then:
<br> (a) if the detected stream is MP3, I make an identity element as the transcoder: transcoder = identity<br> (b) if it's not MP3, I make a real transcoder: transcoder = decodebin ! audioconvert ! lame<br>Next, I link this transcoder to the end of the pipeline and link that to a filesink, so I end up with:
<br> gnomevfssrc ! typefind ! transcoder ! filesink<br>Finally, I unpause the pipeline, and the MP3 output stream magically goes into the output file. Hooray!<br><br>Here are a few things I'm trying to understand:<br>
<br>* Are there any subtleties to modifying a running pipeline? When I pause the pipeline, append to it, and then unpause it, should I be worried about data getting lost, or buffer overflows, or anything like that? This doesn't seem to be a problem, but maybe I've just got lucky.
<br><span style="font-style: italic;"></span><br>* If I add() the transcoder and sink elements to the pipeline BEFORE I'm ready to actually link their pads, then the pipeline runs, and typefind works... but I get no output. Why?
<br><br>* Typefind identifies MP3 files as application/id3 sometimes, rather than audio/mpeg. Is there a more correct and reliable way to identify an MP3 stream?<br><br>* How can I identify the duration of the stream processed by the pipeline?
pipeline.get_clock() seems to keep track of the REAL time, rather than the amount of audio processed.<br><br>Any help will be appreciated! Thanks a lot!<br><br>Dan Lenski<br><br><br>PS- The relevant parts of my code so far:
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class transcode_to_mp3(gst.Bin):<br> # a bin containing decodebin, audioconvert, and lame
<br> # to auto-convert any audio stream to MP3<br> ...<br><br>class StreamRecorder:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def __init__(self, uri, filename):
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> # stream reader</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.stream = gst.element_factory_make('gnomevfssrc')</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.stream.set_property('location', uri)
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> # automatically identify stream type</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.typefind = gst.element_factory_make('typefind')</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.typefind.set_property('minimum', 100)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.typefind.connect('have-type', self.autoconfigure
)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> # convert arbitrary audio stream to MP3, or do nothing to an MP3
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.transcode = transcode_to_mp3()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
self.identity = gst.element_factory_make('identity')</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
# write to file output</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.sink = gst.element_factory_make('filesink')</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.sink.set_property('location', filename)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
# partially assemble pipeline</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.pipeline = gst.Pipeline()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.pipeline.add(self.stream, self.typefind)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.stream.link
(self.typefind)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def autoconfigure(self, tf, prob, caps):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.pipeline.set_state(gst.STATE_PAUSED)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
ismp3 = (caps[0].get_name() == 'audio/mpeg' and caps[0]['layer']==3)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> if ismp3: stage =
self.identity</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> else: stage = self.mp3ify</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.pipeline.add(stage, self.sink)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> gst.element_link_many
(self.typefind, stage, self.sink)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.pipeline.set_state(gst.STATE_PLAYING
)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def start(self):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.pipeline.set_state(gst.STATE_PLAYING)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
def stop(self):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.pipeline.set_state(gst.STATE_NULL)</span><span style="font-family: courier new,monospace;">
<br></span>