#!/usr/bin/python
import sys
import gobject
gobject.threads_init()
import gst
from singledecodebin import SingleDecodeBin

audio_caps = gst.Caps("audio/x-vorbis")

def make_source(filename, inpoint, outpoint, position):
    """ Creates a source for the given:
    * filename
    * inpoint (in seconds)
    * outpoint (in seconds)
    * position (in nanoseconds)

    Returns (updatedposition, source)"""
    duration = outpoint - inpoint

    agnls = gst.element_factory_make("gnlsource")
    agnls.props.duration = int(duration * gst.SECOND)
    agnls.props.media_duration = int(duration * gst.SECOND)
    agnls.props.media_start = int(inpoint * gst.SECOND)
    agnls.props.start = position
    agnls.add(SingleDecodeBin(uri="file://"+filename, caps=audio_caps))

    return (int(position + duration * gst.SECOND), agnls)

class GstChop(object):
    def __init__(self, edlfile, output):
        self.pipeline = gst.Pipeline()
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect("message", self._busMessageCb)

        #output
        self.mux = gst.element_factory_make("oggmux")
        self.fsink = gst.element_factory_make("filesink")
        self.fsink.props.location = output
        self.pipeline.add(self.mux, self.fsink)

        #audio input
        self.aqueue = gst.element_factory_make("queue")
        self.acomp = gst.element_factory_make("gnlcomposition")
        self.acomp.connect("pad-added", self._acompPadAddedCb)
        self.pipeline.add(self.acomp, self.aqueue)
        gst.element_link_many(self.mux, self.fsink)
        self.aqueue.link(self.mux, audio_caps)

        self.mainloop = gobject.MainLoop()
        self.readfile(edlfile)

    def readfile(self, edlfile):
        """Parse the given EDL and fill in
        the composition"""
        position = 0
        for lin in open(edlfile).readlines():
            inpoint, outpoint, filename = lin.strip().split()
            print "Adding %s at %ss [%ss - %ss]" % (filename, position/gst.SECOND,
                                             inpoint, outpoint)
            position, gnls = make_source(filename, float(inpoint),
                                         float(outpoint), position)
            self.acomp.add(gnls)

    def start(self):
        self.pipeline.set_state(gst.STATE_PLAYING)
        self.mainloop.run()

    def _acompPadAddedCb(self, acomp, new_pad):
        acomp.link(self.aqueue)

    def _busMessageCb(self, bus, message):
        if message.type == gst.MESSAGE_ERROR:
            print "An error happened, exiting"
            print message
        elif message.type == gst.MESSAGE_EOS:
            print "Playback ended, exiting"
            self.mainloop.quit()

chop = GstChop(sys.argv[1], sys.argv[2])
chop.start()
