from gi.repository import Gst
from gi.repository import GObject

class Track:

    def __init__(self, pipeline):
        self.comp = Gst.ElementFactory.make("gnlcomposition")
        self.pad_added_handler = self.comp.connect("pad-added", self.on_composition_pad_added)
        pipeline.add(self.comp)
        self.comp.set_state(Gst.State.PLAYING)

    def on_composition_pad_added(self, comp, pad):
        caps = pad.get_caps()
        self.srcpad = pad
        if not comp.get_parent() or not adder.get_parent():
            return
        Gst.Element.link(comp, adder)

    def on_src_blocked(self, pad, blocked):
        global tracks, action
    
        sink = self.srcpad.get_peer()
        Gst.Element.unlink(self.comp, adder)
        adder.release_request_pad(sink)
        #self.comp.set_state(Gst.State.NULL)
        pipeline.remove(self.comp)
        if not tracks:
            action = ACTION_ADD_TRACK
        gobject.idle_add(go)
        
def go():
    global num_tracks, tracks, action
    
    if action == ACTION_ADD_TRACK:
        track = Track(pipeline)
        print "Add Track"
        tracks.append(track)
        action = ACTION_ADD_EVENT
    elif action == ACTION_ADD_EVENT:
        print "Add Event"

        track = tracks[-1]
        silence = Gst.ElementFactory.make("audiotestsrc")
        silence.set_property("wave", "silence")
        src = Gst.ElementFactory.make("gnlsource")
        src.add(silence)
        src.set_property("start", 0 * Gst.SECOND)
        src.set_property("duration", 1000 * Gst.SECOND)
        track.comp.add(src)
        
        if len(tracks) < 3:
            action = ACTION_ADD_TRACK
        else:
            action = ACTION_REMOVE_TRACK
    else:
        print "Remove Track"
        track = tracks.pop()
        try:
            track.srcpad.set_blocked_async(True, track.on_src_blocked)
            return False
        except AttributeError:
            # srcpad has not been created yet
            track.comp.set_state(Gst.State.NULL)
            track.comp.disconnect(track.pad_added_handler)
            pipeline.remove(track.comp)
            if not tracks:
                action = ACTION_ADD_TRACK
    return True

adder = Gst.ElementFactory.make("adder")
sink = Gst.ElementFactory.make("alsasink")
pipeline = Gst.ElementFactory.make("pipeline")
pipeline.add(adder, sink)
Gst.Element.link(adder, sink)

ACTION_ADD_TRACK = 0
ACTION_ADD_EVENT = 1
ACTION_REMOVE_TRACK = 2
action = ACTION_ADD_TRACK

tracks = []

GObject.idle_add(go)
pipeline.set_state(Gst.State.PLAYING)
GObject.MainLoop().run()
pipeline.set_state(Gst.State.NULL)
