0

我正在尝试使用 gstreamer 播放传输流。我能够构建管道并且它声称正在播放,但没有产生音频或视频。 使用的演示应用程序playbin在这种有限的情况下工作,但不是一个真正的选择。使用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,但在队列端是任何。

我还需要做什么才能让它播放?

4

2 回答 2

0

我看到这个实现有两个问题:

(1) 你从来没有将状态设置为 State.PLAYING

(2) 您从不泵送消息循环:您不能在主 gstreamer 线程中执行“time.sleep”。您需要运行消息循环,例如通过调用 Gtk.main()。

您在代码中提到的示例 URL 正确地完成了这两件事。

于 2015-06-26T02:00:14.607 回答
0

问题是当新元素连接到tsdemux它时,它已经处于暂停状态,并且这似乎无法正确传播。添加代码:

  state = self.upstream.get_state(1)
  x.set_state(state[1])

允许composer.link图形正常播放。

于 2015-06-26T16:27:02.257 回答