2 # Let's see if we can get a viewport AND audio working, combining ex. 2 and 3
4 # GdkX11 to get access to xid, GstVideo to get access to set_window_handle
6 gi
.require_version('Gtk', '3.0')
7 gi
.require_version('Gst', '1.0')
8 gi
.require_version('GstVideo', '1.0')
9 from gi
.repository
import Gtk
, Gst
, GdkX11
, GstVideo
15 # Create gui bits and bobs
17 self
.mainwindow
= Gtk
.Builder()
18 self
.mainwindow
.add_from_file("example3.glade")
21 "on_play_clicked" : self
.OnPlay
,
22 "on_stop_clicked" : self
.OnStop
,
23 "on_quit_clicked" : self
.OnQuit
,
26 self
.mainwindow
.connect_signals(signals
)
28 # Create GStreamer bits and bobs
30 # Initiate the pipeline
32 self
.pipeline
= Gst
.Pipeline()
34 # Add a videotestsrc element to the pipeline, set it to pattern "snow."
35 self
.videotestsrc
= Gst
.ElementFactory
.make("videotestsrc", "videosource")
36 self
.videotestsrc
.set_property("pattern", "snow")
37 self
.pipeline
.add(self
.videotestsrc
)
39 # Add a capsfilter that we want to apply to our videotestsrc
40 self
.videotestcaps
= Gst
.ElementFactory
.make("capsfilter", "videotestcaps")
41 self
.videotestcaps
.set_property("caps",Gst
.Caps
.from_string("video/x-raw,width=640,height=480"))
42 self
.pipeline
.add(self
.videotestcaps
)
44 # Link the capsfilter to the videotestsrc
45 self
.videotestsrc
.link(self
.videotestcaps
)
47 # Add a videosink element to the pipeline
48 self
.videosink
= Gst
.ElementFactory
.make("autovideosink", "videosink")
49 self
.pipeline
.add(self
.videosink
)
51 # Link the already linked videotestcaps to the sink
52 self
.videotestcaps
.link(self
.videosink
)
54 # Add an audiotestsrc element to the pipeline
55 self
.audiotestsrc
= Gst
.ElementFactory
.make("audiotestsrc", "audio")
56 self
.audiotestsrc
.set_property("freq", 800)
57 self
.pipeline
.add(self
.audiotestsrc
)
59 # Add a pulsesink element to the pipeline
60 self
.pulsesink
= Gst
.ElementFactory
.make("pulsesink", "sink")
61 self
.pipeline
.add(self
.pulsesink
)
63 # Link the two elements together
64 self
.audiotestsrc
.link(self
.pulsesink
)
66 # Set up a bus to our pipeline to get notified when the video is ready
67 self
.bus
= self
.pipeline
.get_bus()
68 self
.bus
.enable_sync_message_emission()
69 self
.bus
.connect("sync-message::element", self
.OnSyncElement
)
71 # Summon the window and connect the window's close button to quit
72 self
.window
= self
.mainwindow
.get_object("mainwindow")
73 self
.window
.connect("delete-event", Gtk
.main_quit
)
74 self
.window
.show_all()
76 # Get window ID of the viewport widget from the GUI
77 self
.win_id
= self
.mainwindow
.get_object("viewport").get_window().get_xid()
80 # When we get a message that video is ready to display, set the
81 # correct window id to hook it to our viewport
82 def OnSyncElement(self
, bus
, message
):
83 if message
.get_structure().get_name() == "prepare-window-handle":
84 print("prepare-window-handle")
85 message
.src
.set_window_handle(self
.win_id
)
87 def OnPlay(self
, widget
):
89 self
.pipeline
.set_state(Gst
.State
.PLAYING
)
91 def OnStop(self
, widget
):
93 self
.pipeline
.set_state(Gst
.State
.READY
)
95 def OnQuit(self
, widget
):
99 # Workaround to get Ctrl+C to terminate from command line
100 # ref: https://bugzilla.gnome.org/show_bug.cgi?id=622084#c12
101 signal
.signal(signal
.SIGINT
, signal
.SIG_DFL
)