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
)