So I went down to FOSDEM this weekend. One of the things I was able to do while there was sit down with Edward Hervey and figure out how to use the new encodebin element with Transmageddon. The goal of the new encodebin element is to make encoding a much easier task with GStreamer, where you basically pass it a GStreamer caps value for your container format and audio and video streams, and encodebin figures out which elements it needs to create output with those caps. I have a minimal example below:
import sys
import os
import gobject; gobject.threads_init()
import gst
import pygst
import glib
import gst.pbutils
import gtk
class Transcoder:
def __init__(self):
# create GStreamer pipeline object
self.pipeline = gst.Pipeline("TranscodingPipeline")
self.pipeline.set_state(gst.STATE_PAUSED)
self.uridecoder = gst.element_factory_make("uridecodebin", "uridecoder")
self.uridecoder.set_property("uri", "file:///home/cschalle/Videos/gravity.mpg")
self.uridecoder.connect("pad-added", self.OnDynamicPad)
self.pipeline.add(self.uridecoder)
self.containerprofile = gst.pbutils.EncodingContainerProfile ("ogg", None , gst.Caps("application/ogg"), None)
self.videoprofile = gst.pbutils.EncodingVideoProfile (gst.Caps("video/x-dirac"), None, gst.caps_new_any(), 0)
self.audioprofile = gst.pbutils.EncodingAudioProfile (gst.Caps("audio/x-vorbis"), None, gst.caps_new_any(), 0)
self.containerprofile.add_profile(self.videoprofile)
self.containerprofile.add_profile(self.audioprofile)
self.ebin = gst.element_factory_make ("encodebin", None)
self.ebin.set_property("profile", self.containerprofile)
self.pipeline.add(self.ebin)
print "self.ebin is " + str(self.ebin)
self.ebin.set_state(gst.STATE_PAUSED)
self.uridecoder.set_state(gst.STATE_PAUSED)
self.filesink = gst.element_factory_make("filesink", None)
self.filesink.set_property("location", "/tmp/test.ogg")
self.pipeline.add(self.filesink)
self.filesink.set_state(gst.STATE_PAUSED)
self.ebin.link(self.filesink)
self.pipeline.set_state(gst.STATE_PLAYING)
def OnDynamicPad(self, uridecodebin, src_pad):
c = src_pad.get_caps().to_string()
print c
sinkpad = self.ebin.emit("request-pad", src_pad.get_caps())
print "action signal returned", sinkpad
src_pad.link(sinkpad)
if __name__ == "__main__":
hwg = Transcoder()
gtk.main()
The most important thing to notice about this code is the creation of the profiles, the adding of the audio and video profile to the container profile and then finally the setting of that profile onto the encodebin element. In my example I have extremely simple caps statements, basically just the codecs names, but you could add further things here like video height and width, framerate, audio bitrate, audio channels and so on, and encodebin would be able to give you the correct output.
We did find a couple of Python binding bugs though, which Edward fixed promptly, so if you want to try this code now, you need to grab gstreamer-python from git master.