4

我正在尝试使用 gstreamer 将来自网络摄像头的流保存为一系列图像。到目前为止,我已经编写了这段代码......

#!/usr/bin/python
import sys, os
import pygtk, gtk, gobject
import pygst
pygst.require("0.10")
import gst

 def __init__(self):
      #.... 
      # Code to create a gtk Window
      #....
      self.player = gst.Pipeline("player")
      source = gst.element_factory_make("v4l2src", "video-source")
      sink = gst.element_factory_make("xvimagesink", "video-output")
      caps = gst.Caps("video/x-raw-yuv, width=640, height=480")
      filter = gst.element_factory_make("capsfilter", "filter")
      filter.set_property("caps", caps)
      self.player.add(source, filter, sink)
      gst.element_link_many(source, filter, sink)

在此之后,我试图在总线上创建一个信号来侦听来自源或接收器的任何消息,以指示已发送或接收新帧,以便可以保存它。

      bus = self.player.get_bus()
      bus.add_signal_watch()
      bus.connect("message::any", self.save_file,"Save file")

其中 save_file 是我的回调,我想保存文件。

def save_file(self, bus, msg):
      print  "SAVED A NEW FILE"

我有两个问题,

  1. 如何调用此回调。message::any 不起作用。
  2. 调用此消息时,如何访问图像缓冲区。

更新(2012 年 4 月 12 日):

几个链接供参考

  1. v4l 的 python 接口。但这对我不起作用。当我尝试使用 12.04 Ubuntu 时,它似乎崩溃了。 http://code.google.com/p/python-video4linux2/

  2. 感兴趣的人的网络摄像头查看器代码。但这不是我想要的,因为它使用 gst-launch 并且不提供我想要的管道控制级别。http://pygstdocs.berlios.de/pygst-tutorial/webcam-viewer.html

4

2 回答 2

2

Gstreamer Bus 不打算用于此目的。放在那里的消息表示一些特殊事件,如流结束、元素状态更改等。流经元素的缓冲区(图像)通常不会在总线上生成任何消息。

您可以考虑几种可能性:

  • 在videosink之前制作“tee”元素并将“multifilesink”并行连接到videosink(您可能希望看到一些图像编码器,如pngenc或jpegenc并将其中一个放在multifilesink之前)
  • 像以前一样,但是使用“appsink”,它允许你处理缓冲区并用它们做任何你想做的事情
  • 如果要打开和关闭倾倒,请考虑使用“阀门”元素

您可能希望在附加接收器上将“同步”属性设置为 false(这会导致缓冲区尽快转储而不同步到时钟)。还可以考虑在 tee 之后添加一些队列(没有这种死锁可能会在 ready->paused 转换期间发生)。

于 2013-01-31T00:55:22.053 回答
0

我不确定我多年后的回复是否对您有用。但希望,这对其他人有用。

要接收您已收到缓冲区的消息,您可以使用 gstreamer probes

它可能是类似的东西:

def make_pipeline(self):
    CLI2 = [
    'v4l2src ! video/x-raw,format=RGB,width=640,height=480,framerate=30/1 ! ',
    'videoconvert ! x264enc bitrate=128 ! mpegtsmux name="mux" ! hlssink name="sink"',
    ]
    gcmd = ''.join(CLI2)
    self.pipeline = Gst.parse_launch(gcmd)
    self.hlssink = self.pipeline.get_by_name("sink")
    self.hlssink.set_property("target-duration",2)
    self.hlssink_pad = self.hlssink.get_static_pad("sink")
    probe_id = self.hlssink_pad.add_probe(Gst.PadProbeType.EVENT_UPSTREAM,probe_callback)

然后,探测回调函数可以是:

def probe_callback(hlssink_pad,info):
    info_event = info.get_event()
    info_structure = info_event.get_structure()
    do_something_with_this_info
    return Gst.PadProbeReturn.PASS

因此,每次在源焊盘或接收焊盘上发生事件时,都会在主线程中调用探测回调函数。

希望这可以帮助!

于 2015-12-31T22:37:24.617 回答