Add gst-playbin-switch.py
authorAntonio Ospite <ao2@ao2.it>
Fri, 2 Dec 2016 12:03:05 +0000 (13:03 +0100)
committerAntonio Ospite <ao2@ao2.it>
Fri, 2 Dec 2016 12:03:44 +0000 (13:03 +0100)
python/gst-playbin-switch.py [new file with mode: 0755]

diff --git a/python/gst-playbin-switch.py b/python/gst-playbin-switch.py
new file mode 100755 (executable)
index 0000000..5333f53
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+#
+# gst-playbin-switch - an example of switching file inputs with playbin
+#
+# Copyright (C) 2016  Antonio Ospite <ao2@ao2.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/>.
+
+import sys
+
+import gi
+gi.require_version('Gst', '1.0')
+from gi.repository import Gst
+Gst.init(None)
+
+from gi.repository import GObject
+GObject.threads_init()
+
+
+class Player:
+    def __init__(self):
+        self.loop = GObject.MainLoop()
+        self.pipeline = Gst.ElementFactory.make("playbin", "player")
+
+        files = ["sample_440hz.webm", "sample_880hz.webm"]
+        self.uris = [Gst.filename_to_uri(f) for f in files]
+        self.uri_index = 0
+        self.pipeline.set_property("uri", self.uris[self.uri_index])
+        self.pipeline.connect("about-to-finish", self.on_about_to_finish)
+
+        bus = self.pipeline.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::eos', self.on_eos)
+        bus.connect('message::error', self.on_error)
+        bus.connect('message::state-changed', self.on_state_changed)
+
+    def on_about_to_finish(self, playbin):
+        sys.stderr.write(".")
+        sys.stderr.flush()
+        playbin.set_property("uri", self.uris[self.uri_index])
+
+    def run(self):
+        self.pipeline.set_state(Gst.State.PLAYING)
+        self.loop.run()
+
+    def quit(self):
+        self.pipeline.set_state(Gst.State.NULL)
+        self.loop.quit()
+
+    def switch(self):
+        self.uri_index ^= 1
+        print("Next: %s" % self.uris[self.uri_index])
+
+        # Seek to the end of the stream, this will trigger the about-to-finish
+        # signal
+        seek_event = Gst.Event.new_seek(1.0,
+                                        Gst.Format.TIME,
+                                        Gst.SeekFlags.FLUSH,
+                                        Gst.SeekType.END, -1,
+                                        Gst.SeekType.NONE, 0)
+
+        self.pipeline.send_event(seek_event)
+
+    def on_eos(self, bus, msg):
+        self.quit()
+
+    def on_error(self, bus, msg):
+        (err, debug) = msg.parse_error()
+        print("Error: %s" % err)
+        print("Error: %s" % debug)
+        self.quit()
+
+    def on_state_changed(self, bus, msg):
+        if msg.src != self.pipeline:
+            return
+
+        old_state, new_state, pending = msg.parse_state_changed()
+        print("%s from %s to %s" % (msg.src.get_name(), old_state, new_state))
+
+
+def main():
+    player = Player()
+
+    def stdin_cb(source, condition):
+        source.readline()
+        player.switch()
+        return True
+
+    GObject.io_add_watch(sys.stdin, GObject.IO_IN, stdin_cb)
+
+    print("\nPress Enter to switch the source\n")
+    player.run()
+
+
+if __name__ == '__main__':
+    sys.exit(main())