使用Gtreamer获得摄像头数据并显示(Webcam streaming using Python--pyGTK, wxPython and Gstreamer)

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

部分代码略有改动

 

[python] view plain copy
  1. import sys, os  
  2. import pygtk, gtk, gobject  
  3. import pygst  
  4. pygst.require("0.10")  
  5. import gst  
  6. class GTK_Main:  
  7.     def __init__(self):  
  8.         window = gtk.Window(gtk.WINDOW_TOPLEVEL)  
  9.         window.set_title("Webcam-Viewer")  
  10.         window.set_default_size(500400)  
  11.         window.connect("destroy", gtk.main_quit, "WM destroy")  
  12.         vbox = gtk.VBox()  
  13.         window.add(vbox)  
  14.         self.movie_window = gtk.DrawingArea()  
  15.         vbox.add(self.movie_window)  
  16.         hbox = gtk.HBox()  
  17.         vbox.pack_start(hbox, False)  
  18.         hbox.set_border_width(10)  
  19.         hbox.pack_start(gtk.Label())  
  20.         self.button = gtk.Button("Start")  
  21.         self.button.connect("clicked"self.start_stop)  
  22.         hbox.pack_start(self.button, False)  
  23.         self.button2 = gtk.Button("Quit")  
  24.         self.button2.connect("clicked"self.exit)  
  25.         hbox.pack_start(self.button2, False)  
  26.         hbox.add(gtk.Label())  
  27.         window.show_all()  
  28.         # Set up the gstreamer pipeline  
  29.         #self.player = gst.parse_launch ("v4l2src ! autovideosink")  
  30.         self.player = gst.Pipeline("pipeline")  
  31.         src = gst.element_factory_make("v4l2src""source")  
  32.         self.player.add(src)  
  33.         vsink = gst.element_factory_make("autovideosink""video-sink")  
  34.         self.player.add(vsink)  
  35.         src.link(vsink)  
  36.         bus = self.player.get_bus()  
  37.         bus.add_signal_watch()  
  38.         bus.enable_sync_message_emission()  
  39.         bus.connect("message"self.on_message)  
  40.         bus.connect("sync-message::element"self.on_sync_message)  
  41.     def start_stop(self, w):  
  42.         if self.button.get_label() == "Start":  
  43.             self.button.set_label("Stop")  
  44.             self.player.set_state(gst.STATE_PLAYING)  
  45.         else:  
  46.             self.player.set_state(gst.STATE_NULL)  
  47.             self.button.set_label("Start")  
  48.     def exit(self, widget, data=None):  
  49.         gtk.main_quit()  
  50.     def on_message(self, bus, message):  
  51.         t = message.type  
  52.         if t == gst.MESSAGE_EOS:  
  53.             self.player.set_state(gst.STATE_NULL)  
  54.             self.button.set_label("Start")  
  55.         elif t == gst.MESSAGE_ERROR:  
  56.             err, debug = message.parse_error()  
  57.             print "Error: %s" % err, debug  
  58.             self.player.set_state(gst.STATE_NULL)  
  59.             self.button.set_label("Start")  
  60.     def on_sync_message(self, bus, message):  
  61.         if message.structure is None:  
  62.             return  
  63.         message_name = message.structure.get_name()  
  64.         if message_name == "prepare-xwindow-id":  
  65.             # Assign the viewport  
  66.             imagesink = message.src  
  67.             imagesink.set_property("force-aspect-ratio"True)  
  68.             imagesink.set_xwindow_id(self.movie_window.window.xid)  
  69. GTK_Main()  
  70. gtk.gdk.threads_init()  
  71. gtk.main()  

运行结果图如下:

 

使用wxPython重写代码如下:

[python] view plain copy
  1. """rewrite the serweb.py code with wxpython"""  
  2. import sys, os  
  3. import pygtk, gtk, gobject  
  4. import pygst  
  5. pygst.require("0.10")  
  6. import gst  
  7. import wx  
  8.   
  9. class Frame(wx.Frame):  
  10.     """Frame class that displays an image."""  
  11.     def __init__(self, parent=None, id=-1,  
  12.                  pos=wx.DefaultPosition, title='Hello, wxPython!'):  
  13.         wx.Frame.__init__(self, parent, id, title, pos, (400,300))  
  14.         #self.windows = wx.PaintDC(self)  
  15.         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)  
  16.         self.player = gst.parse_launch ("v4l2src ! autovideosink")  
  17.         bus = self.player.get_bus()  
  18.         bus.add_signal_watch()  
  19.         bus.enable_sync_message_emission()  
  20.         bus.connect("message"self.on_message)  
  21.         bus.connect("sync-message::element"self.on_sync_message)  
  22.         self.player.set_state(gst.STATE_PLAYING)  
  23.     def OnCloseWindow(self, event):  
  24.         self.player.set_state(gst.STATE_NULL);  
  25.         event.Skip()  
  26.     def on_message(self, bus, message):  
  27.         t = message.type  
  28.         if t == gst.MESSAGE_EOS:  
  29.             self.player.set_state(gst.STATE_NULL)  
  30.         elif t == gst.MESSAGE_ERROR:  
  31.             err, debug = message.parse_error()  
  32.             print "Error: %s" % err, debug  
  33.             self.player.set_state(gst.STATE_NULL)  
  34.     def on_sync_message(self, bus, message):  
  35.         if message.structure is None:  
  36.             return  
  37.         message_name = message.structure.get_name()  
  38.         if message_name == "prepare-xwindow-id":  
  39.             # Assign the viewport  
  40.             imagesink = message.src  
  41.             imagesink.set_property("force-aspect-ratio"True)  
  42.             imagesink.set_xwindow_id(self.GetHandle())  
  43. class App(wx.App):  
  44.     """Application class."""  
  45.     def OnInit(self):  
  46.         self.frame = Frame()  
  47.         self.frame.Show()  
  48.         self.SetTopWindow(self.frame)  
  49.         return True  
  50. def main():  
  51.     gtk.gdk.threads_init()  
  52.     app = App()  
  53.     app.MainLoop()  
  54. if __name__ == '__main__':  
  55.     main()  

运行结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值