It's faster to set pipeline to READY than to NULL
[python-gstreamer-examples] / example3.py
1 #!/usr/bin/env python
2 # Let's see if we can get a viewport working, building on code from example2.py
3 # Some final info and updated code stolen from
4 # http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/video-player-1.0
5
6 # GdkX11 to get access to xid, GstVideo to get access to set_window_handle
7 import gi, signal
8 gi.require_version('Gtk', '3.0')
9 gi.require_version('Gst', '1.0')
10 gi.require_version('GstVideo', '1.0')
11 from gi.repository import Gtk, Gst, GdkX11, GstVideo
12
13 class Main:
14 def __init__(self):
15
16 # Create gui bits and bobs
17
18 self.mainwindow = Gtk.Builder()
19 self.mainwindow.add_from_file("example3.glade")
20
21 signals = {
22 "on_play_clicked" : self.OnPlay,
23 "on_stop_clicked" : self.OnStop,
24 "on_quit_clicked" : self.OnQuit,
25 }
26
27 self.mainwindow.connect_signals(signals)
28
29 # Create GStreamer bits and bobs
30
31 # Initiate the pipeline
32 Gst.init(None)
33 self.pipeline = Gst.Pipeline()
34
35 # Add a videotestsrc element to the pipeline, set it to pattern "snow."
36 self.videotestsrc = Gst.ElementFactory.make("videotestsrc", "videosource")
37 self.videotestsrc.set_property("pattern", "snow")
38 self.pipeline.add(self.videotestsrc)
39
40 # Add a capsfilter that we want to apply to our videotestsrc
41 self.videotestcaps = Gst.ElementFactory.make("capsfilter", "videotestcaps")
42 self.videotestcaps.set_property("caps",Gst.Caps.from_string("video/x-raw,width=640,height=480"))
43 self.pipeline.add(self.videotestcaps)
44
45 # Link the capsfilter to the videotestsrc
46 self.videotestsrc.link(self.videotestcaps)
47
48 # Add a videosink element to the pipeline
49 self.videosink = Gst.ElementFactory.make("autovideosink", "videosink")
50 self.pipeline.add(self.videosink)
51
52 # Link the already linked videotestcaps to the sink
53 self.videotestcaps.link(self.videosink)
54
55 # Set up a bus to our pipeline to get notified when the video is ready
56 self.bus = self.pipeline.get_bus()
57 self.bus.enable_sync_message_emission()
58 self.bus.connect("sync-message::element", self.OnSyncElement)
59
60 # Summon the window and connect the window's close button to quit
61 self.window = self.mainwindow.get_object("mainwindow")
62 self.window.connect("delete-event", Gtk.main_quit)
63 self.window.show_all()
64
65 # Get window ID of the viewport widget from the GUI
66 self.win_id = self.mainwindow.get_object("viewport").get_window().get_xid()
67
68
69 # When we get a message that video is ready to display, set the
70 # correct window id to hook it to our viewport
71 def OnSyncElement(self, bus, message):
72 if message.get_structure().get_name() == "prepare-window-handle":
73 print("prepare-window-handle")
74 message.src.set_window_handle(self.win_id)
75
76 def OnPlay(self, widget):
77 print("play")
78 self.pipeline.set_state(Gst.State.PLAYING)
79
80 def OnStop(self, widget):
81 print("stop")
82 self.pipeline.set_state(Gst.State.READY)
83
84 def OnQuit(self, widget):
85 print("quit")
86 Gtk.main_quit()
87
88 # Workaround to get Ctrl+C to terminate from command line
89 # ref: https://bugzilla.gnome.org/show_bug.cgi?id=622084#c12
90 signal.signal(signal.SIGINT, signal.SIG_DFL)
91
92 start = Main()
93 Gtk.main()