从 GStreamer 实时接收 Numpy 数组
Receive Numpy Array Realtime from GStreamer
我尝试从 GStreamer 框架实时接收逐帧的 numpy 数组。
我已经在 Python 中尝试使用这样的管道(来自 并进行了修改):
self.filesrc = Gst.ElementFactory.make('filesrc')
self.filesrc.set_property('location', self.source_file)
self.pipeline.add(self.filesrc)
# Demuxer
self.decoder = Gst.ElementFactory.make('decodebin')
self.decoder.connect('pad-added', self.__on_decoded_pad)
self.pipeline.add(self.decoder)
# Video elements
self.videoqueue = Gst.ElementFactory.make('queue', 'videoqueue')
self.pipeline.add(self.videoqueue)
self.autovideoconvert = Gst.ElementFactory.make('autovideoconvert')
self.pipeline.add(self.autovideoconvert)
self.autovideosink = Gst.ElementFactory.make('autovideosink')
self.pipeline.add(self.autovideosink)
# Audio elements
self.audioqueue = Gst.ElementFactory.make('queue', 'audioqueue')
self.pipeline.add(self.audioqueue)
self.audioconvert = Gst.ElementFactory.make('audioconvert')
self.pipeline.add(self.audioconvert)
self.autoaudiosink = Gst.ElementFactory.make('autoaudiosink')
self.pipeline.add(self.autoaudiosink)
self.progressreport = Gst.ElementFactory.make('progressreport')
self.progressreport.set_property('update-freq', 1)
self.pipeline.add(self.progressreport)
所有管道也已链接。但是,我 运行 不知道如何从流中实时检索 numpy 数组。你有什么建议吗?
原题中的管道是为了显示视频和播放音频而设计的,所以分别使用了autovideosink
和autoaudiosink
元素。如果您希望您的视频帧转到您的应用程序而不是屏幕,您需要使用不同的接收器元素,即 appsink
而不是 autovideosink
。
self.appsink = Gst.ElementFactory.make('appsink')
self.pipeline.add(self.appsink)
appsink
元素有一个名为 "new-sample" 的信号,如果您启用 appsink 的 "emit-signals" 属性,您可以连接到该信号,当新框架可用时将触发该信号。
serf.appsink.set_property("emit-signals", True)
handler_id = self.appsink.connect("new-sample", self.__on_new_sample)
接下来就是将GStreamer的buffer格式转为Numpy数组的问题了
def __on_new_sample(self, app_sink):
sample = app_sink.pull_sample()
caps = sample.get_caps()
# Extract the width and height info from the sample's caps
height = caps.get_structure(0).get_value("height")
width = caps.get_structure(0).get_value("width")
# Get the actual data
buffer = sample.get_buffer()
# Get read access to the buffer data
success, map_info = buffer.map(Gst.MapFlags.READ)
if not success:
raise RuntimeError("Could not map buffer data!")
numpy_frame = np.ndarray(
shape=(height, width, 3),
dtype=np.uint8,
buffer=map_info.data)
# Clean up the buffer mapping
buffer.unmap(map_info)
请注意,此代码对帧数据做了某些假设,即它是像 RGB 一样的三色格式,并且颜色数据将是无符号的 8 位整数。
我尝试从 GStreamer 框架实时接收逐帧的 numpy 数组。
我已经在 Python 中尝试使用这样的管道(来自 并进行了修改):
self.filesrc = Gst.ElementFactory.make('filesrc')
self.filesrc.set_property('location', self.source_file)
self.pipeline.add(self.filesrc)
# Demuxer
self.decoder = Gst.ElementFactory.make('decodebin')
self.decoder.connect('pad-added', self.__on_decoded_pad)
self.pipeline.add(self.decoder)
# Video elements
self.videoqueue = Gst.ElementFactory.make('queue', 'videoqueue')
self.pipeline.add(self.videoqueue)
self.autovideoconvert = Gst.ElementFactory.make('autovideoconvert')
self.pipeline.add(self.autovideoconvert)
self.autovideosink = Gst.ElementFactory.make('autovideosink')
self.pipeline.add(self.autovideosink)
# Audio elements
self.audioqueue = Gst.ElementFactory.make('queue', 'audioqueue')
self.pipeline.add(self.audioqueue)
self.audioconvert = Gst.ElementFactory.make('audioconvert')
self.pipeline.add(self.audioconvert)
self.autoaudiosink = Gst.ElementFactory.make('autoaudiosink')
self.pipeline.add(self.autoaudiosink)
self.progressreport = Gst.ElementFactory.make('progressreport')
self.progressreport.set_property('update-freq', 1)
self.pipeline.add(self.progressreport)
所有管道也已链接。但是,我 运行 不知道如何从流中实时检索 numpy 数组。你有什么建议吗?
原题中的管道是为了显示视频和播放音频而设计的,所以分别使用了autovideosink
和autoaudiosink
元素。如果您希望您的视频帧转到您的应用程序而不是屏幕,您需要使用不同的接收器元素,即 appsink
而不是 autovideosink
。
self.appsink = Gst.ElementFactory.make('appsink')
self.pipeline.add(self.appsink)
appsink
元素有一个名为 "new-sample" 的信号,如果您启用 appsink 的 "emit-signals" 属性,您可以连接到该信号,当新框架可用时将触发该信号。
serf.appsink.set_property("emit-signals", True)
handler_id = self.appsink.connect("new-sample", self.__on_new_sample)
接下来就是将GStreamer的buffer格式转为Numpy数组的问题了
def __on_new_sample(self, app_sink):
sample = app_sink.pull_sample()
caps = sample.get_caps()
# Extract the width and height info from the sample's caps
height = caps.get_structure(0).get_value("height")
width = caps.get_structure(0).get_value("width")
# Get the actual data
buffer = sample.get_buffer()
# Get read access to the buffer data
success, map_info = buffer.map(Gst.MapFlags.READ)
if not success:
raise RuntimeError("Could not map buffer data!")
numpy_frame = np.ndarray(
shape=(height, width, 3),
dtype=np.uint8,
buffer=map_info.data)
# Clean up the buffer mapping
buffer.unmap(map_info)
请注意,此代码对帧数据做了某些假设,即它是像 RGB 一样的三色格式,并且颜色数据将是无符号的 8 位整数。