2 # GdkX11 to get access to xid, GstVideo to get access to set_window_handle
4 gi
.require_version('Gtk', '3.0')
5 gi
.require_version('Gst', '1.0')
6 gi
.require_version('GstVideo', '1.0')
7 from gi
.repository
import Gtk
, Gst
, GstVideo
, GdkX11
10 settings
= Gtk
.Settings
.get_default()
11 settings
.props
.gtk_button_images
= True
16 # Create gui bits and bobs
18 self
.mainwindow
= Gtk
.Builder()
19 self
.mainwindow
.add_from_file("stream.glade")
22 "on_stream_clicked" : self
.OnStream
,
23 "on_stop_clicked" : self
.OnStop
,
24 "on_quit_clicked" : self
.OnQuit
,
27 self
.mainwindow
.connect_signals(signals
)
29 # Create GStreamer bits and bobs
31 # Initiate the pipeline
33 self
.pipeline
= Gst
.Pipeline("mypipeline")
35 # Add our video source, the first v4l2 device we can find
36 self
.videosrc
= Gst
.ElementFactory
.make("v4l2src", "videosource")
37 self
.pipeline
.add(self
.videosrc
)
39 # Add a jpeg decoder to force the v4l2src to output jpeg data
40 self
.jpegdec
= Gst
.ElementFactory
.make("jpegdec", "jpegdec")
41 self
.pipeline
.add(self
.jpegdec
)
42 self
.videosrc
.link(self
.jpegdec
)
44 # Add some video convert magic
45 self
.videoconvert
= Gst
.ElementFactory
.make("videoconvert", "videoconvert")
46 self
.pipeline
.add(self
.videoconvert
)
47 self
.jpegdec
.link(self
.videoconvert
)
49 # Add a videosink element to the pipeline
50 self
.videosink
= Gst
.ElementFactory
.make("autovideosink", "videosink")
51 self
.videosink
.set_property("sync", False)
52 self
.pipeline
.add(self
.videosink
)
53 self
.videoconvert
.link(self
.videosink
)
56 self
.pipeline
.set_state(Gst
.State
.PLAYING
)
58 # Set up a bus to our pipeline to get notified when the video is ready
59 self
.bus
= self
.pipeline
.get_bus()
60 self
.bus
.enable_sync_message_emission()
61 self
.bus
.connect("sync-message::element", self
.OnSyncElement
)
63 # Summon the window and connect the window's close button to quit
64 self
.window
= self
.mainwindow
.get_object("mainwindow")
65 self
.window
.connect("delete-event", Gtk
.main_quit
)
66 self
.window
.show_all()
68 # Get window ID of the viewport widget from the GUI
69 self
.win_id
= self
.mainwindow
.get_object("viewport").get_window().get_xid()
72 # When we get a message that video is ready to display, set the
73 # correct window id to hook it to our viewport
74 def OnSyncElement(self
, bus
, message
):
75 if message
.get_structure().get_name() == "prepare-window-handle":
76 print "prepare-window-handle"
77 message
.src
.set_window_handle(self
.win_id
)
79 def OnStream(self
, widget
):
81 self
.pipeline
.set_state(Gst
.State
.PLAYING
)
83 def OnStop(self
, widget
):
85 self
.pipeline
.set_state(Gst
.State
.READY
)
87 def OnQuit(self
, widget
):
91 # Workaround to get Ctrl+C to terminate from command line
92 # ref: https://bugzilla.gnome.org/show_bug.cgi?id=622084#c12
93 signal
.signal(signal
.SIGINT
, signal
.SIG_DFL
)