2005年5月11日

Python with Gstreamer

OK, so what if we use python and the playbin of gstreamer? Well, that can be done in a few lines:

player.py



#!/usr/bin/python
import sys, os.path
import pygtk; pygtk.require('2.0')
import gtk
import gst, gst.interfaces

def cb_eos(kele, data):
gtk.main_quit()
def cb_error(*args):
print args, args[2]

class Control:
def __init__(self, playbin, vsink,da):
self.fullscreen = False
self.play = playbin
self.vsink = vsink
self.da = da
def key_release(self, widget, event, *args):
if event.string in ['p', ' ']:
if self.play.get_state() == gst.STATE_PLAYING:
ret = self.play.set_state(gst.STATE_PAUSED)
else:
self.vsink.set_xwindow_id(self.da.window.xid)
ret = self.play.set_state(gst.STATE_PLAYING)
elif event.string == 's':
ret = self.play.set_state(gst.STATE_NULL)
elif event.string == 'q':
self.quit()
elif event.string == 'f':
if self.fullscreen:
widget.unfullscreen()
else:
widget.fullscreen()
self.fullscreen = not self.fullscreen
def quit(self, *args):
ret = self.play.set_state(gst.STATE_NULL)
gtk.main_quit()


def main():
fname = sys.argv[1]
absfname = os.path.abspath(fname)
uri = 'file://%s' % absfname

# Setup video/audio sink and playbin
vsink = gst.element_factory_make('xvimagesink')
asink = gst.element_factory_make('esdsink', 'asink')
playbin = gst.element_factory_make('playbin', 'playbin')
playbin.set_property('video-sink', vsink)
playbin.set_property('audio-sink', asink)
playbin.set_property('uri', uri)

playbin.connect('eos', cb_eos)
playbin.connect('error', cb_error)

win = gtk.Window(gtk.WINDOW_TOPLEVEL)
da = gtk.DrawingArea()
ctr = Control(playbin, vsink, da)
win.add(da)
win.connect('key-release-event', ctr.key_release)
win.connect('delete-event', ctr.quit)
win.show_all()
gtk.main()
playbin.set_state(gst.STATE_NULL)

if __name__ == '__main__':
main()
# vim:ts=8:sw=4:expandtab



You can just type


player.py test.avi


The key bindings are:





p or spacePlay/pause the movie
sStop the movie
fFullscreen/un-fullscreen
qQuit the program.



Note:



  • You have to import gst.interfaces for many methods to exist, e.g. xvimagesink.set_xwindow_id().

  • It seems that the binding between gstreamer video window and gtk+ window have to happens later. That's why we set_xwindow_id() before starting to play the movie.

  • You need to use a gtk.AspectFrame for keeping the aspect ratio of the movie.

1 条评论:

Toufeeq 说...

Nice post on Gstreamer. Really helped a lot. Thanks.