从 GStreamer 实时接收 Numpy 数组

Posted

技术标签:

【中文标题】从 GStreamer 实时接收 Numpy 数组【英文标题】:Receive Numpy Array Realtime from GStreamer 【发布时间】:2019-11-08 09:08:00 【问题描述】:

我尝试从 GStreamer 框架实时接收帧到帧的 numpy 数组。

我已经尝试在 Python 中使用这样的管道(来自 http://***.com/questions/8187257/play-audio-and-video-with-a-pipeline-in-gstreamer-python/8197837 并进行了修改):

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.progres-s-report = Gst.ElementFactory.make('progres-s-report')
self.progres-s-report.set_property('update-freq', 1)
self.pipeline.add(self.progres-s-report)

所有管道也已链接。但是,我不知道如何从流中实时进行 numpy 数组检索。你有什么建议吗?

【问题讨论】:

【参考方案1】:

原始问题中的管道旨在显示视频和播放音频,因此它分别使用autovideosinkautoaudiosink 元素。如果您希望视频帧进入您的应用程序而不是屏幕,您需要使用不同的接收器元素,即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的缓冲区格式转换为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 的 3 色格式,并且颜色数据将是无符号的 8 位整数。

【讨论】:

以上是关于从 GStreamer 实时接收 Numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

如何从 gstreamer 中的源请求更多缓冲区?

Python:使用 PyAudio(或其他东西)的实时音频流?

Qt+GStreamer:如何在播放实时视频流时拍摄快照

图像数据作为 gstreamer 中的源 [关闭]

在 Web 浏览器上使用带有 Janus 或 WebRTC 的 GStreamer 进行实时视频流

使用 GStreamer 播放保存在数组中的原始 PCM