Python 等价于 gst_element_link_many?
Python equivalence for gst_element_link_many?
我似乎无法在 Python 的 gst 管道中 link 超过 3 个元素。例如,我尝试在 Python.
中实现以下 cli 命令
gst-launch-1.0 filesrc location=cooldance.ogg ! oggdemux ! theoradec ! videoconvert ! autovideosink
由于C函数gst_element_link_many()没有Python等价关系,我试着一一联系起来:
import sys, os
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
class TestPlayer(object):
def __init__(self):
self.player = Gst.Pipeline.new("player")
source = Gst.ElementFactory.make("filesrc", "file-source")
demux = Gst.ElementFactory.make("oggdemux", "demux1")
decode = Gst.ElementFactory.make("theoradec", "decode1")
sink = Gst.ElementFactory.make("autovideosink", "sink1")
source.set_property("location", "/ione/gsttest/sample.ogg")
# Try to implement this pipeline using multiple links.
#self.player = Gst.parse_launch ("filesrc location=sample.ogg ! oggdemux ! theoradec ! autovideosink")
self.player.add(source)
self.player.add(demux)
self.player.add(decode)
self.player.add(sink)
# link elements one by one.
source.link(demux)
demux.link(decode)
decode.link(sink)
ret = self.player.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
print("ERROR: Unable to set the pipeline to the playing state")
sys.exit(1)
bus = self.player.get_bus()
terminate = False
while True:
msg = bus.timed_pop_filtered(
Gst.CLOCK_TIME_NONE,
Gst.MessageType.EOS | Gst.MessageType.ERROR) # listen on these types,.
if not msg:
continue
t = msg.type
if t == Gst.MessageType.ERROR: # exit if error.
err, dbg = msg.parse_error()
print("ERROR:", msg.src.get_name(), " ", err.message)
if dbg:
print("debugging info:", dbg)
terminate = True
elif t == Gst.MessageType.EOS: # exit if EOS
print("End-Of-Stream reached")
terminate = True
if terminate:
break
self.player.set_state(Gst.State.NULL)
if __name__ == '__main__':
Gst.init(None)
p = TestPlayer()
但是脚本失败并显示以下错误消息:
ERROR: demux1 Internal data stream error.
debugging info: gstoggdemux.c(4961): gst_ogg_demux_loop (): /GstPipeline:player/GstOggDemux:demux1:
streaming stopped, reason not-linked (-1)
我在 github 上找到了一些样本,但它们都失败了,并出现了类似的错误。请指教
您的问题源于对延迟 linking 的不正确理解。
gstreamer 中的垫可以 linked 当且仅当它们同意它们的格式。对于某些元素,所有可能的填充格式都是已知的 ahead-of-time。这意味着它们可以提前 linked,具有 link_may
和 link
等功能。例如,从 gst-inspect-1.0 oggdemux
的 pad 部分,我们看到这个:
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
application/ogg
audio/ogg
video/ogg
application/kate
这是一个可以 link 静态的水槽垫。 oggdemux
总会有一个水槽垫,它可以是此处列出的 4 种功能之一。
然而,关于它的 src 模板却不能这样说:
SRC template: 'src_%08x'
Availability: Sometimes
Capabilities:
ANY
由于ogg的内部结构,无法提前知道确切的src pad数量。相反,在管道功能期间,ogg-demux 根据需要添加焊盘。也许它有视频和音频数据,所以它会即时创建两个 pad,一个用于音频,一个用于视频。也许在 运行 的时候它没有任何音频,所以它只制作视频板,反之亦然。
因为 oggdemux 动态分配它的一些垫,你不能提前静态地 link 它。对于如何处理此问题,您有两种选择。
选项 1:
切换到只有静电垫的东西。 h264parse
就是一个例子。从gst-inspect-1.0
我们看到:
Pad Templates:
SRC template: 'src'
Availability: Always
Capabilities:
video/x-h264
parsed: true
stream-format: { (string)avc, (string)avc3, (string)byte-stream }
alignment: { (string)au, (string)nal }
SINK template: 'sink'
Availability: Always
Capabilities:
video/x-h264
它总是有一个 src 和一个 sink,并且它们总是输出完全相同的格式。这可以link提前静态编辑,没有问题。
选项 2:
您可以在 ogg-demux 上安装回调并等待它发出 pad-added
信号。在此信号上,您可以回调 link 新垫。这有利于支持动态管道,并避免 allocations/links 不需要制作。这也是 gst-launch-1.0
内部正在做的事情。但是,请注意。这是很多额外的工作,它更脆弱,而且可能不是你想要的。如果您可以摆脱它,请尝试使用选项 1。但是,可以说您不在乎并且无论如何都想这样做。祝你好运! gstreamer docs 包含实现此行为所需的所有信息。
注意:oggdemux 可能不是您管道中唯一带有有时垫的元素,请确保检查所有元素
注意 2:如果您将环境变量 GST_DEBUG 设置得足够高(可能是 4,也许是 5?),然后 运行 使用 gst-launch-1.0
的管道,日志输出将描述动态垫 linking 的详细信息,这对于了解您的管道实际在做什么应该非常有帮助。
我似乎无法在 Python 的 gst 管道中 link 超过 3 个元素。例如,我尝试在 Python.
中实现以下 cli 命令gst-launch-1.0 filesrc location=cooldance.ogg ! oggdemux ! theoradec ! videoconvert ! autovideosink
由于C函数gst_element_link_many()没有Python等价关系,我试着一一联系起来:
import sys, os
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
class TestPlayer(object):
def __init__(self):
self.player = Gst.Pipeline.new("player")
source = Gst.ElementFactory.make("filesrc", "file-source")
demux = Gst.ElementFactory.make("oggdemux", "demux1")
decode = Gst.ElementFactory.make("theoradec", "decode1")
sink = Gst.ElementFactory.make("autovideosink", "sink1")
source.set_property("location", "/ione/gsttest/sample.ogg")
# Try to implement this pipeline using multiple links.
#self.player = Gst.parse_launch ("filesrc location=sample.ogg ! oggdemux ! theoradec ! autovideosink")
self.player.add(source)
self.player.add(demux)
self.player.add(decode)
self.player.add(sink)
# link elements one by one.
source.link(demux)
demux.link(decode)
decode.link(sink)
ret = self.player.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
print("ERROR: Unable to set the pipeline to the playing state")
sys.exit(1)
bus = self.player.get_bus()
terminate = False
while True:
msg = bus.timed_pop_filtered(
Gst.CLOCK_TIME_NONE,
Gst.MessageType.EOS | Gst.MessageType.ERROR) # listen on these types,.
if not msg:
continue
t = msg.type
if t == Gst.MessageType.ERROR: # exit if error.
err, dbg = msg.parse_error()
print("ERROR:", msg.src.get_name(), " ", err.message)
if dbg:
print("debugging info:", dbg)
terminate = True
elif t == Gst.MessageType.EOS: # exit if EOS
print("End-Of-Stream reached")
terminate = True
if terminate:
break
self.player.set_state(Gst.State.NULL)
if __name__ == '__main__':
Gst.init(None)
p = TestPlayer()
但是脚本失败并显示以下错误消息:
ERROR: demux1 Internal data stream error.
debugging info: gstoggdemux.c(4961): gst_ogg_demux_loop (): /GstPipeline:player/GstOggDemux:demux1:
streaming stopped, reason not-linked (-1)
我在 github 上找到了一些样本,但它们都失败了,并出现了类似的错误。请指教
您的问题源于对延迟 linking 的不正确理解。
gstreamer 中的垫可以 linked 当且仅当它们同意它们的格式。对于某些元素,所有可能的填充格式都是已知的 ahead-of-time。这意味着它们可以提前 linked,具有 link_may
和 link
等功能。例如,从 gst-inspect-1.0 oggdemux
的 pad 部分,我们看到这个:
Pad Templates:
SINK template: 'sink'
Availability: Always
Capabilities:
application/ogg
audio/ogg
video/ogg
application/kate
这是一个可以 link 静态的水槽垫。 oggdemux
总会有一个水槽垫,它可以是此处列出的 4 种功能之一。
然而,关于它的 src 模板却不能这样说:
SRC template: 'src_%08x'
Availability: Sometimes
Capabilities:
ANY
由于ogg的内部结构,无法提前知道确切的src pad数量。相反,在管道功能期间,ogg-demux 根据需要添加焊盘。也许它有视频和音频数据,所以它会即时创建两个 pad,一个用于音频,一个用于视频。也许在 运行 的时候它没有任何音频,所以它只制作视频板,反之亦然。
因为 oggdemux 动态分配它的一些垫,你不能提前静态地 link 它。对于如何处理此问题,您有两种选择。
选项 1:
切换到只有静电垫的东西。 h264parse
就是一个例子。从gst-inspect-1.0
我们看到:
Pad Templates:
SRC template: 'src'
Availability: Always
Capabilities:
video/x-h264
parsed: true
stream-format: { (string)avc, (string)avc3, (string)byte-stream }
alignment: { (string)au, (string)nal }
SINK template: 'sink'
Availability: Always
Capabilities:
video/x-h264
它总是有一个 src 和一个 sink,并且它们总是输出完全相同的格式。这可以link提前静态编辑,没有问题。
选项 2:
您可以在 ogg-demux 上安装回调并等待它发出 pad-added
信号。在此信号上,您可以回调 link 新垫。这有利于支持动态管道,并避免 allocations/links 不需要制作。这也是 gst-launch-1.0
内部正在做的事情。但是,请注意。这是很多额外的工作,它更脆弱,而且可能不是你想要的。如果您可以摆脱它,请尝试使用选项 1。但是,可以说您不在乎并且无论如何都想这样做。祝你好运! gstreamer docs 包含实现此行为所需的所有信息。
注意:oggdemux 可能不是您管道中唯一带有有时垫的元素,请确保检查所有元素
注意 2:如果您将环境变量 GST_DEBUG 设置得足够高(可能是 4,也许是 5?),然后 运行 使用 gst-launch-1.0
的管道,日志输出将描述动态垫 linking 的详细信息,这对于了解您的管道实际在做什么应该非常有帮助。