1. 使用gst-launch工具测试摄像头能否使用,在终端中键入命令如下:
gst-launch v4l2src ! autovideosink
这样就可以看到摄像头中的自己了,效果如下图所示:
2. 使用 python脚本实现
使用gst-launch工具,只是为了测试摄像头是否能用,以及所使用的管道。强烈建议在用具体的语言实现Gstreamer前,用gst-launch工具做一些简单的测试。
如果我们要做一个视频聊天的软件,我们更需要对输出的视频进行控制,比如在指定的GUI中显示,控制视频大小等等,下面的代码使用pyGTK实现的在一个window里面显示视频:
参考链接:http://pygstdocs.berlios.de/pygst-tutorial/webcam-viewer.html
部分代码略有改动
- import sys, os
- import pygtk, gtk, 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()
-
-
- self.player = gst.Pipeline("pipeline")
- src = gst.element_factory_make("v4l2src", "source")
- self.player.add(src)
- vsink = gst.element_factory_make("autovideosink", "video-sink")
- self.player.add(vsink)
- src.link(vsink)
- bus = self.player.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)
- def start_stop(self, w):
- if self.button.get_label() == "Start":
- self.button.set_label("Stop")
- self.player.set_state(gst.STATE_PLAYING)
- else:
- self.player.set_state(gst.STATE_NULL)
- 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.player.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.player.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":
-
- 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()
运行结果图如下:
使用wxPython重写代码如下:
-
- import sys, os
- import pygtk, gtk, gobject
- import pygst
- pygst.require("0.10")
- import gst
- import wx
-
- class Frame(wx.Frame):
-
- def __init__(self, parent=None, id=-1,
- pos=wx.DefaultPosition, title='Hello, wxPython!'):
- wx.Frame.__init__(self, parent, id, title, pos, (400,300))
-
- self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
- self.player = gst.parse_launch ("v4l2src ! autovideosink")
- bus = self.player.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.player.set_state(gst.STATE_PLAYING)
- def OnCloseWindow(self, event):
- self.player.set_state(gst.STATE_NULL);
- event.Skip()
- def on_message(self, bus, message):
- t = message.type
- if t == gst.MESSAGE_EOS:
- self.player.set_state(gst.STATE_NULL)
- elif t == gst.MESSAGE_ERROR:
- err, debug = message.parse_error()
- print "Error: %s" % err, debug
- self.player.set_state(gst.STATE_NULL)
- 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":
-
- imagesink = message.src
- imagesink.set_property("force-aspect-ratio", True)
- imagesink.set_xwindow_id(self.GetHandle())
- class App(wx.App):
-
- def OnInit(self):
- self.frame = Frame()
- self.frame.Show()
- self.SetTopWindow(self.frame)
- return True
- def main():
- gtk.gdk.threads_init()
- app = App()
- app.MainLoop()
- if __name__ == '__main__':
- main()
运行结果如下: