传输流管道不播放
transport stream pipeline doesn't play
我正在尝试使用 gstreamer 播放传输流。我能够构建管道,它 声称正在播放,但没有生成音频或视频 。使用 playbin
的 The demo app 在这种有限的情况下有效,但并不是真正的选择。使用 gst-launch
构建完全相同的图形也可以,但不是一个选项。这是我用来构建管道的(简化的)代码:
class composer:
def __init__(self,pipeline,upstream = None):
self.pipeline = pipeline
self.upstream = upstream
def link(self,filter,src_pad_name = None):
x = Gst.ElementFactory.make(filter)
self.pipeline.add(x)
if self.upstream:
if src_pad_name:
src_pad = self.upstream.get_static_pad(src_pad_name)
else:
src_pad = self.upstream.srcpads[0]
src_pad.link(x.sinkpads[0])
self.upstream = x
return self
def props(self,pd):
for k in pd:
self.upstream.set_property(k,pd[k])
return self
def connect(self,message,handler):
self.upstream.connect(message,handler)
return self
class graph(object):
def render_streams(self,unused):
c = composer(self.pipeline,self.mux) \
.link('queue','video_0031') \
.link('mpegvideoparse') \
.link('mpeg2dec') \
.link('queue') \
.link('videoconvert') \
.link('videoscale') \
.link('xvimagesink')
c = composer(self.pipeline,self.mux) \
.link('queue','audio_0032') \
.link('ac3parse') \
.link('a52dec') \
.link('queue') \
.link('audioconvert') \
.link('audioresample') \
.link('pulsesink')
self.rendered = True
def __init__(self,file):
self.pipeline = Gst.Pipeline('pipeline for ' + file)
self.demo_copy_pasta() #from http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/video-player-1.0
self.rendered = False
c = composer(self.pipeline) \
.link('filesrc') \
.props({'location':file}) \
.link('tsdemux') \
.connect('no-more-pads',self.render_streams)
self.mux = c.upstream
self.pipeline.set_state(Gst.State.PAUSED)
while not self.rendered: # not spinning in real app
time.sleep(0.5)
def run(self):
self.window.show_all()
self.xid = self.drawingarea.get_property('window').get_xid()
self.pipeline.set_state(Gst.State.PLAYING)
Gtk.main()
graph('bbb.ts').run() #run has the same implementation as the (working) demo code
关于图表我注意到的一件事是格式看起来不像是经过完全协商的。例如,在工作版本上,多路分解器和队列之间的格式是 mpeg2。在损坏的版本上,它在 demux 端是 mpeg2,但在队列端是任何。
我还需要做什么才能播放它?
我发现此实现有两个问题:
(1) 您从未将状态设置为 State.PLAYING
(2) 您永远不会启动消息循环:您不能在主 gstreamer 线程中执行 'time.sleep'。您需要 运行 消息循环,例如通过调用 Gtk.main()。
您在代码中提到的示例 URL 正确地完成了这两件事。
问题是,当新元素连接到 tsdemux
时,它已经处于暂停状态,并且似乎无法正确传播。添加代码:
state = self.upstream.get_state(1)
x.set_state(state[1])
到composer.link
允许图表正常播放。
我正在尝试使用 gstreamer 播放传输流。我能够构建管道,它 声称正在播放,但没有生成音频或视频 。使用 playbin
的 The demo app 在这种有限的情况下有效,但并不是真正的选择。使用 gst-launch
构建完全相同的图形也可以,但不是一个选项。这是我用来构建管道的(简化的)代码:
class composer:
def __init__(self,pipeline,upstream = None):
self.pipeline = pipeline
self.upstream = upstream
def link(self,filter,src_pad_name = None):
x = Gst.ElementFactory.make(filter)
self.pipeline.add(x)
if self.upstream:
if src_pad_name:
src_pad = self.upstream.get_static_pad(src_pad_name)
else:
src_pad = self.upstream.srcpads[0]
src_pad.link(x.sinkpads[0])
self.upstream = x
return self
def props(self,pd):
for k in pd:
self.upstream.set_property(k,pd[k])
return self
def connect(self,message,handler):
self.upstream.connect(message,handler)
return self
class graph(object):
def render_streams(self,unused):
c = composer(self.pipeline,self.mux) \
.link('queue','video_0031') \
.link('mpegvideoparse') \
.link('mpeg2dec') \
.link('queue') \
.link('videoconvert') \
.link('videoscale') \
.link('xvimagesink')
c = composer(self.pipeline,self.mux) \
.link('queue','audio_0032') \
.link('ac3parse') \
.link('a52dec') \
.link('queue') \
.link('audioconvert') \
.link('audioresample') \
.link('pulsesink')
self.rendered = True
def __init__(self,file):
self.pipeline = Gst.Pipeline('pipeline for ' + file)
self.demo_copy_pasta() #from http://bazaar.launchpad.net/~jderose/+junk/gst-examples/view/head:/video-player-1.0
self.rendered = False
c = composer(self.pipeline) \
.link('filesrc') \
.props({'location':file}) \
.link('tsdemux') \
.connect('no-more-pads',self.render_streams)
self.mux = c.upstream
self.pipeline.set_state(Gst.State.PAUSED)
while not self.rendered: # not spinning in real app
time.sleep(0.5)
def run(self):
self.window.show_all()
self.xid = self.drawingarea.get_property('window').get_xid()
self.pipeline.set_state(Gst.State.PLAYING)
Gtk.main()
graph('bbb.ts').run() #run has the same implementation as the (working) demo code
关于图表我注意到的一件事是格式看起来不像是经过完全协商的。例如,在工作版本上,多路分解器和队列之间的格式是 mpeg2。在损坏的版本上,它在 demux 端是 mpeg2,但在队列端是任何。
我还需要做什么才能播放它?
我发现此实现有两个问题:
(1) 您从未将状态设置为 State.PLAYING
(2) 您永远不会启动消息循环:您不能在主 gstreamer 线程中执行 'time.sleep'。您需要 运行 消息循环,例如通过调用 Gtk.main()。
您在代码中提到的示例 URL 正确地完成了这两件事。
问题是,当新元素连接到 tsdemux
时,它已经处于暂停状态,并且似乎无法正确传播。添加代码:
state = self.upstream.get_state(1)
x.set_state(state[1])
到composer.link
允许图表正常播放。