1

Python 3.x で gstreamer をオーディオ エンコーディングに使用し、後でストリーミングに使用する方法を実験しようとしていますが、残念ながら行き詰まりました。

正常に動作するこのシンプルなオーディオ プレーヤーを見つけました。

import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk

# Initializing threads used by the Gst various elements
GObject.threads_init()
#Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Gst.init(None)

class Main:
    def __init__(self):
        self.mainloop = GObject.MainLoop()
        #Creating the gst pipeline we're going to add elements to and use to play the file
        self.pipeline = Gst.Pipeline()

        #creating the filesrc element, and adding it to the pipeline
        self.filesrc = Gst.ElementFactory.make("filesrc", "filesrc")
        self.filesrc.set_property("location", "beatles.mp3")
        self.pipeline.add(self.filesrc)

        #creating and adding the decodebin element , an "automagic" element able to configure itself to decode pretty much anything
        self.decode = Gst.ElementFactory.make("decodebin", "decode")
        self.pipeline.add(self.decode)
        #connecting the decoder's "pad-added" event to a handler: the decoder doesn't yet have an output pad (a source), it's created at runtime when the decoders starts receiving some data
        self.decode.connect("pad-added", self.decode_src_created)

        #setting up (and adding) the alsasin, which is actually going to "play" the sound it receives
        self.sink = Gst.ElementFactory.make("alsasink", "sink")
        self.pipeline.add(self.sink)

        #linking elements one to another (here it's just the filesrc - > decoder link , the decoder -> sink link's going to be set up later)
        self.filesrc.link(self.decode)

    #handler taking care of linking the decoder's newly created source pad to the sink
    def decode_src_created(self, element, pad):
        pad.link(self.sink.get_static_pad("sink"))

    #running the shit
    def run(self):
        self.pipeline.set_state(Gst.State.PLAYING)
        self.mainloop.run()

start=Main()
start.run()

次に、間に speexenc 要素と speexdec 要素を追加しようとしました。「# ADDED」で示される 6 行と「# MODIFIED」で示される 1 行を参照してください。この特定のケースでは、speex を介したエンコードとデコードが意味をなさないことはわかっていますが、python 3.x ではこの問題に関するチュートリアルと例が不足しているため、基本的な gstreamer のドキュメントと FAQ を読んだ後、何らかの方法で実験を開始したいと思いました。エラーメッセージはありませんが、最終的には何も再生されず、スピーカーは無音です:

import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk

# Initializing threads used by the Gst various elements
GObject.threads_init()
#Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Gst.init(None)

class Main:
    def __init__(self):
        self.mainloop = GObject.MainLoop()
        #Creating the gst pipeline we're going to add elements to and use to play the file
        self.pipeline = Gst.Pipeline()

        #creating the filesrc element, and adding it to the pipeline
        self.filesrc = Gst.ElementFactory.make("filesrc", "filesrc")
        self.filesrc.set_property("location", "beatles.mp3")
        self.pipeline.add(self.filesrc)

        #creating and adding the decodebin element , an "automagic" element able to configure itself to decode pretty much anything
        self.decode = Gst.ElementFactory.make("decodebin", "decode")
        self.pipeline.add(self.decode)
        #connecting the decoder's "pad-added" event to a handler: the decoder doesn't yet have an output pad (a source), it's created at runtime when the decoders starts receiving some data
        self.decode.connect("pad-added", self.decode_src_created)

        self.speexenc = Gst.ElementFactory.make("speexenc", "speexenc") # ADDED
        self.pipeline.add(self.speexenc) # ADDED

        self.speexdec = Gst.ElementFactory.make("speexdec", "speexdec") # ADDED
        self.pipeline.add(self.speexdec) # ADDED

        #setting up (and adding) the alsasin, which is actually going to "play" the sound it receives
        self.sink = Gst.ElementFactory.make("alsasink", "sink")
        self.pipeline.add(self.sink)

        #linking elements one to another
        self.filesrc.link(self.decode)
        self.speexenc.link(self.speexdec) # ADDED
        self.speexdec.link(self.sink) # ADDED

    #handler taking care of linking the decoder's newly created source pad to the speexenc
    def decode_src_created(self, element, pad):
        pad.link(self.speexenc.get_static_pad("sink")) # MODIFIED

    #running the shit
    def run(self):
        self.pipeline.set_state(Gst.State.PLAYING)
        self.mainloop.run()

start=Main()
start.run()

最終的に機能させるための提案は大歓迎です! よろしくお願いします!

編集: GST_DEBUG="*:3" の出力

** (GsTest04.py:2500): WARNING **: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files
0:00:00.310035438  2500  0x25b7290 FIXME                  id3v2      gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.310425594  2500  0x25b7290 FIXME                  id3v2 gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.310597677  2500  0x25b7290 FIXME                  id3v2 gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.310753458  2500  0x25b7290 FIXME                  id3v2 gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.310931687  2500  0x25b7290 FIXME                  id3v2 gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.311063614  2500  0x25b7290 FIXME                  id3v2 gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.311322155  2500  0x25b7290 FIXME                  id3v2 gstid3tag.c:142:gst_tag_from_id3_tag: Cannot map ID3v2 tag 'PRIV' to GStreamer tag
0:00:00.376435699  2500 0x741014f0 WARN                    alsa conf.c:4544:parse_args: alsalib error: Unknown parameter AES0
0:00:00.376732365  2500 0x741014f0 WARN                    alsa conf.c:4704:snd_config_expand: alsalib error: Parse arguments error: No such file or directory
0:00:00.376897261  2500 0x741014f0 WARN                    alsa pcm.c:2217:snd_pcm_open_noupdate: alsalib error: Unknown PCM default:{AES0 0x02 AES1 0x82 AES2 0x00 AES3 0x02}
0:00:00.378137573  2500 0x741014f0 WARN               baseparse gstbaseparse.c:3188:gst_base_parse_loop:<mpegaudioparse0> error: streaming stopped, reason not-linked
4

1 に答える 1

2

明らかに間違っているものは何も見えません。GST_DEBUG="*:3" を使用してプログラムを実行し、ログに警告があるかどうかを確認することをお勧めします。また、すべての API 呼び出しが機能したことを再確認することもできます。(例えば、

self.speexenc = Gst.ElementFactory.make(...)

にはなりませんでしたNone。また、decode_src_created の pad.link() の戻り値も確認します。デコーダーによって生成された生のオーディオが speexenc が好むものではない場合、リンクは失敗します。スピーチの前に audioconvert 要素を追加してみてください。

于 2015-09-15T15:54:54.650 に答える