Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- import sys, os
- import pygtk, gtk
- import gobject
- import pygst
- pygst.require("0.10")
- import gst
- class GTK_Main:
- def __init__(self):
- window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- window.set_title("Webcam-Viewer")
- window.set_default_size(500, 400)
- window.connect("destroy", gtk.main_quit, "WM destroy")
- vbox = gtk.VBox()
- window.add(vbox)
- self.movie_window = gtk.DrawingArea()
- vbox.add(self.movie_window)
- hbox = gtk.HBox()
- vbox.pack_start(hbox, False)
- hbox.set_border_width(10)
- hbox.pack_start(gtk.Label())
- self.button = gtk.Button("Start")
- self.button.connect("clicked", self.start_stop)
- hbox.pack_start(self.button, False)
- self.button2 = gtk.Button("Quit")
- self.button2.connect("clicked", self.exit)
- hbox.pack_start(self.button2, False)
- hbox.add(gtk.Label())
- window.show_all()
- # Set up the gstreamer pipeline
- self.full_pipe = gst.Pipeline("full_pipe")
- #########################################################
- # Play/view path bin
- #########################################################
- self.play_bin = gst.Bin("play_bin")
- # Video source
- self.autov4l2src = gst.element_factory_make("v4l2src", "autov4l2src")
- # for other webcam self.autov4l2src = gst.element_factory_make("v4lsrc", "autov4l2src")
- self.play_bin.add(self.autov4l2src)
- # Scaler - Not really used right now though
- self.scaler = gst.element_factory_make("videoscale", "scaler")
- self.play_bin.add(self.scaler)
- self.autov4l2src.link(self.scaler)
- #cn_new = gst.caps_from_string('video/x-raw-yuv, format=(fourcc)I420, width=(int)352, height=(int)288, framerate=(fraction)9/1')
- cn_new = gst.caps_new_any()
- # Tee element
- self.tee = gst.element_factory_make("tee", "tee0")
- self.play_bin.add(self.tee)
- self.scaler.link(self.tee, cn_new)
- # Queue for play path
- self.play_queue = gst.element_factory_make("queue", "play_queue")
- self.play_bin.add(self.play_queue)
- self.tee.link(self.play_queue)
- # Element for displaying video
- self.sink = gst.element_factory_make("autovideosink", "sink")
- self.play_bin.add(self.sink)
- self.play_queue.link(self.sink)
- # Encode path queue, that will also be the GhostPad for the play Bin
- self.enc_queue = gst.element_factory_make("queue", "enc_queue")
- self.play_bin.add(self.enc_queue)
- self.tee.link(self.enc_queue)
- # Main ghost pad for the play Bin
- self.play_bin_src_gp = gst.GhostPad("src", self.enc_queue.get_pad('src'))
- self.play_bin.add_pad(self.play_bin_src_gp)
- #########################################################
- # Encode path bin
- #########################################################
- self.enc_bin = gst.Bin("enc_bin")
- # Theora encoder element, will also be the sink ghost pad for the encode path
- self.bitstream = gst.element_factory_make("theoraenc", "video_bitstream")
- self.enc_bin.add(self.bitstream)
- self.enc_bin_sink_gp = gst.GhostPad("src", self.bitstream.get_pad('sink'))
- self.enc_bin.add_pad(self.enc_bin_sink_gp)
- # Ogg container element. The video stream (and eventually audio) will be muxed into this container
- self.container = gst.element_factory_make("oggmux", "video_container")
- self.enc_bin.add(self.container)
- self.bitstream.link(self.container)
- # File sink element where the ogg container file is written
- self.file = gst.element_factory_make("filesink", "outputfile")
- self.enc_bin.add(self.file)
- self.file.set_property("location", "testoutput.ogv")
- self.container.link(self.file)
- # Add the play and enc Bin elements to the pipeline
- self.full_pipe.add(self.play_bin)
- #self.full_pipe.add(self.enc_bin)
- #self.play_bin.link(self.enc_bin)
- bus = self.full_pipe.get_bus()
- bus.add_signal_watch()
- bus.enable_sync_message_emission()
- bus.connect("message", self.on_message)
- bus.connect("sync-message::element", self.on_sync_message)
- self.full_pipe.set_state(gst.STATE_PLAYING)
- # def encodeAddLinkCb(self, ghost, blocked):
- # if blocked:
- # self.full_pipe.add(self.enc_bin)
- # self.play_bin.link(self.enc_bin)
- # self.tee.get_pad('sink').set_blocked(False)
- #
- #
- def start_stop(self, w):
- if self.button.get_label() == "Start":
- # self.tee.get_pad('sink').set_blocked_async(True, self.encodeAddLinkCb)
- self.button.set_label("Stop")
- self.tee.get_pad('sink').set_blocked(True)
- self.full_pipe.add(self.enc_bin)
- self.play_bin.link(self.enc_bin)
- synced = self.enc_bin.sync_state_with_parent()
- if not synced:
- # bail
- gtk.main_quit()
- pass
- self.tee.get_pad('sink').set_blocked(False)
- else:
- #self.full_pipe.set_state(gst.STATE_NULL)
- self.tee.get_pad('sink').set_blocked(True)
- self.play_bin.unlink(self.enc_bin)
- self.full_pipe.remove(self.enc_bin)
- self.tee.get_pad('sink').set_blocked(False)
- #self.full_pipe.set_state(gst.STATE_PLAYING)
- self.button.set_label("Start")
- def exit(self, widget, data=None):
- gtk.main_quit()
- def on_message(self, bus, message):
- t = message.type
- if t == gst.MESSAGE_EOS:
- self.full_pipe.set_state(gst.STATE_NULL)
- self.button.set_label("Start")
- elif t == gst.MESSAGE_ERROR:
- err, debug = message.parse_error()
- print "Error: %s" % err, debug
- self.full_pipe.set_state(gst.STATE_NULL)
- self.button.set_label("Start")
- def on_sync_message(self, bus, message):
- if message.structure is None:
- return
- message_name = message.structure.get_name()
- if message_name == "prepare-xwindow-id":
- # Assign the viewport
- imagesink = message.src
- imagesink.set_property("force-aspect-ratio", True)
- imagesink.set_xwindow_id(self.movie_window.window.xid)
- GTK_Main()
- gtk.gdk.threads_init()
- gtk.main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement