# Transmageddon
# Copyright (C) 2009-2011 Christian Schaller <uraeus@gnome.org>
# 
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This librarmy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import sys
import os

os.environ["GST_DEBUG_DUMP_DOT_DIR"] = "/tmp"

from gi.repository import GObject
GObject.threads_init()
from gi.repository import GLib
from gi.repository import Gst
Gst.init(None)
from gi.repository import GstPbutils

class Mixer(GObject.GObject):

   __gsignals__ = {
            'ready-for-querying' : (GObject.SignalFlags.RUN_LAST, None, []),
            'got-eos' : (GObject.SignalFlags.RUN_LAST, None, []),
            'missing-plugin' : (GObject.SignalFlags.RUN_LAST, None, []),
            'got-error' : (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_PYOBJECT,))
                    }

   def __init__(self):
       self.mainloop = GObject.MainLoop()
       GObject.GObject.__init__(self)
       
       # Create transcoding pipeline
       self.pipeline = Gst.Pipeline()
       self.pipeline.set_state(Gst.State.PAUSED)

       self.videoenc = Gst.ElementFactory.make("x264enc", None)
       self.pipeline.add(self.videoenc)

       self.audioenc = Gst.ElementFactory.make("faac", None)
       self.pipeline.add(self.audioenc)

       factory=self.audioenc.get_factory()
       print(factory)
       if factory != None:
           # Set Transmageddon as Application name using Tagsetter interface
           tagyes = factory.has_interface("GstTagSetter")
           if tagyes ==True:
               taglist=Gst.TagList.new_empty()
               taglist.add_value(Gst.TagMergeMode.APPEND, Gst.TAG_APPLICATION_NAME, "Testmageddon transcoder")
               self.audioenc.merge_tags(taglist, Gst.TagMergeMode.REPLACE)
           if Gst.ElementFactory.list_is_type(factory, 1125899906842626): # Audio Encoders factory code
                   print("got audio encoder")
                   taglist=Gst.TagList.new_empty()
                   taglist.add_value(Gst.TagMergeMode.APPEND, Gst.TAG_LANGUAGE_CODE, "fr") #set language to french
                   longname=factory.get_metadata('long-name') # get longname to set encoder tag
                   taglist.add_value(Gst.TagMergeMode.APPEND, Gst.TAG_ENCODER, longname)
                   self.audioenc.merge_tags(taglist, Gst.TagMergeMode.REPLACE)
  
       self.muxer = Gst.ElementFactory.make('qtmux', None)
       self.pipeline.add(self.muxer)

       self.filesink = Gst.ElementFactory.make('filesink', None)
       self.filesink.set_property("location", "/home/cschalle/Videos/testclip-out.mov")
       self.pipeline.add(self.filesink)


       self.videoenc.link(self.muxer)
       self.audioenc.link(self.muxer)
       self.muxer.link(self.filesink)
       self.audioenc.set_state(Gst.State.PAUSED)
       self.videoenc.set_state(Gst.State.PAUSED)
       self.muxer.set_state(Gst.State.PAUSED)

       self.uridecoder = Gst.ElementFactory.make("uridecodebin", "uridecoder")
       self.uridecoder.set_property("uri", "file:///home/cschalle/Videos/testclip.ogg" )
       self.uridecoder.connect("pad-added", self.OnDynamicPad)
       self.pipeline.add(self.uridecoder)
       self.uridecoder.set_state(Gst.State.PAUSED)

       # we need to wait on this one before going further
       self.uridecoder.connect("no-more-pads", self.noMorePads)

       self.BusMessages = self.BusWatcher()

       self.mainloop.run()

   def noMorePads(self, dbin):
       Gst.debug_bin_to_dot_file (self.pipeline, Gst.DebugGraphDetails.ALL, 'testmageddon-quicktime')
       self.muxer.set_state(Gst.State.PAUSED)
       self.filesink.set_state(Gst.State.PAUSED)
       GLib.idle_add(self.idlePlay)

   def idlePlay(self):
        # print("going to playing")
        self.pipeline.set_state(Gst.State.PLAYING)

   def BusWatcher(self):
     bus = self.pipeline.get_bus()
     bus.add_signal_watch()
     bus.connect('message', self.on_message)

   def on_message(self, bus, message):
       mtype = message.type
       if mtype == Gst.MessageType.ERROR:
           print("we got an error, life is shit")
           err, debug = message.parse_error()
           print(err) 
           print(debug)
           Gst.debug_bin_to_dot_file (self.pipeline, \
           Gst.DebugGraphDetails.ALL, 'testmageddon-error')
       elif mtype == Gst.MessageType.ELEMENT:
           if GstPbutils.is_missing_plugin_message(message):
               if self.missingplugin==False:
                   self.missingplugin=message
                   self.emit('missing-plugin')
           
       elif mtype == Gst.MessageType.ASYNC_DONE:
           self.emit('ready-for-querying')
       elif mtype == Gst.MessageType.EOS:
           self.emit('got-eos')
           self.pipeline.set_state(Gst.State.NULL)
           self.mainloop.quit()
       elif mtype == Gst.MessageType.APPLICATION:
           self.pipeline.set_state(Gst.State.NULL)
           self.pipeline.remove(self.uridecoder)
       return True

   def OnDynamicPad(self, uridecodebin, src_pad):
       origin = src_pad.query_caps(None)
       c = origin.to_string()
       # print(c)
       if not c.startswith("text/"):
               if c.startswith("audio/"):
                       apad1=self.audioenc.get_compatible_pad(src_pad, None)
                       src_pad.link(apad1)
               elif (c.startswith("video/") or c.startswith("image/")):
                       vconvert1pad=self.videoenc.get_compatible_pad(src_pad, None)
                       src_pad.link(vconvert1pad)


if __name__ == "__main__":
    app = Mixer()
