Gstreamer 自动插入:在 "have-type" 上创建多路分解
Gstreamer autoplugging: create demux on "have-type"
我正在尝试使用 typefind
元素在 运行 时选择正确的多路分解器类型。如果我在播放前创建解复用器并在收到 "have-type" 信号后 link 它,一切正常。例如:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from gi.repository import GObject
def on_message(bus, message, loop):
mtype = message.type
if mtype == Gst.MessageType.EOS:
print("End of stream")
loop.quit()
return True
n = 0
def new_sample(sink, data):
global n
n += 1
#print('new-sample')
sample = sink.emit('pull-sample')
return Gst.FlowReturn.OK
Gst.init(None)
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
src = Gst.ElementFactory.make('splitfilesrc')
typefind = Gst.ElementFactory.make('typefind')
demux = Gst.ElementFactory.make('avidemux')
sink = Gst.ElementFactory.make('appsink')
src.set_property('location', sys.argv[1])
pipeline.add(src)
pipeline.add(typefind)
pipeline.add(demux)
pipeline.add(sink)
if not src.link(typefind):
print('Could not link src to typefind.')
exit(1)
def demux_pad_added(element, pad):
stream = pad.query_caps(None).to_string()
print('Found stream: {}'.format(stream))
result = pad.link(sink.get_static_pad('sink'))
if result != Gst.PadLinkReturn.OK:
print()
print('Could not link demux to sink.')
loop.quit()
sink.set_property('emit-signals', True)
sink.set_property('sync', False)
sink.connect('new-sample', new_sample, None)
def have_type(typefind, probability, caps):
print('have-type:', caps.to_string())
demux.connect('pad-added', demux_pad_added)
if not typefind.link(demux):
print('Could not link typefind to demux.')
exit(1)
typefind.connect('have-type', have_type)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', on_message, loop)
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
print()
pipeline.set_state(Gst.State.NULL)
print('total:', n)
如果我 运行 这样我会得到类似的东西:
$ python foo.py foo.avi
have-type: video/x-msvideo
Found stream: video/x-h264, variant=(string)itu, framerate=(fraction)50/1, max-input-size=(int)1048576, width=(int)1728, height=(int)3072, stream-format=(string)byte-stream,
alignment=(string)au
^C
total: 12144
现在,如果我在 "have-type" 回调中移动 demux 创建:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from gi.repository import GObject
def on_message(bus, message, loop):
mtype = message.type
if mtype == Gst.MessageType.EOS:
print("End of stream")
loop.quit()
return True
n = 0
def new_sample(sink, data):
global n
n += 1
#print('new-sample')
sample = sink.emit('pull-sample')
return Gst.FlowReturn.OK
Gst.init(None)
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
src = Gst.ElementFactory.make('splitfilesrc')
typefind = Gst.ElementFactory.make('typefind')
#demux = Gst.ElementFactory.make('avidemux')
sink = Gst.ElementFactory.make('appsink')
src.set_property('location', sys.argv[1])
pipeline.add(src)
pipeline.add(typefind)
#pipeline.add(demux)
pipeline.add(sink)
if not src.link(typefind):
print('Could not link src to typefind.')
exit(1)
def demux_pad_added(element, pad):
stream = pad.query_caps(None).to_string()
print('Found stream: {}'.format(stream))
result = pad.link(sink.get_static_pad('sink'))
if result != Gst.PadLinkReturn.OK:
print()
print('Could not link demux to sink.')
loop.quit()
sink.set_property('emit-signals', True)
sink.set_property('sync', False)
sink.connect('new-sample', new_sample, None)
def have_type(typefind, probability, caps):
print('have-type:', caps.to_string())
demux = Gst.ElementFactory.make('avidemux')
pipeline.add(demux)
demux.connect('pad-added', demux_pad_added)
if not typefind.link(demux):
print('Could not link typefind to demux.')
exit(1)
typefind.connect('have-type', have_type)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', on_message, loop)
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
print()
pipeline.set_state(Gst.State.NULL)
print('total:', n)
请注意,只有 demux = ...
和 pipeline.add(demux)
两行已移至回调中,但此管道似乎没有执行任何操作:
$ python foo.py foo.avi
have-type: video/x-msvideo
^C
total: 0
我可能可以事先创建所有可能的解复用器,link 我想在回调中创建一个解复用器,但我想知道为什么这不起作用,我是否可以让它像这样工作?
这里有小细节。由于您将解复用器添加到管道的时间较晚,它仍处于 NULL
状态,因为它没有从管道接收到 PLAYING 的状态更改。它需要处于 PAUSED/PLAYING 状态才能真正执行任何操作。
如果我没记错的话,如果你修改你的代码让你的解复用器在连接后进入 PLAYING 状态,它应该可以工作..:[=12=]
[..]
demux = Gst.ElementFactory.make('avidemux')
pipeline.add(demux)
demux.connect('pad-added', demux_pad_added)
if not typefind.link(demux):
print('Could not link typefind to demux.')
exit(1)
demux.set_state(Gst.State.PLAYING)
typefind.connect('have-type', have_type)
[..]
我正在尝试使用 typefind
元素在 运行 时选择正确的多路分解器类型。如果我在播放前创建解复用器并在收到 "have-type" 信号后 link 它,一切正常。例如:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from gi.repository import GObject
def on_message(bus, message, loop):
mtype = message.type
if mtype == Gst.MessageType.EOS:
print("End of stream")
loop.quit()
return True
n = 0
def new_sample(sink, data):
global n
n += 1
#print('new-sample')
sample = sink.emit('pull-sample')
return Gst.FlowReturn.OK
Gst.init(None)
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
src = Gst.ElementFactory.make('splitfilesrc')
typefind = Gst.ElementFactory.make('typefind')
demux = Gst.ElementFactory.make('avidemux')
sink = Gst.ElementFactory.make('appsink')
src.set_property('location', sys.argv[1])
pipeline.add(src)
pipeline.add(typefind)
pipeline.add(demux)
pipeline.add(sink)
if not src.link(typefind):
print('Could not link src to typefind.')
exit(1)
def demux_pad_added(element, pad):
stream = pad.query_caps(None).to_string()
print('Found stream: {}'.format(stream))
result = pad.link(sink.get_static_pad('sink'))
if result != Gst.PadLinkReturn.OK:
print()
print('Could not link demux to sink.')
loop.quit()
sink.set_property('emit-signals', True)
sink.set_property('sync', False)
sink.connect('new-sample', new_sample, None)
def have_type(typefind, probability, caps):
print('have-type:', caps.to_string())
demux.connect('pad-added', demux_pad_added)
if not typefind.link(demux):
print('Could not link typefind to demux.')
exit(1)
typefind.connect('have-type', have_type)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', on_message, loop)
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
print()
pipeline.set_state(Gst.State.NULL)
print('total:', n)
如果我 运行 这样我会得到类似的东西:
$ python foo.py foo.avi
have-type: video/x-msvideo
Found stream: video/x-h264, variant=(string)itu, framerate=(fraction)50/1, max-input-size=(int)1048576, width=(int)1728, height=(int)3072, stream-format=(string)byte-stream,
alignment=(string)au
^C
total: 12144
现在,如果我在 "have-type" 回调中移动 demux 创建:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
from gi.repository import GObject
def on_message(bus, message, loop):
mtype = message.type
if mtype == Gst.MessageType.EOS:
print("End of stream")
loop.quit()
return True
n = 0
def new_sample(sink, data):
global n
n += 1
#print('new-sample')
sample = sink.emit('pull-sample')
return Gst.FlowReturn.OK
Gst.init(None)
loop = GObject.MainLoop()
pipeline = Gst.Pipeline()
src = Gst.ElementFactory.make('splitfilesrc')
typefind = Gst.ElementFactory.make('typefind')
#demux = Gst.ElementFactory.make('avidemux')
sink = Gst.ElementFactory.make('appsink')
src.set_property('location', sys.argv[1])
pipeline.add(src)
pipeline.add(typefind)
#pipeline.add(demux)
pipeline.add(sink)
if not src.link(typefind):
print('Could not link src to typefind.')
exit(1)
def demux_pad_added(element, pad):
stream = pad.query_caps(None).to_string()
print('Found stream: {}'.format(stream))
result = pad.link(sink.get_static_pad('sink'))
if result != Gst.PadLinkReturn.OK:
print()
print('Could not link demux to sink.')
loop.quit()
sink.set_property('emit-signals', True)
sink.set_property('sync', False)
sink.connect('new-sample', new_sample, None)
def have_type(typefind, probability, caps):
print('have-type:', caps.to_string())
demux = Gst.ElementFactory.make('avidemux')
pipeline.add(demux)
demux.connect('pad-added', demux_pad_added)
if not typefind.link(demux):
print('Could not link typefind to demux.')
exit(1)
typefind.connect('have-type', have_type)
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', on_message, loop)
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
print()
pipeline.set_state(Gst.State.NULL)
print('total:', n)
请注意,只有 demux = ...
和 pipeline.add(demux)
两行已移至回调中,但此管道似乎没有执行任何操作:
$ python foo.py foo.avi
have-type: video/x-msvideo
^C
total: 0
我可能可以事先创建所有可能的解复用器,link 我想在回调中创建一个解复用器,但我想知道为什么这不起作用,我是否可以让它像这样工作?
这里有小细节。由于您将解复用器添加到管道的时间较晚,它仍处于 NULL
状态,因为它没有从管道接收到 PLAYING 的状态更改。它需要处于 PAUSED/PLAYING 状态才能真正执行任何操作。
如果我没记错的话,如果你修改你的代码让你的解复用器在连接后进入 PLAYING 状态,它应该可以工作..:[=12=]
[..]
demux = Gst.ElementFactory.make('avidemux')
pipeline.add(demux)
demux.connect('pad-added', demux_pad_added)
if not typefind.link(demux):
print('Could not link typefind to demux.')
exit(1)
demux.set_state(Gst.State.PLAYING)
typefind.connect('have-type', have_type)
[..]