gstreamer appsink 无法获取 flvmux 数据
gstreamer appsink can not get flvmux data
我使用 gstreamer 和 python-gi 来获取编码的视频流数据。我的发布就像 gst-launch-1.0 v4l2src device=/dev/video0 ! x264enc bitrate=1000 ! h264parse ! flvmux ! appsink
。
现在我在 python 中编码如下:
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstApp', '1.0')
from gi.repository import GObject, Gst, GstApp
GObject.threads_init()
Gst.init(None)
class Example:
def __init__(self):
self.mainloop = GObject.MainLoop()
self.pipeline = Gst.Pipeline()
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect('message::eos', self.on_eos)
self.bus.connect('message::error', self.on_error)
# Create elements
self.src = Gst.ElementFactory.make('v4l2src', None)
self.encoder = Gst.ElementFactory.make('x264enc', None)
self.parse = Gst.ElementFactory.make('h264parse', None)
self.mux = Gst.ElementFactory.make('flvmux', None)
self.sink = Gst.ElementFactory.make('appsink', None)
# Add elements to pipeline
self.pipeline.add(self.src)
self.pipeline.add(self.encoder)
self.pipeline.add(self.parse)
self.pipeline.add(self.mux)
self.pipeline.add(self.sink)
# Set properties
self.src.set_property('device', "/dev/video0")
# Link elements
self.src.link(self.encoder)
self.encoder.link(self.parse)
self.parse.link(self.mux)
self.mux.link(self.sink)
def run(self):
self.pipeline.set_state(Gst.State.PLAYING)
# self.mainloop.run()
appsink_sample = GstApp.AppSink.pull_sample(self.sink)
while True:
buff = appsink_sample.get_buffer()
size, offset, maxsize = buff.get_sizes()
frame_data = buff.extract_dup(offset, size)
print(frame_data)
def kill(self):
self.pipeline.set_state(Gst.State.NULL)
self.mainloop.quit()
def on_eos(self, bus, msg):
print('on_eos()')
self.kill()
def on_error(self, bus, msg):
print('on_error():', msg.parse_error())
self.kill()
example = Example()
example.run()
但我每次都得到相同的数据,就像"FLV[=18=]x01[=18=]x01"。
我用C语言写函数,结果一样。为什么?谁能帮帮我?
print
打印我假设的字符串?缓冲区包含二进制数据。它只是从类似于字符串的数据开始。所以它可能以 FLV[=13=]x01[=13=]x01[=13=]x00.. 开头,然后是更多二进制数据。字符串函数会将 0x00 视为字符串的结束标记并停止打印(因为打印函数不采用大小参数,这是数据结束的协议)。大小 属性 应该改变..除非所有数据都具有相同的数据块大小..但是你需要找到另一个打印二进制数据的函数 - 虽然我不确定这是否真的是你想要的.也许您想将此数据写入文件?
问题出在 gstreamer 的进程上。我们应该使用信号函数来获取appsink中的流数据。
我使用 gstreamer 和 python-gi 来获取编码的视频流数据。我的发布就像 gst-launch-1.0 v4l2src device=/dev/video0 ! x264enc bitrate=1000 ! h264parse ! flvmux ! appsink
。
现在我在 python 中编码如下:
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstApp', '1.0')
from gi.repository import GObject, Gst, GstApp
GObject.threads_init()
Gst.init(None)
class Example:
def __init__(self):
self.mainloop = GObject.MainLoop()
self.pipeline = Gst.Pipeline()
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.connect('message::eos', self.on_eos)
self.bus.connect('message::error', self.on_error)
# Create elements
self.src = Gst.ElementFactory.make('v4l2src', None)
self.encoder = Gst.ElementFactory.make('x264enc', None)
self.parse = Gst.ElementFactory.make('h264parse', None)
self.mux = Gst.ElementFactory.make('flvmux', None)
self.sink = Gst.ElementFactory.make('appsink', None)
# Add elements to pipeline
self.pipeline.add(self.src)
self.pipeline.add(self.encoder)
self.pipeline.add(self.parse)
self.pipeline.add(self.mux)
self.pipeline.add(self.sink)
# Set properties
self.src.set_property('device', "/dev/video0")
# Link elements
self.src.link(self.encoder)
self.encoder.link(self.parse)
self.parse.link(self.mux)
self.mux.link(self.sink)
def run(self):
self.pipeline.set_state(Gst.State.PLAYING)
# self.mainloop.run()
appsink_sample = GstApp.AppSink.pull_sample(self.sink)
while True:
buff = appsink_sample.get_buffer()
size, offset, maxsize = buff.get_sizes()
frame_data = buff.extract_dup(offset, size)
print(frame_data)
def kill(self):
self.pipeline.set_state(Gst.State.NULL)
self.mainloop.quit()
def on_eos(self, bus, msg):
print('on_eos()')
self.kill()
def on_error(self, bus, msg):
print('on_error():', msg.parse_error())
self.kill()
example = Example()
example.run()
但我每次都得到相同的数据,就像"FLV[=18=]x01[=18=]x01"。
我用C语言写函数,结果一样。为什么?谁能帮帮我?
print
打印我假设的字符串?缓冲区包含二进制数据。它只是从类似于字符串的数据开始。所以它可能以 FLV[=13=]x01[=13=]x01[=13=]x00.. 开头,然后是更多二进制数据。字符串函数会将 0x00 视为字符串的结束标记并停止打印(因为打印函数不采用大小参数,这是数据结束的协议)。大小 属性 应该改变..除非所有数据都具有相同的数据块大小..但是你需要找到另一个打印二进制数据的函数 - 虽然我不确定这是否真的是你想要的.也许您想将此数据写入文件?
问题出在 gstreamer 的进程上。我们应该使用信号函数来获取appsink中的流数据。