2017-07-16 19 views
0

我在gstreamer管道中使用交错元素时遇到问题。当使用带有两个接收器的交错元素时,Gst管道未运行

我正在从输入(autoaudiosrc)中读取音频到一个tee中,所以我可以将它写入磁盘并实时获取音频电平(将其添加到硬件vu计量器中,级别到标准输出)。我希望能够使用任何1或2个通道并将它们写入单独的文件,这样我就可以将6个输入通道分成5个文件(1个立体声,4个单声道)。 现在把一切写到一个文件中工作正常,然后我添加了一个deinterleave元素来将所有文件拆分成单声道文件,这些文件也可以正常工作,但是将两个通道合并到一个立体声通道中会破坏整个管道。

def new_recorder_bin(path, sinks=1): 
    bin = Gst.Bin() 
    interleave = Gst.ElementFactory.make('interleave', None) 
    queue = Gst.ElementFactory.make('queue', None) 
    encoder = Gst.ElementFactory.make('wavenc', None) 
    output = Gst.ElementFactory.make('filesink', None) 
    output.set_property('location', path) 
    bin.add(interleave) 
    bin.add(queue) 
    bin.add(encoder) 
    bin.add(output) 
    interleave.link(queue) 
    queue.link(encoder) 
    encoder.link(output) 
    if sinks == 1: 
     interleave.set_property('channel_positions', [GstAudio.AudioChannelPosition.MONO]) 
     sink = interleave.get_request_pad('sink_0') 
     ghostpad = Gst.GhostPad.new('sink_0', sink) 
     bin.add_pad(ghostpad) 
    elif sinks == 2: 
     interleave.set_property('channel_positions', [ 
      GstAudio.AudioChannelPosition.FRONT_LEFT, 
      GstAudio.AudioChannelPosition.FRONT_RIGHT 
     ]) 
     sink0 = interleave.get_request_pad('sink_0') 
     ghostpad0 = Gst.GhostPad.new('sink_0', sink0) 
     sink1 = interleave.get_request_pad('sink_1') 
     ghostpad1 = Gst.GhostPad.new('sink_1', sink1) 
     bin.add_pad(ghostpad0) 
     bin.add_pad(ghostpad1) 
    return bin 

这是创建一个新的bin来将一个或两个通道写入磁盘的代码。当我只连接到一个水槽垫(并将水槽设置为1)时,一切仍然正常,但是当我连接两个水槽垫(并将水槽设置为2)时,文件被创建,但管道似乎卡住了。级别不会打印出来,也不会将数据写入文件。

我已经附上完整的文件的要点,这是原型代码,但在我重构此之前,我希望一切工作,因为它应该。

https://gist.github.com/maxjoehnk/16785499db6e864bf120cf85a81b1ecf

+0

不确定完整流水线的样子。但是因为所有音频都来自一个线程(相同的音频源)。我希望交错元素能够阻止自己。尝试在交织汇点之前添加队列元素。 –

+0

现在我有一个将信号“分裂”成两个队列的三通,一个用于level元素,另一个用于解交错元素。完整管道的源代码可以在我已链接的要点中找到。我真的需要为每个pad或每个元素添加一个队列吗?因为我在交错元素后面有一个队列,所以我不太确定如何在之前添加它 –

回答

0

好了,所以通过Florian Zwoch的意见是线索。我为每个频道添加了一个队列,现在一切正常。所以我new_recorder_bin函数现在看起来是这样的:

def new_recorder_bin(path, sinks=1): 
    bin = Gst.Bin() 
    interleave = Gst.ElementFactory.make('interleave', None) 
    encoder = Gst.ElementFactory.make('wavenc', None) 
    output = Gst.ElementFactory.make('filesink', None) 
    output.set_property('location', path) 
    bin.add(interleave) 
    bin.add(encoder) 
    bin.add(output) 
    interleave.link(encoder) 
    encoder.link(output) 
    if sinks == 1: 
     queue = Gst.ElementFactory.make('queue', None) 
     bin.add(queue) 
     interleave.set_property('channel_positions', [GstAudio.AudioChannelPosition.MONO]) 
     sink = interleave.get_request_pad('sink_0') 
     queueSink = queue.get_static_pad('sink') 
     queueSrc = queue.get_static_pad('src') 
     queueSrc.link(sink) 
     ghostpad = Gst.GhostPad.new('sink_0', queueSink) 
     bin.add_pad(ghostpad) 
    elif sinks == 2: 
     queue0 = Gst.ElementFactory.make('queue', 'Queue L') 
     queue1 = Gst.ElementFactory.make('queue', 'Queue R') 
     bin.add(queue0) 
     bin.add(queue1) 
     interleave.set_property('channel_positions', [ 
      GstAudio.AudioChannelPosition.FRONT_LEFT, 
      GstAudio.AudioChannelPosition.FRONT_RIGHT 
     ]) 
     sink0 = interleave.get_request_pad('sink_0') 
     queueSink0 = queue0.get_static_pad('sink') 
     queueSrc0 = queue0.get_static_pad('src') 
     queueSrc0.link(sink0) 
     ghostpad0 = Gst.GhostPad.new('sink_0', queueSink0) 
     sink1 = interleave.get_request_pad('sink_1') 
     queueSink1 = queue1.get_static_pad('sink') 
     queueSrc1 = queue1.get_static_pad('src') 
     queueSrc1.link(sink1) 
     ghostpad1 = Gst.GhostPad.new('sink_1', queueSink1) 
     bin.add_pad(ghostpad0) 
     bin.add_pad(ghostpad1) 
    return bin 

这是不是特别干净,但它似乎做工精细所以现在我会坚持下去。

相关问题