Initial commit, not functional yet.
[autonomnom] / stream.py
1 #!/usr/bin/env python
2 # GdkX11 to get access to xid, GstVideo to get access to set_window_handle
3 import gi
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
8 import signal
9
10 settings = Gtk.Settings.get_default()
11 settings.props.gtk_button_images = True
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("stream.glade")
20
21 signals = {
22 "on_stream_clicked" : self.OnStream,
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("mypipeline")
34
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)
38
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)
43
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)
48
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)
54
55 # Start playing
56 self.pipeline.set_state(Gst.State.PLAYING)
57
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)
62
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()
67
68 # Get window ID of the viewport widget from the GUI
69 self.win_id = self.mainwindow.get_object("viewport").get_window().get_xid()
70
71
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)
78
79 def OnStream(self, widget):
80 print "stream"
81 self.pipeline.set_state(Gst.State.PLAYING)
82
83 def OnStop(self, widget):
84 print "stop"
85 self.pipeline.set_state(Gst.State.READY)
86
87 def OnQuit(self, widget):
88 print "quit"
89 Gtk.main_quit()
90
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)
94
95 start = Main()
96 Gtk.main()