Move python experiments to a python/ subdir
authorAntonio Ospite <ospite@studenti.unina.it>
Thu, 24 Oct 2013 11:27:42 +0000 (13:27 +0200)
committerAntonio Ospite <ospite@studenti.unina.it>
Thu, 24 Oct 2013 11:27:42 +0000 (13:27 +0200)
14 files changed:
gst-custom-player.py [deleted file]
gst-looping-video-1.py [deleted file]
gst-looping-video-2.py [deleted file]
gst-trick-mode-looping-1.py [deleted file]
gst-trick-mode-looping-2.py [deleted file]
gst-trick-mode-looping-3.py [deleted file]
gst-trick-mode.py [deleted file]
python/gst-custom-player.py [new file with mode: 0755]
python/gst-looping-video-1.py [new file with mode: 0755]
python/gst-looping-video-2.py [new file with mode: 0755]
python/gst-trick-mode-looping-1.py [new file with mode: 0755]
python/gst-trick-mode-looping-2.py [new file with mode: 0755]
python/gst-trick-mode-looping-3.py [new file with mode: 0755]
python/gst-trick-mode.py [new file with mode: 0755]

diff --git a/gst-custom-player.py b/gst-custom-player.py
deleted file mode 100755 (executable)
index cbeace2..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/usr/bin/env python
-
-# Simple media player with GStreamer
-#
-# Copyright (C) 2013  Antonio Ospite <ospite@studenti.unina.it>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# References:
-# http://pygstdocs.berlios.de/pygst-reference
-# https://core.fluendo.com/gstreamer/svn/trunk/gst-fluendo-gdlsink/test/ismdplay.py
-
-import sys
-import os
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-# The player window will have a fixed width and height.
-# This is just to demonstrate the use of capabilities.
-WIDTH = 640
-HEIGHT = 300
-
-
-class CustomVideoBin(gst.Bin):
-    def __init__(self):
-        gst.Bin.__init__(self, 'CustomVideoBin')
-
-        queue = gst.element_factory_make('queue', 'vqueue')
-        self.add(queue)
-
-        rescale = gst.element_factory_make("videoscale", "rescale")
-        self.add(rescale)
-
-        caps = gst.Caps("video/x-raw-yuv,format=(fourcc)AYUV,width=%d,height=%d,pixel-aspect-ratio=1/1" % (WIDTH, HEIGHT))
-        capsfilter = gst.element_factory_make("capsfilter", "filter")
-        capsfilter.set_property("caps", caps)
-        self.add(capsfilter)
-
-        colorspace = gst.element_factory_make("colorspace", "colorspace")
-        self.add(colorspace)
-
-        videosink = gst.element_factory_make("autovideosink", "vidoesink")
-        self.add(videosink)
-
-        gst.element_link_many(queue, rescale, capsfilter, colorspace, videosink)
-        sink = queue.get_pad('sink')
-        self.add_pad(gst.GhostPad('sink', sink))
-
-
-class CustomAudioBin(gst.Bin):
-    def __init__(self):
-        gst.Bin.__init__(self, 'CustomAudioBin')
-
-        queue = gst.element_factory_make('queue', 'aqueue')
-        self.add(queue)
-
-        audioconvert = gst.element_factory_make("audioconvert", "audioconverter")
-        self.add(audioconvert)
-
-        audiosink = gst.element_factory_make("autoaudiosink", "audiosink")
-        self.add(audiosink)
-
-        gst.element_link_many(queue, audioconvert, audiosink)
-        sink = queue.get_pad('sink')
-        self.add_pad(gst.GhostPad('sink', sink))
-
-
-class CustomPlayBin(gst.Pipeline):
-    __gproperties__ = {
-        'source': (gst.Element, "source", "Source element", gobject.PARAM_READABLE)
-    }
-
-    def __init__(self, uri=None):
-        gst.Pipeline.__init__(self, 'CustomPlayBin')
-
-        self._uri = uri
-
-        self._playbin = gst.element_factory_make("playbin2", "playbin")
-        self.add(self._playbin)
-
-        self._playbin.set_property("uri", self._uri)
-        self._playbin.set_property("video-sink", CustomVideoBin())
-        self._playbin.set_property("audio-sink", CustomAudioBin())
-
-    def set_uri(self, uri):
-        self._uri = uri
-        self._playbin.set_property("uri", self._uri)
-
-
-class GstPlayer:
-    def __init__(self):
-
-        # The user can require some action at End Of Stream
-        self.eos_cb = None
-
-        self.pipeline = CustomPlayBin()
-
-        bus = self.pipeline.get_bus()
-        bus.add_signal_watch()
-        bus.connect('message::eos', self.on_eos)
-        bus.connect('message::tag', self.on_tag)
-        bus.connect('message::error', self.on_error)
-        bus.connect('message::state-changed', self.on_state_changed)
-
-    def on_eos(self, bus, msg):
-        print 'on_eos'
-        self.stop()
-        if self.eos_cb:
-            self.eos_cb()
-
-    def on_tag(self, bus, msg):
-        print 'on_tag:'
-        taglist = msg.parse_tag()
-        for key in taglist.keys():
-            print '\t%s = %s' % (key, taglist[key])
-
-    def on_error(self, bus, msg):
-        print 'on_error'
-        error, debug = msg.parse_error()
-        print "Error: %s" % error, debug
-        self.stop()
-
-    def on_state_changed(self, bus, msg):
-        print 'on_state_changed'
-        if msg.src != self.pipeline:
-            return
-
-        old_state, new_state, pending = msg.parse_state_changed()
-
-    def set_location(self, location):
-        self.pipeline.set_uri(location)
-
-    def play(self):
-        self.pipeline.set_state(gst.STATE_PLAYING)
-
-    def pause(self):
-        self.pipeline.set_state(gst.STATE_PAUSED)
-
-    def stop(self):
-        self.pipeline.set_state(gst.STATE_NULL)
-
-
-class PlayerTUI():
-    def __init__(self, location):
-
-        self.player = GstPlayer()
-        self.player.eos_cb = self.quit
-
-        self.mainloop = gobject.MainLoop()
-
-        self.player.set_location(location)
-        self.player.play()
-
-        gobject.io_add_watch(sys.stdin, gobject.IO_IN, self.on_stdin)
-
-        try:
-            self.mainloop.run()
-        except KeyboardInterrupt:
-            self.quit()
-
-    def on_stdin(self, fd, event):
-        # The user has to send a newline fo this to go on
-        c = os.read(fd.fileno(), 1)
-
-        if c == "q":
-            self.quit()
-        elif c == "s":
-            self.player.pause()
-        elif c == "r":
-            self.player.play()
-
-        return True
-
-    def quit(self):
-        self.player.stop()
-        self.player = None
-        self.mainloop.quit()
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    tui = PlayerTUI(args[1])
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/gst-looping-video-1.py b/gst-looping-video-1.py
deleted file mode 100755 (executable)
index 9886abe..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python
-
-# Get a test sample with:
-# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
-
-import sys
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-
-class Player:
-    def __init__(self, filename):
-        self._filename = filename
-
-        self._player = gst.element_factory_make("playbin2", "player")
-        self._player.set_property("uri", filename)
-
-        bus = self._player.get_bus()
-        bus.add_signal_watch()
-        bus.connect('message::eos', self.on_eos)
-
-    def run(self):
-        self._player.set_state(gst.STATE_PLAYING)
-        loop = gobject.MainLoop()
-        loop.run()
-
-    def on_eos(self, bus, msg):
-        sys.stderr.write(".")
-        self._player.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, 0)
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    player = Player(args[1])
-    player.run()
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/gst-looping-video-2.py b/gst-looping-video-2.py
deleted file mode 100755 (executable)
index eabb7a4..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-
-# Get a test sample with:
-# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
-
-import sys
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-
-class Player:
-    def __init__(self, filename):
-        self._filename = filename
-
-        self._player = gst.element_factory_make("playbin2", "player")
-        self._player.set_property("uri", filename)
-        self._player.connect("about-to-finish", self.on_about_to_finish)
-
-    def run(self):
-        self._player.set_state(gst.STATE_PLAYING)
-        loop = gobject.MainLoop()
-        loop.run()
-
-    def on_about_to_finish(self, player):
-        sys.stderr.write(".")
-        player.set_property("uri", self._filename)
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    player = Player(args[1])
-    player.run()
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/gst-trick-mode-looping-1.py b/gst-trick-mode-looping-1.py
deleted file mode 100755 (executable)
index fe00556..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-
-# Get a test sample with:
-# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
-
-import sys
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-
-class Player:
-    def __init__(self, filename, rate):
-        self._filename = filename
-        self._rate = rate
-
-        self._player = gst.element_factory_make("playbin2", "player")
-        self._player.set_property("uri", filename)
-
-        bus = self._player.get_bus()
-        bus.add_signal_watch()
-        bus.connect('message::eos', self.on_eos)
-        bus.connect('message::state-changed', self.on_state_changed)
-
-    def run(self):
-        self._player.set_state(gst.STATE_PLAYING)
-        loop = gobject.MainLoop()
-        loop.run()
-
-    def on_eos(self, bus, msg):
-        sys.stderr.write(".")
-        self._player.set_state(gst.STATE_PLAYING)
-        seek_event = gst.event_new_seek(self._rate,
-                gst.FORMAT_TIME,
-                gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                gst.SEEK_TYPE_SET, 0,
-                gst.SEEK_TYPE_NONE, 0)
-        self._player.send_event(seek_event)
-
-    def on_state_changed(self, bus, msg):
-        if msg.src != self._player:
-            return
-
-        print 'on_state_changed'
-        old_state, new_state, pending = msg.parse_state_changed()
-        print "%s -> %s" % (old_state, new_state)
-        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
-            self.set_rate(self._rate)
-
-    def set_rate(self, rate):
-        self._rate = rate
-        try:
-            position, format = self._player.query_position(gst.FORMAT_TIME)
-        except:
-            position = 0
-
-        # Create the seek event
-        if rate > 0:
-            seek_event = gst.event_new_seek(rate,
-                    gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, position,
-                    gst.SEEK_TYPE_NONE, 0)
-        else:
-            seek_event = gst.event_new_seek(rate,
-                    gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, 0,
-                    gst.SEEK_TYPE_SET, position)
-
-        if seek_event:
-            self._player.send_event(seek_event)
-            gst.info("rate set to %s" % rate)
-        else:
-            gst.warining("change rate failed")
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    player = Player(args[1], 3.0)
-    player.run()
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/gst-trick-mode-looping-2.py b/gst-trick-mode-looping-2.py
deleted file mode 100755 (executable)
index 920677d..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-
-# Get a test sample with:
-# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
-
-import sys
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-
-class Player:
-    def __init__(self, filename, rate):
-        self._filename = filename
-        self._rate = rate
-
-        self._player = gst.element_factory_make("playbin2", "player")
-        self._player.set_property("uri", filename)
-        self._player.connect("about-to-finish", self.on_about_to_finish)
-
-        bus = self._player.get_bus()
-        bus.add_signal_watch()
-        bus.connect('message::state-changed', self.on_state_changed)
-
-    def run(self):
-        self._player.set_state(gst.STATE_PLAYING)
-        loop = gobject.MainLoop()
-        loop.run()
-
-    def on_about_to_finish(self, player):
-        sys.stderr.write(".")
-        player.set_property("uri", self._filename)
-
-        # XXX Ater the first iteration of the loop the playback rate is
-        # reset to normal. Do I need to re-set the rate here?
-
-        # If I uncomment the following line, the player hangs:
-        #self.set_rate(self._date)
-
-        # And it hangs also if I set the seek_event manually using position=0:
-        #seek_event = gst.event_new_seek(self._rate,
-        #        gst.FORMAT_TIME,
-        #        gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-        #        gst.SEEK_TYPE_SET, 0,
-        #        gst.SEEK_TYPE_NONE, 0)
-        #self._player.send_event(seek_event)
-
-    def on_state_changed(self, bus, msg):
-        if msg.src != self._player:
-            return
-
-        print 'on_state_changed'
-        old_state, new_state, pending = msg.parse_state_changed()
-        print "%s -> %s" % (old_state, new_state)
-        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
-            self.set_rate(self._rate)
-
-    def set_rate(self, rate):
-        self._rate = rate
-        try:
-            position, format = self._player.query_position(gst.FORMAT_TIME)
-        except:
-            position = 0
-
-        # Create the seek event
-        if rate > 0:
-            seek_event = gst.event_new_seek(rate,
-                    gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, position,
-                    gst.SEEK_TYPE_NONE, 0)
-        else:
-            seek_event = gst.event_new_seek(rate,
-                    gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, 0,
-                    gst.SEEK_TYPE_SET, position)
-
-        if seek_event:
-            self._player.send_event(seek_event)
-            gst.info("rate set to %s" % rate)
-        else:
-            gst.warining("change rate failed")
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    player = Player(args[1], 3.0)
-    player.run()
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/gst-trick-mode-looping-3.py b/gst-trick-mode-looping-3.py
deleted file mode 100755 (executable)
index 94b99af..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-
-# Get a test sample with:
-# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
-
-import sys
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-
-class Player:
-    def __init__(self, filename, rate):
-        self._filename = filename
-        self._rate = rate
-
-        self._player = gst.element_factory_make("playbin2", "player")
-        self._player.set_property("uri", filename)
-
-        bus = self._player.get_bus()
-        bus.add_signal_watch()
-        bus.connect('message::state-changed', self.on_state_changed)
-        bus.connect('message::segment-done', self.on_segment_done)
-
-    def run(self):
-        self._player.set_state(gst.STATE_PLAYING)
-        loop = gobject.MainLoop()
-        loop.run()
-
-    def on_segment_done(self, bus, msg):
-        self._player.seek(self._rate, gst.FORMAT_TIME,
-                gst.SEEK_FLAG_SEGMENT | gst.SEEK_FLAG_SKIP | gst.SEEK_FLAG_ACCURATE,
-                gst.SEEK_TYPE_SET, 0,
-                gst.SEEK_TYPE_END, 0)
-
-    def on_state_changed(self, bus, msg):
-        if msg.src != self._player:
-            return
-
-        print 'on_state_changed'
-        old_state, new_state, pending = msg.parse_state_changed()
-        print "%s -> %s" % (old_state, new_state)
-        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
-            self.set_rate(self._rate)
-
-    def set_rate(self, rate):
-        self._rate = rate
-
-        if rate == 0:
-            self._player.set_state(gst.STATE_PAUSED)
-        else:
-            self._player.set_state(gst.STATE_PLAYING)
-            self._player.seek(self._rate, gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_SEGMENT | gst.SEEK_FLAG_SKIP | gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, 0,
-                    gst.SEEK_TYPE_END, 0)
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    player = Player(args[1], 3.0)
-    player.run()
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/gst-trick-mode.py b/gst-trick-mode.py
deleted file mode 100755 (executable)
index a4e063f..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-
-# Get a test sample with:
-# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
-
-import sys
-
-import gobject
-gobject.threads_init()
-
-import gst
-
-
-class Player:
-    def __init__(self, filename, rate):
-        self._filename = filename
-        self._rate = rate
-
-        self._player = gst.element_factory_make("playbin2", "player")
-        self._player.set_property("uri", filename)
-
-        bus = self._player.get_bus()
-        bus.add_signal_watch()
-        bus.connect('message::state-changed', self.on_state_changed)
-
-    def run(self):
-        self._player.set_state(gst.STATE_PLAYING)
-        loop = gobject.MainLoop()
-        loop.run()
-
-    def on_state_changed(self, bus, msg):
-        if msg.src != self._player:
-            return
-
-        print 'on_state_changed'
-        old_state, new_state, pending = msg.parse_state_changed()
-        print "%s -> %s" % (old_state, new_state)
-        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
-            self.set_rate(self._rate)
-
-    def set_rate(self, rate):
-        self._rate = rate
-        try:
-            position, format = self._player.query_position(gst.FORMAT_TIME)
-        except:
-            position = 0
-
-        # Create the seek event
-        if rate > 0:
-            seek_event = gst.event_new_seek(rate,
-                    gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, position,
-                    gst.SEEK_TYPE_NONE, 0)
-        else:
-            seek_event = gst.event_new_seek(rate,
-                    gst.FORMAT_TIME,
-                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
-                    gst.SEEK_TYPE_SET, 0,
-                    gst.SEEK_TYPE_SET, position)
-
-        if seek_event:
-            self._player.send_event(seek_event)
-            gst.info("rate set to %s" % rate)
-        else:
-            gst.warining("change rate failed")
-
-
-def main(args):
-    def usage():
-        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
-
-    if len(args) != 2:
-        usage()
-        sys.exit(1)
-
-    if not gst.uri_is_valid(args[1]):
-        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
-        sys.exit(1)
-
-    player = Player(args[1], 3.0)
-    player.run()
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/python/gst-custom-player.py b/python/gst-custom-player.py
new file mode 100755 (executable)
index 0000000..cbeace2
--- /dev/null
@@ -0,0 +1,209 @@
+#!/usr/bin/env python
+
+# Simple media player with GStreamer
+#
+# Copyright (C) 2013  Antonio Ospite <ospite@studenti.unina.it>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# References:
+# http://pygstdocs.berlios.de/pygst-reference
+# https://core.fluendo.com/gstreamer/svn/trunk/gst-fluendo-gdlsink/test/ismdplay.py
+
+import sys
+import os
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+# The player window will have a fixed width and height.
+# This is just to demonstrate the use of capabilities.
+WIDTH = 640
+HEIGHT = 300
+
+
+class CustomVideoBin(gst.Bin):
+    def __init__(self):
+        gst.Bin.__init__(self, 'CustomVideoBin')
+
+        queue = gst.element_factory_make('queue', 'vqueue')
+        self.add(queue)
+
+        rescale = gst.element_factory_make("videoscale", "rescale")
+        self.add(rescale)
+
+        caps = gst.Caps("video/x-raw-yuv,format=(fourcc)AYUV,width=%d,height=%d,pixel-aspect-ratio=1/1" % (WIDTH, HEIGHT))
+        capsfilter = gst.element_factory_make("capsfilter", "filter")
+        capsfilter.set_property("caps", caps)
+        self.add(capsfilter)
+
+        colorspace = gst.element_factory_make("colorspace", "colorspace")
+        self.add(colorspace)
+
+        videosink = gst.element_factory_make("autovideosink", "vidoesink")
+        self.add(videosink)
+
+        gst.element_link_many(queue, rescale, capsfilter, colorspace, videosink)
+        sink = queue.get_pad('sink')
+        self.add_pad(gst.GhostPad('sink', sink))
+
+
+class CustomAudioBin(gst.Bin):
+    def __init__(self):
+        gst.Bin.__init__(self, 'CustomAudioBin')
+
+        queue = gst.element_factory_make('queue', 'aqueue')
+        self.add(queue)
+
+        audioconvert = gst.element_factory_make("audioconvert", "audioconverter")
+        self.add(audioconvert)
+
+        audiosink = gst.element_factory_make("autoaudiosink", "audiosink")
+        self.add(audiosink)
+
+        gst.element_link_many(queue, audioconvert, audiosink)
+        sink = queue.get_pad('sink')
+        self.add_pad(gst.GhostPad('sink', sink))
+
+
+class CustomPlayBin(gst.Pipeline):
+    __gproperties__ = {
+        'source': (gst.Element, "source", "Source element", gobject.PARAM_READABLE)
+    }
+
+    def __init__(self, uri=None):
+        gst.Pipeline.__init__(self, 'CustomPlayBin')
+
+        self._uri = uri
+
+        self._playbin = gst.element_factory_make("playbin2", "playbin")
+        self.add(self._playbin)
+
+        self._playbin.set_property("uri", self._uri)
+        self._playbin.set_property("video-sink", CustomVideoBin())
+        self._playbin.set_property("audio-sink", CustomAudioBin())
+
+    def set_uri(self, uri):
+        self._uri = uri
+        self._playbin.set_property("uri", self._uri)
+
+
+class GstPlayer:
+    def __init__(self):
+
+        # The user can require some action at End Of Stream
+        self.eos_cb = None
+
+        self.pipeline = CustomPlayBin()
+
+        bus = self.pipeline.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::eos', self.on_eos)
+        bus.connect('message::tag', self.on_tag)
+        bus.connect('message::error', self.on_error)
+        bus.connect('message::state-changed', self.on_state_changed)
+
+    def on_eos(self, bus, msg):
+        print 'on_eos'
+        self.stop()
+        if self.eos_cb:
+            self.eos_cb()
+
+    def on_tag(self, bus, msg):
+        print 'on_tag:'
+        taglist = msg.parse_tag()
+        for key in taglist.keys():
+            print '\t%s = %s' % (key, taglist[key])
+
+    def on_error(self, bus, msg):
+        print 'on_error'
+        error, debug = msg.parse_error()
+        print "Error: %s" % error, debug
+        self.stop()
+
+    def on_state_changed(self, bus, msg):
+        print 'on_state_changed'
+        if msg.src != self.pipeline:
+            return
+
+        old_state, new_state, pending = msg.parse_state_changed()
+
+    def set_location(self, location):
+        self.pipeline.set_uri(location)
+
+    def play(self):
+        self.pipeline.set_state(gst.STATE_PLAYING)
+
+    def pause(self):
+        self.pipeline.set_state(gst.STATE_PAUSED)
+
+    def stop(self):
+        self.pipeline.set_state(gst.STATE_NULL)
+
+
+class PlayerTUI():
+    def __init__(self, location):
+
+        self.player = GstPlayer()
+        self.player.eos_cb = self.quit
+
+        self.mainloop = gobject.MainLoop()
+
+        self.player.set_location(location)
+        self.player.play()
+
+        gobject.io_add_watch(sys.stdin, gobject.IO_IN, self.on_stdin)
+
+        try:
+            self.mainloop.run()
+        except KeyboardInterrupt:
+            self.quit()
+
+    def on_stdin(self, fd, event):
+        # The user has to send a newline fo this to go on
+        c = os.read(fd.fileno(), 1)
+
+        if c == "q":
+            self.quit()
+        elif c == "s":
+            self.player.pause()
+        elif c == "r":
+            self.player.play()
+
+        return True
+
+    def quit(self):
+        self.player.stop()
+        self.player = None
+        self.mainloop.quit()
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    tui = PlayerTUI(args[1])
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/python/gst-looping-video-1.py b/python/gst-looping-video-1.py
new file mode 100755 (executable)
index 0000000..9886abe
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+# Get a test sample with:
+# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
+
+import sys
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+
+class Player:
+    def __init__(self, filename):
+        self._filename = filename
+
+        self._player = gst.element_factory_make("playbin2", "player")
+        self._player.set_property("uri", filename)
+
+        bus = self._player.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::eos', self.on_eos)
+
+    def run(self):
+        self._player.set_state(gst.STATE_PLAYING)
+        loop = gobject.MainLoop()
+        loop.run()
+
+    def on_eos(self, bus, msg):
+        sys.stderr.write(".")
+        self._player.seek_simple(gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, 0)
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    player = Player(args[1])
+    player.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/python/gst-looping-video-2.py b/python/gst-looping-video-2.py
new file mode 100755 (executable)
index 0000000..eabb7a4
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+# Get a test sample with:
+# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
+
+import sys
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+
+class Player:
+    def __init__(self, filename):
+        self._filename = filename
+
+        self._player = gst.element_factory_make("playbin2", "player")
+        self._player.set_property("uri", filename)
+        self._player.connect("about-to-finish", self.on_about_to_finish)
+
+    def run(self):
+        self._player.set_state(gst.STATE_PLAYING)
+        loop = gobject.MainLoop()
+        loop.run()
+
+    def on_about_to_finish(self, player):
+        sys.stderr.write(".")
+        player.set_property("uri", self._filename)
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    player = Player(args[1])
+    player.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/python/gst-trick-mode-looping-1.py b/python/gst-trick-mode-looping-1.py
new file mode 100755 (executable)
index 0000000..fe00556
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+# Get a test sample with:
+# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
+
+import sys
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+
+class Player:
+    def __init__(self, filename, rate):
+        self._filename = filename
+        self._rate = rate
+
+        self._player = gst.element_factory_make("playbin2", "player")
+        self._player.set_property("uri", filename)
+
+        bus = self._player.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::eos', self.on_eos)
+        bus.connect('message::state-changed', self.on_state_changed)
+
+    def run(self):
+        self._player.set_state(gst.STATE_PLAYING)
+        loop = gobject.MainLoop()
+        loop.run()
+
+    def on_eos(self, bus, msg):
+        sys.stderr.write(".")
+        self._player.set_state(gst.STATE_PLAYING)
+        seek_event = gst.event_new_seek(self._rate,
+                gst.FORMAT_TIME,
+                gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                gst.SEEK_TYPE_SET, 0,
+                gst.SEEK_TYPE_NONE, 0)
+        self._player.send_event(seek_event)
+
+    def on_state_changed(self, bus, msg):
+        if msg.src != self._player:
+            return
+
+        print 'on_state_changed'
+        old_state, new_state, pending = msg.parse_state_changed()
+        print "%s -> %s" % (old_state, new_state)
+        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
+            self.set_rate(self._rate)
+
+    def set_rate(self, rate):
+        self._rate = rate
+        try:
+            position, format = self._player.query_position(gst.FORMAT_TIME)
+        except:
+            position = 0
+
+        # Create the seek event
+        if rate > 0:
+            seek_event = gst.event_new_seek(rate,
+                    gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, position,
+                    gst.SEEK_TYPE_NONE, 0)
+        else:
+            seek_event = gst.event_new_seek(rate,
+                    gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, 0,
+                    gst.SEEK_TYPE_SET, position)
+
+        if seek_event:
+            self._player.send_event(seek_event)
+            gst.info("rate set to %s" % rate)
+        else:
+            gst.warining("change rate failed")
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    player = Player(args[1], 3.0)
+    player.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/python/gst-trick-mode-looping-2.py b/python/gst-trick-mode-looping-2.py
new file mode 100755 (executable)
index 0000000..920677d
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+# Get a test sample with:
+# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
+
+import sys
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+
+class Player:
+    def __init__(self, filename, rate):
+        self._filename = filename
+        self._rate = rate
+
+        self._player = gst.element_factory_make("playbin2", "player")
+        self._player.set_property("uri", filename)
+        self._player.connect("about-to-finish", self.on_about_to_finish)
+
+        bus = self._player.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::state-changed', self.on_state_changed)
+
+    def run(self):
+        self._player.set_state(gst.STATE_PLAYING)
+        loop = gobject.MainLoop()
+        loop.run()
+
+    def on_about_to_finish(self, player):
+        sys.stderr.write(".")
+        player.set_property("uri", self._filename)
+
+        # XXX Ater the first iteration of the loop the playback rate is
+        # reset to normal. Do I need to re-set the rate here?
+
+        # If I uncomment the following line, the player hangs:
+        #self.set_rate(self._date)
+
+        # And it hangs also if I set the seek_event manually using position=0:
+        #seek_event = gst.event_new_seek(self._rate,
+        #        gst.FORMAT_TIME,
+        #        gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+        #        gst.SEEK_TYPE_SET, 0,
+        #        gst.SEEK_TYPE_NONE, 0)
+        #self._player.send_event(seek_event)
+
+    def on_state_changed(self, bus, msg):
+        if msg.src != self._player:
+            return
+
+        print 'on_state_changed'
+        old_state, new_state, pending = msg.parse_state_changed()
+        print "%s -> %s" % (old_state, new_state)
+        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
+            self.set_rate(self._rate)
+
+    def set_rate(self, rate):
+        self._rate = rate
+        try:
+            position, format = self._player.query_position(gst.FORMAT_TIME)
+        except:
+            position = 0
+
+        # Create the seek event
+        if rate > 0:
+            seek_event = gst.event_new_seek(rate,
+                    gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, position,
+                    gst.SEEK_TYPE_NONE, 0)
+        else:
+            seek_event = gst.event_new_seek(rate,
+                    gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, 0,
+                    gst.SEEK_TYPE_SET, position)
+
+        if seek_event:
+            self._player.send_event(seek_event)
+            gst.info("rate set to %s" % rate)
+        else:
+            gst.warining("change rate failed")
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    player = Player(args[1], 3.0)
+    player.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/python/gst-trick-mode-looping-3.py b/python/gst-trick-mode-looping-3.py
new file mode 100755 (executable)
index 0000000..94b99af
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+# Get a test sample with:
+# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
+
+import sys
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+
+class Player:
+    def __init__(self, filename, rate):
+        self._filename = filename
+        self._rate = rate
+
+        self._player = gst.element_factory_make("playbin2", "player")
+        self._player.set_property("uri", filename)
+
+        bus = self._player.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::state-changed', self.on_state_changed)
+        bus.connect('message::segment-done', self.on_segment_done)
+
+    def run(self):
+        self._player.set_state(gst.STATE_PLAYING)
+        loop = gobject.MainLoop()
+        loop.run()
+
+    def on_segment_done(self, bus, msg):
+        self._player.seek(self._rate, gst.FORMAT_TIME,
+                gst.SEEK_FLAG_SEGMENT | gst.SEEK_FLAG_SKIP | gst.SEEK_FLAG_ACCURATE,
+                gst.SEEK_TYPE_SET, 0,
+                gst.SEEK_TYPE_END, 0)
+
+    def on_state_changed(self, bus, msg):
+        if msg.src != self._player:
+            return
+
+        print 'on_state_changed'
+        old_state, new_state, pending = msg.parse_state_changed()
+        print "%s -> %s" % (old_state, new_state)
+        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
+            self.set_rate(self._rate)
+
+    def set_rate(self, rate):
+        self._rate = rate
+
+        if rate == 0:
+            self._player.set_state(gst.STATE_PAUSED)
+        else:
+            self._player.set_state(gst.STATE_PLAYING)
+            self._player.seek(self._rate, gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_SEGMENT | gst.SEEK_FLAG_SKIP | gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, 0,
+                    gst.SEEK_TYPE_END, 0)
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    player = Player(args[1], 3.0)
+    player.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
diff --git a/python/gst-trick-mode.py b/python/gst-trick-mode.py
new file mode 100755 (executable)
index 0000000..a4e063f
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+
+# Get a test sample with:
+# youtube-dl -t http://www.youtube.com/watch?v=yWa-YXiSk2Y
+
+import sys
+
+import gobject
+gobject.threads_init()
+
+import gst
+
+
+class Player:
+    def __init__(self, filename, rate):
+        self._filename = filename
+        self._rate = rate
+
+        self._player = gst.element_factory_make("playbin2", "player")
+        self._player.set_property("uri", filename)
+
+        bus = self._player.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::state-changed', self.on_state_changed)
+
+    def run(self):
+        self._player.set_state(gst.STATE_PLAYING)
+        loop = gobject.MainLoop()
+        loop.run()
+
+    def on_state_changed(self, bus, msg):
+        if msg.src != self._player:
+            return
+
+        print 'on_state_changed'
+        old_state, new_state, pending = msg.parse_state_changed()
+        print "%s -> %s" % (old_state, new_state)
+        if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED:
+            self.set_rate(self._rate)
+
+    def set_rate(self, rate):
+        self._rate = rate
+        try:
+            position, format = self._player.query_position(gst.FORMAT_TIME)
+        except:
+            position = 0
+
+        # Create the seek event
+        if rate > 0:
+            seek_event = gst.event_new_seek(rate,
+                    gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, position,
+                    gst.SEEK_TYPE_NONE, 0)
+        else:
+            seek_event = gst.event_new_seek(rate,
+                    gst.FORMAT_TIME,
+                    gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
+                    gst.SEEK_TYPE_SET, 0,
+                    gst.SEEK_TYPE_SET, position)
+
+        if seek_event:
+            self._player.send_event(seek_event)
+            gst.info("rate set to %s" % rate)
+        else:
+            gst.warining("change rate failed")
+
+
+def main(args):
+    def usage():
+        sys.stdout.write("usage: %s <URI-OF-MEDIA-FILE>\n" % args[0])
+
+    if len(args) != 2:
+        usage()
+        sys.exit(1)
+
+    if not gst.uri_is_valid(args[1]):
+        sys.stderr.write("Error: Invalid URI: %s\n" % args[1])
+        sys.exit(1)
+
+    player = Player(args[1], 3.0)
+    player.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))