Python GStreamer
Sample code
Jono Bacon posted an intro to programming with python gstreamer and glade:
Alessandro Decina (twism) posted some sample code for a simple video player in python gstreamer to xvimagesink:
- http://pastebin.ca/150771
- http://pastebin.ca/164714 (updated for better cmml syncing)
Mike Smith posted some minimal code for a playbin based player:
Documentation
Some docs are at:
- http://pygstdocs.berlios.de/
- http://gstreamer.freedesktop.org/documentation/
- http://webcvs.freedesktop.org/gstreamer/gstreamer/docs/design/
General documentation for the GStreamer C API is available in devhelp. On Debian based systems:
apt-get install devhelp libgtk2.0-doc libglib2.0-doc libpango1.0-doc libgstreamer0.10-doc gstreamer0.10-plugins-base-doc
Video Playback
Getting ready to play a video
Set up the pipeline, set it to READY and preroll
When you want to play, set it to PLAY
To put text on a video, use textoverlay
Prerolling
Prerolling is what the elements/pipeline do when they set up for PAUSED or PLAYING. if an element is at READY and you ask it to go to PAUSED, then it will set itself up to go to paused (decode keyframes etc) and send an asynchronous message when it is at paused.
Hence, you can wait for all the async messages to come in.
Alternatively, you can call gst_element_get_state() with an infinite timeout GST_CLOCK_TIME_NONE
Switching between video streams
To switch between video streams, it may be necessary to set up a pipeline for each video. However, you only want one output video sink. In order to set a pipeline to READY or PAUSED without having a video sink connected, you need to block the output pads, then preroll the video (tho paused will incur actual decode CPU etc. so you might not want to do that to set up lots of videos).
pad blocking: devhelp://GStreamer Core/GstPad :: gst_pad_set_blocked
Then, to switch video, connect to the videosink and set to PLAY.
Switching to images
You don't need to preroll images; data doesn't flow until you set it going. You can't play the image, but you can simply set its pipeline to PAUSED to force the image to be displayed.
To put text on an image, use textrender
Hooking an xvimagesink into a given x window (eg. a fullscreen window)
1. Get its xid
To get the drawable for a widget: widget->window
To get the xid for a drawable:
widget.window.xid
http://www.daa.com.au/pipermail/pygtk/2005-March/009720.html
2. xvimagesink implements the interface for XOverlay
devhelp://GStreamer Base/Interfaces/gstxoverlay
xvimagesink uses synchronous events. The sample code in devhelp shows how to set up a sync handler such that on receipt of the "prepare-xwindow-id" message, you can connect the xvimagesink to the xid.
ie. create the pipeline containing an xvimagesink, then wait for it to send a prepare-xwindow-id message (once you've started mainloop) and hook it up to the xid you prepared earlier.
gst_x_overlay_set_xwindow_id()
Buffers ; text buffers
Buffers contain data, start time and duration.
For textoverlay, the input buffer can be plaintext or pangotext (pangotext allows some simple markup like bold, italic and colors).
Textoverlay has properties for the type of input, and for the x,y placement and padding.
Static text can be set as a property instead of being read in from a buffer.
Twism suggests to "place a queue element infront of the textoverlay before pushing data to it." His example code "pushes data into the pipeline from the main thread. The sink could block the main thread waiting for buf.timestamp. If the main thread is blocked, all the events dispatched by the GMainLoop would be delayed.
"If you insert a queue element (gst.element_factory_make ("queue")) that will create a new thread and the main thread and the queue thread will work like a producer-consumer so the main thread returns in the main loop as soon as the buffer enters the queue."
Caveat: gst_clock_id_*() are not wrapped, and they're what is needed to synchronze to the clock. GstClockID is not a GObject, so it needs to be GBoxed in order to wrap it.
Wrapping GStreamer in Python: Codegen
Codegen is the Python parser used to wrap Gtk/GObject/GStreamer/anything using GObjects. It reduces the amount of boring code you have to write, and makes it more fun by using a Lisp-like syntax.
http://www.smh.com.au/ffximage/2006/09/08/python_wideweb__470x325,2.jpg
Codegen is shipped with gst-python, in gst-python/gst/ you have a bunch of *.defs and *.override files. For structs that are GObjects, you need to add a definition in a def file. For structs that are not GObjects (such as GstClockID), you additionally need to write the boxed_copy and boxed_free functions ... and then submit a patch. In order to do all this, only gst-python needs to be run from cvs.
Credits
Thanks to Jan Schmidt (thaytan) and Alessandro Decina (twism) for the explanations. Thanks to Jono and Mike for the tutorials and useful code.
