gstreamerパイプラインのインターリーブ要素の使用に問題があります。2つのシンクを持つインターリーブ要素を使用するとGstパイプラインが実行されない
私はInput(autoaudiosrc)のオーディオをT字に読み込んで、ディスクに書き込んでリアルタイムでオーディオレベルを取得できます(ハードウェアのvuメーターにフィードを渡すことができます。レベルから標準出力まで)。 1つまたは2つのチャンネルを使用して別々のファイルに書き込むことができるので、6つの入力チャンネルを5つのファイル(1つのステレオ、4つのモノラル)に分割できます。 すべてのファイルを1つのファイルに書き込んだ後、デインタリーブ要素を追加してすべてをモノラルファイルに分割しましたが、2つのチャネルを1つのステレオチャネルに結合するとパイプライン全体が破損します。
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
これは、1つまたは2つのチャネルをディスクに書き込むための新しいビンを作成するコードです。私が1つのシンクパッドに接続すると(そしてシンクを1に設定すると)すべて正常に動作しますが、2つのシンクパッドを接続してシンクを2に設定すると、ファイルが作成されますが、パイプはスタックしているようです。レベルはプリントアウトされず、データもファイルに書き込まれません。
私は要点に完全なファイルを添付しましたが、これはプロトタイプコードですが、私がこれをリファクタリングする前に、必要なものすべてを動作させたいと思います。
https://gist.github.com/maxjoehnk/16785499db6e864bf120cf85a81b1ecf
完全なパイプラインがどのように正確に見えるかわかりません。しかし、すべてのオーディオは1つのスレッド(同じオーディオソース)から来ているからです。私はインターリーブ要素がそれ自身をブロックすることを期待するでしょう。インタリーブシンクパッドの前にキューエレメントを追加してみてください。 –
今、私は信号を2つのキューに分けています.1つはレベル要素用で、もう1つはdeinterleave要素用です。完全なパイプラインのソースコードは、私がリンクした要点にあります。パッドごと、または要素ごとにキューを追加する必要がありますか?インターリーブ要素のすぐ後ろにキューがあるので、どのように前に追加するのかよく分かりません –