Simultaneously play two audio files (pygst)

David Banks amoebae at gmail.com
Mon Dec 17 09:43:01 PST 2012


Hi,

I think I am missing something obvious.  I want to make a program that
plays two audio files at the same time, mixing them.  My basic pipeline
looks like:

filesrc -> decodebin
                     -> adder -> audioconvert -> autoaudiosink
filesrc -> decodebin

I made the program below to try to realize this.  However, when I run it
I get the following error:

  amoe at vuurvlieg $ python gstreamer.py test.mp3 test2.mp3
  Traceback (most recent call last):
    File "gstreamer.py", line 58, in on_new_decoded_pad
      decode.link(adder)
  gst.LinkError: failed to link decode1 with adder
  Fatal Python error: PyEval_RestoreThread: NULL tstate
  zsh: abort (core dumped)  python gstreamer.py test.mp3 test.mp3

I don't see where the problem is.  I try to link the decodebin to the
adder in the callback 'on_new_decoded_pad' as I believe is necessary,
but the link fails, but I'm not sure why.  Also I'm not sure why the
library is aborting -- presumably I'm making some gross usage error
somewhere.  Can anyone help?  [code below]

Cheers,
Dave

import gst
import sys
import pygtk, gtk, gobject
import pdb
import glib

class MyTest():
    player = None
    pipeline = None

    def run(self, args):
        self.pipeline = gst.Pipeline('pipeline')

        filesrc1 = gst.element_factory_make("filesrc", "filesrc1")
        filesrc1.set_property("location", args[0])

        filesrc2 = gst.element_factory_make("filesrc", "filesrc2")
        filesrc2.set_property("location", args[1])

        decode1 = gst.element_factory_make("decodebin", "decode1")
        decode2 = gst.element_factory_make("decodebin", "decode2")
        adder = gst.element_factory_make("adder", "adder")
        convert = gst.element_factory_make('audioconvert', 'convert')
        sink = gst.element_factory_make("autoaudiosink", "sink")

        self.pipeline.add(filesrc1, decode1, filesrc2, decode2, adder,
convert, sink)

        gst.element_link_many(filesrc1, decode1)
        gst.element_link_many(filesrc2, decode2)
        gst.element_link_many(adder, convert)
        gst.element_link_many(convert, sink)

        decode1.connect("new-decoded-pad", self.on_new_decoded_pad)
        decode2.connect("new-decoded-pad", self.on_new_decoded_pad)
        bus = self.pipeline.get_bus()

        bus.add_signal_watch()
        bus.connect("message", self.on_message)

        self.pipeline.set_state(gst.STATE_PAUSED)

        gtk.gdk.threads_init()
        gtk.main()

    def on_message(self, bus, message):
        t = message.type
        if t == gst.MESSAGE_EOS:
            self.pipeline.set_state(gst.STATE_NULL)
        elif t == gst.MESSAGE_ERROR:
            self.pipeline.set_state(gst.STATE_NULL)
            err, debug = message.parse_error()
            print "Error: %s" % err, debug

    def on_new_decoded_pad(self, dbin, pad, islast):
        decode = pad.get_parent()
        pipeline = decode.get_parent()
        adder = pipeline.get_by_name('adder')
        decode.link(adder)

if __name__ == "__main__":
    obj = MyTest()
    obj.run(sys.argv[1:])

-- 
David Banks  <amoebae at gmail.com>


More information about the gstreamer-devel mailing list