Ejemplo n.º 1
0
    def __init__(self, ventana_id):

        gobject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.video = False
        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0
        self.posicion = 0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = gst.element_factory_make("playbin2", "player")
        self.player.set_property("buffer-size", 50000)

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        #self.bus.set_sync_handler(self.__bus_handler)
        self.bus.add_signal_watch()  # ****
        self.bus.connect('message', self.__on_mensaje)  # ****
        self.bus.enable_sync_message_emission()  # ****
        self.bus.connect('sync-message', self.__sync_message)  # ****
Ejemplo n.º 2
0
    def __init__(self, ventana_id):
        """
        Recibe el id de un DrawingArea
        para mostrar el video.
        """

        gobject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0
        self.posicion = 0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = gst.element_factory_make(
            "playbin2", "player")

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        self.bus.set_sync_handler(self.__bus_handler)
Ejemplo n.º 3
0
    def __init__(self, ventana_id):

        gobject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.video = False
        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0.0
        self.posicion = 0.0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = gst.element_factory_make("playbin2", "player")
        self.player.set_property("buffer-size", 50000)

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        self.bus.add_signal_watch()
        self.bus.connect('message', self.__on_mensaje)
        self.bus.enable_sync_message_emission()
        self.bus.connect('sync-message', self.__sync_message)
Ejemplo n.º 4
0
    def __init__(self, ventana_id):
        """
        Recibe el id de un DrawingArea
        para mostrar el video.
        """

        GObject.GObject.__init__(self)

        self.name = "JAMediaReproductor"
        self.ventana_id = ventana_id

        self.estado = None
        self.volumen = 0.10
        self.config = {
            'saturacion': 50.0,
            'contraste': 50.0,
            'brillo': 50.0,
            'hue': 50.0,
            'gamma': 10.0,
            'rotacion': 0
        }

        self.duracion = 0
        self.posicion = 0
        self.actualizador = False

        self.player = None
        self.bus = None

        from JAMediaBins import JAMedia_Video_Pipeline
        from JAMediaBins import JAMedia_Audio_Pipeline

        # Gestor de la salida de Video del reproductor.
        self.video_pipeline = JAMedia_Video_Pipeline()

        # Gestor de salida de Audio del reproductor.
        self.audio_pipelin = JAMedia_Audio_Pipeline()

        # Debe iniciarse como None (ver señal video)
        self.video_in_stream = None

        self.efectos = []
        #self.config_efectos = {}

        self.__reset()
Ejemplo n.º 5
0
    def __init__(self, ventana_id):
        """
        Recibe el id de un DrawingArea
        para mostrar el video.
        """

        GObject.GObject.__init__(self)

        self.name = "JAMediaReproductor"
        self.ventana_id = ventana_id

        self.estado = None
        self.volumen = 0.10
        self.config = {
            'saturacion': 50.0,
            'contraste': 50.0,
            'brillo': 50.0,
            'hue': 50.0,
            'gamma': 10.0,
            'rotacion': 0}

        self.duracion = 0
        self.posicion = 0
        self.actualizador = False

        self.player = None
        self.bus = None

        from JAMediaBins import JAMedia_Video_Pipeline
        from JAMediaBins import JAMedia_Audio_Pipeline

        # Gestor de la salida de Video del reproductor.
        self.video_pipeline = JAMedia_Video_Pipeline()

        # Gestor de salida de Audio del reproductor.
        self.audio_pipelin = JAMedia_Audio_Pipeline()

        # Debe iniciarse como None (ver señal video)
        self.video_in_stream = None

        self.efectos = []
        #self.config_efectos = {}

        self.__reset()
Ejemplo n.º 6
0
class JAMediaReproductor(gobject.GObject):

    __gsignals__ = {
        "endfile": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
        "estado":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
        "newposicion":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, )),
        "video":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN, )),
        "loading-buffer":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, )),
    }

    # Estados: playing, paused, None

    def __init__(self, ventana_id):

        gobject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.video = False
        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0
        self.posicion = 0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = gst.element_factory_make("playbin2", "player")
        self.player.set_property("buffer-size", 50000)

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        #self.bus.set_sync_handler(self.__bus_handler)
        self.bus.add_signal_watch()  # ****
        self.bus.connect('message', self.__on_mensaje)  # ****
        self.bus.enable_sync_message_emission()  # ****
        self.bus.connect('sync-message', self.__sync_message)  # ****

    def __sync_message(self, bus, message):
        if message.type == gst.MESSAGE_ELEMENT:
            if message.structure.get_name() == 'prepare-xwindow-id':
                gtk.gdk.threads_enter()
                gtk.gdk.display_get_default().sync()
                message.src.set_xwindow_id(self.ventana_id)
                gtk.gdk.threads_leave()

        elif message.type == gst.MESSAGE_STATE_CHANGED:
            old, new, pending = message.parse_state_changed()

            if self.estado != new:
                self.estado = new

                if new == gst.STATE_PLAYING:
                    self.emit("estado", "playing")
                    self.__new_handle(True)

                elif new == gst.STATE_PAUSED:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

                elif new == gst.STATE_NULL:
                    self.emit("estado", "None")
                    self.__new_handle(False)

                else:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

        elif message.type == gst.MESSAGE_TAG:
            taglist = message.parse_tag()
            datos = taglist.keys()
            if 'video-codec' in datos:
                if self.video == False or self.video == None:
                    self.video = True
                    self.emit("video", self.video)

        elif message.type == gst.MESSAGE_LATENCY:
            self.player.recalculate_latency()

        elif message.type == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

    def __on_mensaje(self, bus, message):
        if message.type == gst.MESSAGE_EOS:
            self.__new_handle(False)
            self.emit("endfile")

        elif message.type == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

        elif message.type == gst.MESSAGE_BUFFERING:
            buf = int(message.structure["buffer-percent"])
            if buf < 100 and self.estado == gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__pause()

            elif buf > 99 and self.estado != gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__play()

    '''
    def __bus_handler(self, bus, message):
        if message.type == gst.MESSAGE_ELEMENT:
            if message.structure.get_name() == 'prepare-xwindow-id':
                gtk.gdk.threads_enter()
                gtk.gdk.display_get_default().sync()
                message.src.set_xwindow_id(self.ventana_id)
                gtk.gdk.threads_leave()

        elif message.type == gst.MESSAGE_BUFFERING:
            buf = int(message.structure["buffer-percent"])
            if buf < 100 and self.estado == gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__pause()

            elif buf > 99 and self.estado != gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__play()

        elif message.type == gst.MESSAGE_STATE_CHANGED:
            old, new, pending = message.parse_state_changed()

            if self.estado != new:
                self.estado = new

                if new == gst.STATE_PLAYING:
                    self.emit("estado", "playing")
                    self.__new_handle(True)

                elif new == gst.STATE_PAUSED:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

                elif new == gst.STATE_NULL:
                    self.emit("estado", "None")
                    self.__new_handle(False)

                else:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

        elif message.type == gst.MESSAGE_EOS:
            self.__new_handle(False)
            self.emit("endfile")

        elif message.type == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

        elif message.type == gst.MESSAGE_LATENCY:
            self.player.recalculate_latency()

        elif message.type == gst.MESSAGE_TAG:
            taglist = message.parse_tag()
            datos = taglist.keys()

            if 'video-codec' in datos:
                if self.video == False or self.video == None:
                    self.video = True
                    self.emit("video", self.video)

        return gst.BUS_PASS
    '''

    def __play(self):
        self.player.set_state(gst.STATE_PLAYING)

    def __pause(self):
        self.player.set_state(gst.STATE_PAUSED)

    def __new_handle(self, reset):
        if self.actualizador:
            gobject.source_remove(self.actualizador)
            self.actualizador = False

        if reset:
            self.actualizador = gobject.timeout_add(500, self.__handle)

    def __handle(self):
        if not self.progressbar:
            return True

        valor1 = None
        valor2 = None
        pos = None
        duracion = None

        try:
            valor1, bool1 = self.player.query_duration(gst.FORMAT_TIME)
            valor2, bool2 = self.player.query_position(gst.FORMAT_TIME)

        except:
            if PR:
                print "ERROR en HANDLER"
            return True

        if valor1 != None:
            duracion = valor1 / 1000000000

        if valor2 != None:
            posicion = valor2 / 1000000000

        if duracion == 0 or duracion == None:
            return True

        pos = int(posicion * 100 / duracion)

        if pos < 0 or pos > self.duracion:
            return True

        if self.duracion != duracion:
            self.duracion = duracion

        if pos != self.posicion:
            self.posicion = pos
            self.emit("newposicion", self.posicion)

        return True

    def pause_play(self):
        if self.estado == gst.STATE_PAUSED or self.estado == gst.STATE_NULL \
            or self.estado == gst.STATE_READY:
            self.__play()

        elif self.estado == gst.STATE_PLAYING:
            self.__pause()

    def rotar(self, valor):
        self.video_bin.rotar(valor)

    def set_balance(self,
                    brillo=False,
                    contraste=False,
                    saturacion=False,
                    hue=False,
                    gamma=False):
        self.video_bin.set_balance(brillo=brillo,
                                   contraste=contraste,
                                   saturacion=saturacion,
                                   hue=hue,
                                   gamma=gamma)

    def get_balance(self):
        return self.video_bin.get_balance()

    def stop(self):
        self.__new_handle(False)
        self.player.set_state(gst.STATE_NULL)
        self.emit("newposicion", 0)

    def load(self, uri):
        if not uri:
            return

        if os.path.exists(uri):
            #direccion = gst.filename_to_uri(uri)
            direccion = "file://" + uri
            self.player.set_property("uri", direccion)
            self.progressbar = True
            self.__play()

        else:
            if gst.uri_is_valid(uri):
                self.player.set_property("uri", uri)
                self.progressbar = False
                self.__play()

        return False

    def set_position(self, posicion):
        if not self.progressbar:
            return

        if self.duracion < posicion:
            return

        if self.duracion == 0 or posicion == 0:
            return

        posicion = self.duracion * posicion / 100

        # http://pygstdocs.berlios.de/pygst-reference/gst-constants.html
        #self.player.set_state(gst.STATE_PAUSED)
        # http://nullege.com/codes/show/
        #   src@d@b@dbr-HEAD@trunk@[email protected]/72/gst.SEEK_TYPE_SET
        #self.player.seek(
        #    1.0,
        #    gst.FORMAT_TIME,
        #    gst.SEEK_FLAG_FLUSH,
        #    gst.SEEK_TYPE_SET,
        #    posicion,
        #    gst.SEEK_TYPE_SET,
        #    self.duracion)

        # http://nullege.com/codes/show/
        #   src@c@o@congabonga-HEAD@congaplayer@congalib@[email protected]/
        #   104/gst.SEEK_FLAG_ACCURATE
        event = gst.event_new_seek(
            1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
            gst.SEEK_TYPE_SET, posicion * 1000000000, gst.SEEK_TYPE_NONE,
            self.duracion * 1000000000)

        self.player.send_event(event)
        #self.player.set_state(gst.STATE_PLAYING)

    def set_volumen(self, volumen):
        self.player.set_property('volume', volumen / 10)

    def get_volumen(self):
        return self.player.get_property('volume') * 10
Ejemplo n.º 7
0
class JAMediaReproductor(gobject.GObject):

    __gsignals__ = {
    "endfile": (gobject.SIGNAL_RUN_LAST,
        gobject.TYPE_NONE, []),
    "estado": (gobject.SIGNAL_RUN_LAST,
        gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
    "newposicion": (gobject.SIGNAL_RUN_LAST,
        gobject.TYPE_NONE, (gobject.TYPE_INT,)),
    "video": (gobject.SIGNAL_RUN_LAST,
        gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,)),
    "loading-buffer": (gobject.SIGNAL_RUN_LAST,
        gobject.TYPE_NONE, (gobject.TYPE_INT, )),
        }

    # Estados: playing, paused, None

    def __init__(self, ventana_id):

        gobject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.video = False
        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0.0
        self.posicion = 0.0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = gst.element_factory_make("playbin2", "player")
        self.player.set_property("buffer-size", 50000)

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        self.bus.add_signal_watch()
        self.bus.connect('message', self.__on_mensaje)
        self.bus.enable_sync_message_emission()
        self.bus.connect('sync-message', self.__sync_message)

    def __sync_message(self, bus, message):
        if message.type == gst.MESSAGE_ELEMENT:
            if message.structure.get_name() == 'prepare-xwindow-id':
                #gtk.gdk.threads_enter()
                #gtk.gdk.display_get_default().sync()
                message.src.set_xwindow_id(self.ventana_id)
                #gtk.gdk.threads_leave()

        elif message.type == gst.MESSAGE_STATE_CHANGED:
            old, new, pending = message.parse_state_changed()
            if self.estado != new:
                self.estado = new
                if new == gst.STATE_PLAYING:
                    self.emit("estado", "playing")
                    self.__new_handle(True)
                elif new == gst.STATE_PAUSED:
                    self.emit("estado", "paused")
                    self.__new_handle(False)
                elif new == gst.STATE_NULL:
                    self.emit("estado", "None")
                    self.__new_handle(False)
                else:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

        elif message.type == gst.MESSAGE_TAG:
            taglist = message.parse_tag()
            datos = taglist.keys()
            if 'video-codec' in datos:
                if self.video == False or self.video == None:
                    self.video = True
                    self.emit("video", self.video)

        elif message.type == gst.MESSAGE_LATENCY:
            self.player.recalculate_latency()

        elif message.type == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

    def __on_mensaje(self, bus, message):
        if message.type == gst.MESSAGE_EOS:
            self.__new_handle(False)
            self.emit("endfile")

        elif message.type == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

        elif message.type == gst.MESSAGE_BUFFERING:
            buf = int(message.structure["buffer-percent"])
            if buf < 100 and self.estado == gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__pause()
            elif buf > 99 and self.estado != gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.play()

    def __pause(self):
        self.player.set_state(gst.STATE_PAUSED)

    def __new_handle(self, reset):
        if self.actualizador:
            gobject.source_remove(self.actualizador)
            self.actualizador = False
        if reset:
            self.actualizador = gobject.timeout_add(500, self.__handle)

    def __handle(self):
        if not self.progressbar:
            return True
        duracion = self.player.query_duration(gst.FORMAT_TIME)[0] / gst.SECOND
        posicion = self.player.query_position(gst.FORMAT_TIME)[0] / gst.SECOND
        pos = posicion * 100 / duracion
        if self.duracion != duracion:
            self.duracion = duracion
        if pos != self.posicion:
            self.posicion = pos
            self.emit("newposicion", self.posicion)
        return True

    def play(self):
        self.player.set_state(gst.STATE_PLAYING)

    def pause_play(self):
        if self.estado == gst.STATE_PAUSED or self.estado == gst.STATE_NULL \
            or self.estado == gst.STATE_READY:
            self.play()
        elif self.estado == gst.STATE_PLAYING:
            self.__pause()

    def rotar(self, valor):
        self.video_bin.rotar(valor)

    def set_balance(self, brillo=False, contraste=False,
        saturacion=False, hue=False, gamma=False):
        self.video_bin.set_balance(brillo=brillo, contraste=contraste,
            saturacion=saturacion, hue=hue, gamma=gamma)

    def get_balance(self):
        return self.video_bin.get_balance()

    def stop(self):
        self.__new_handle(False)
        self.player.set_state(gst.STATE_NULL)
        self.emit("newposicion", 0)

    def load(self, uri):
        if not uri:
            return False
        self.duracion = 0.0
        self.posicion = 0.0
        self.emit("newposicion", self.posicion)
        self.emit("loading-buffer", 100)
        if os.path.exists(uri):
            #direccion = gst.filename_to_uri(uri)
            direccion = "file://" + uri
            self.player.set_property("uri", direccion)
            self.progressbar = True
        else:
            if gst.uri_is_valid(uri):
                self.player.set_property("uri", uri)
                self.progressbar = False
        return False

    def set_position(self, posicion):
        if not self.progressbar:
            return
        if self.duracion < posicion:
            return
        if self.duracion == 0 or posicion == 0:
            return
        posicion = self.duracion * posicion / 100

        # http://pygstdocs.berlios.de/pygst-reference/gst-constants.html
        #self.player.set_state(gst.STATE_PAUSED)
        # http://nullege.com/codes/show/
        #   src@d@b@dbr-HEAD@trunk@[email protected]/72/gst.SEEK_TYPE_SET
        #self.player.seek(
        #    1.0,
        #    gst.FORMAT_TIME,
        #    gst.SEEK_FLAG_FLUSH,
        #    gst.SEEK_TYPE_SET,
        #    posicion,
        #    gst.SEEK_TYPE_SET,
        #    self.duracion)
        # http://nullege.com/codes/show/
        #   src@c@o@congabonga-HEAD@congaplayer@congalib@[email protected]/
        #   104/gst.SEEK_FLAG_ACCURATE

        event = gst.event_new_seek(
            1.0, gst.FORMAT_TIME,
            gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
            gst.SEEK_TYPE_SET, posicion * 1000000000,
            gst.SEEK_TYPE_NONE, self.duracion * 1000000000)
        self.player.send_event(event)
        #self.player.set_state(gst.STATE_PLAYING)

    def set_volumen(self, volumen):
        self.player.set_property('volume', volumen / 10)
Ejemplo n.º 8
0
class JAMediaReproductor(GObject.GObject):

    __gsignals__ = {
    "endfile": (GObject.SignalFlags.RUN_LAST,
        None, []),
    "estado": (GObject.SignalFlags.RUN_LAST,
        None, (GObject.TYPE_STRING,)),
    "newposicion": (GObject.SignalFlags.RUN_LAST,
        None, (GObject.TYPE_INT,)),
    "video": (GObject.SignalFlags.RUN_LAST,
        None, (GObject.TYPE_BOOLEAN,)),
    "loading-buffer": (GObject.SignalFlags.RUN_LAST,
        None, (GObject.TYPE_INT, )),
        }

    def __init__(self, ventana_id):

        GObject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.video = False
        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0.0
        self.posicion = 0.0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = Gst.ElementFactory.make("playbin2", "player")
        self.player.set_property("buffer-size", 50000)

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        self.bus.add_signal_watch()
        self.bus.connect('message', self.__on_mensaje)
        self.bus.enable_sync_message_emission()
        self.bus.connect('sync-message', self.__sync_message)

    def __sync_message(self, bus, message):
        if message.type == Gst.MessageType.ELEMENT:
            if message.structure.get_name() == 'prepare-xwindow-id':
                message.src.set_xwindow_id(self.ventana_id)

        elif message.type == Gst.MessageType.STATE_CHANGED:
            old, new, pending = message.parse_state_changed()

            if self.estado != new:
                self.estado = new

                if new == Gst.State.PLAYING:
                    self.emit("estado", "playing")
                    self.__new_handle(True)

                elif new == Gst.State.PAUSED:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

                elif new == Gst.State.NULL:
                    self.emit("estado", "None")
                    self.__new_handle(False)

                else:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

        elif message.type == Gst.MessageType.TAG:
            taglist = message.parse_tag()
            datos = taglist.keys()
            if 'video-codec' in datos:
                if self.video == False or self.video == None:
                    self.video = True
                    self.emit("video", self.video)

        elif message.type == Gst.MessageType.LATENCY:
            self.player.recalculate_latency()

        elif message.type == Gst.MessageType.ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

    def __on_mensaje(self, bus, message):
        if message.type == Gst.MessageType.EOS:
            self.__new_handle(False)
            self.emit("endfile")

        elif message.type == Gst.MessageType.ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

        elif message.type == Gst.MessageType.BUFFERING:
            buf = int(message.structure["buffer-percent"])
            if buf < 100 and self.estado == Gst.State.PLAYING:
                self.emit("loading-buffer", buf)
                self.__pause()

            elif buf > 99 and self.estado != Gst.State.PLAYING:
                self.emit("loading-buffer", buf)
                self.__play()

    def __play(self):
        self.player.set_state(Gst.State.PLAYING)

    def __pause(self):
        self.player.set_state(Gst.State.PAUSED)

    def __new_handle(self, reset):
        if self.actualizador:
            GLib.source_remove(self.actualizador)
            self.actualizador = False

        if reset:
            self.actualizador = GLib.timeout_add(500, self.__handle)

    def __handle(self):
        if not self.progressbar:
            return True

        duracion = self.player.query_duration(Gst.Format.TIME)[0] / Gst.SECOND
        posicion = self.player.query_position(Gst.Format.TIME)[0] / Gst.SECOND

        pos = posicion * 100 / duracion

        if self.duracion != duracion:
            self.duracion = duracion

        if pos != self.posicion:
            self.posicion = pos
            self.emit("newposicion", self.posicion)

        return True

    def pause_play(self):
        if self.estado == Gst.State.PAUSED or self.estado == Gst.State.NULL \
            or self.estado == Gst.State.READY:
            self.__play()

        elif self.estado == Gst.State.PLAYING:
            self.__pause()

    def rotar(self, valor):
        self.video_bin.rotar(valor)

    def set_balance(self, brillo=False, contraste=False,
        saturacion=False, hue=False, gamma=False):
        self.video_bin.set_balance(brillo=brillo, contraste=contraste,
            saturacion=saturacion, hue=hue, gamma=gamma)

    def get_balance(self):
        return self.video_bin.get_balance()

    def stop(self):
        self.__new_handle(False)
        self.player.set_state(Gst.State.NULL)
        self.emit("newposicion", 0)

    def load(self, uri):
        if not uri:
            return

        self.duracion = 0.0
        self.posicion = 0.0
        self.emit("newposicion", self.posicion)
        self.emit("loading-buffer", 100)

        if os.path.exists(uri):
            direccion = "file://" + uri
            self.player.set_property("uri", direccion)
            self.progressbar = True
            self.__play()

        else:
            if Gst.uri_is_valid(uri):
                self.player.set_property("uri", uri)
                self.progressbar = False
                self.__play()

        return False

    def set_position(self, posicion):
        if not self.progressbar:
            return

        if self.duracion < posicion:
            return

        if self.duracion == 0 or posicion == 0:
            return

        posicion = self.duracion * posicion / 100

        event = Gst.Event.new_seek(
            1.0, Gst.Format.TIME,
            Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
            Gst.SeekType.SET, posicion * 1000000000,
            Gst.SeekType.NONE, self.duracion * 1000000000)

        self.player.send_event(event)

    def set_volumen(self, volumen):
        self.player.set_property('volume', volumen / 10)

    def get_volumen(self):
        return self.player.get_property('volume') * 10
Ejemplo n.º 9
0
class JAMediaReproductor(gobject.GObject):
    """
    Reproductor de Streaming de Radio y Television.
    """

    __gsignals__ = {
    "endfile": (gobject.SIGNAL_RUN_CLEANUP,
        gobject.TYPE_NONE, []),
    "estado": (gobject.SIGNAL_RUN_CLEANUP,
        gobject.TYPE_NONE, (gobject.TYPE_STRING,)),
    "newposicion": (gobject.SIGNAL_RUN_CLEANUP,
        gobject.TYPE_NONE, (gobject.TYPE_INT,)),
    #"video": (gobject.SIGNAL_RUN_CLEANUP,
    #    gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,)),
        }

    # Estados: playing, paused, None

    def __init__(self, ventana_id):
        """
        Recibe el id de un DrawingArea
        para mostrar el video.
        """

        gobject.GObject.__init__(self)

        self.nombre = "JAMediaReproductor"

        self.ventana_id = ventana_id
        self.progressbar = True
        self.estado = None
        self.duracion = 0
        self.posicion = 0
        self.actualizador = False
        self.player = None
        self.bus = None

        self.player = gst.element_factory_make(
            "playbin2", "player")

        self.audio_bin = JAMedia_Audio_Pipeline()
        self.video_bin = JAMedia_Video_Pipeline()

        self.player.set_property('video-sink', self.video_bin)
        self.player.set_property('audio-sink', self.audio_bin)

        self.bus = self.player.get_bus()
        self.bus.set_sync_handler(self.__bus_handler)

    def __bus_handler(self, bus, message):

        if message.type == gst.MESSAGE_ELEMENT:
            if message.structure.get_name() == 'prepare-xwindow-id':
                message.src.set_xwindow_id(self.ventana_id)

        elif message.type == gst.MESSAGE_STATE_CHANGED:
            old, new, pending = message.parse_state_changed()

            if self.estado != new:
                self.estado = new

                if new == gst.STATE_PLAYING:
                    self.emit("estado", "playing")
                    self.__new_handle(True)

                elif new == gst.STATE_PAUSED:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

                elif new == gst.STATE_NULL:
                    self.emit("estado", "None")
                    self.__new_handle(False)

                else:
                    self.emit("estado", "paused")
                    self.__new_handle(False)

        elif message.type == gst.MESSAGE_EOS:
            self.__new_handle(False)
            self.emit("endfile")

        elif message.type == gst.MESSAGE_ERROR:
            err, debug = message.parse_error()
            if PR:
                print "JAMediaReproductor ERROR:"
                print "\t%s" % err
                print "\t%s" % debug
            self.__new_handle(False)

        elif message.type == gst.MESSAGE_LATENCY:
        #    http://cgit.collabora.com/git/farstream.git/
        #       tree/examples/gui/fs-gui.py
        #    print "\n gst.MESSAGE_LATENCY"
            self.player.recalculate_latency()

        #elif message.type == gst.MESSAGE_TAG:
        #    taglist = message.parse_tag()
        #    datos = taglist.keys()

        #    #for dato in datos:
        #    #    print dato, taglist[dato]

        #    if 'audio-codec' in datos and not 'video-codec' in datos:
        #        if self.video_in_stream == True or \
        #            self.video_in_stream == None:

        #            self.video_in_stream = False
        #            self.emit("video", False)
        #            #self.audio_pipeline.agregar_visualizador('monoscope')

        #    elif 'video-codec' in datos:
        #        if self.video_in_stream == False or \
        #            self.video_in_stream == None:

        #            self.video_in_stream = True
        #            self.emit("video", True)
        #            #self.audio_pipeline.quitar_visualizador()

        #else:
        #    print message.type, message.src

        return gst.BUS_PASS

    def __play(self):
        """
        Pone el pipe de gst en gst.STATE_PLAYING
        """

        self.player.set_state(gst.STATE_PLAYING)

    def __pause(self):
        """
        Pone el pipe de gst en gst.STATE_PAUSED
        """

        self.player.set_state(gst.STATE_PAUSED)

    def __new_handle(self, reset):
        """
        Elimina o reinicia la funcion que
        envia los datos de actualizacion para
        la barra de progreso del reproductor.
        """

        if self.actualizador:
            gobject.source_remove(self.actualizador)
            self.actualizador = False

        if reset:
            self.actualizador = gobject.timeout_add(500, self.__handle)

    def __handle(self):
        """
        Envia los datos de actualizacion para
        la barra de progreso del reproductor.
        """

        if not self.progressbar:
            return True

        valor1 = None
        valor2 = None
        pos = None
        duracion = None

        try:
            valor1, bool1 = self.player.query_duration(gst.FORMAT_TIME)
            valor2, bool2 = self.player.query_position(gst.FORMAT_TIME)

        except:
            if PR:
                print "ERROR en HANDLER"
            return True

        if valor1 != None:
            duracion = valor1 / 1000000000

        if valor2 != None:
            posicion = valor2 / 1000000000

        if duracion == 0 or duracion == None:
            return True

        pos = int(posicion * 100 / duracion)

        if pos < 0 or pos > self.duracion:
            return True

        if self.duracion != duracion:
            self.duracion = duracion

        if pos != self.posicion:
            self.posicion = pos
            self.emit("newposicion", self.posicion)

        return True

    def pause_play(self):
        """
        Llama a play() o pause()
        segun el estado actual del pipe de gst.
        """

        if self.estado == gst.STATE_PAUSED \
            or self.estado == gst.STATE_NULL \
            or self.estado == gst.STATE_READY:
            self.__play()

        elif self.estado == gst.STATE_PLAYING:
            self.__pause()

    def rotar(self, valor):
        """
        Rota el Video.
        """

        self.video_bin.rotar(valor)

    def set_balance(self, brillo=False, contraste=False,
        saturacion=False, hue=False, gamma=False):
        """
        Seteos de balance en video.
        Recibe % en float y convierte a los valores del filtro.
        """

        self.video_bin.set_balance(brillo=brillo, contraste=contraste,
            saturacion=saturacion, hue=hue, gamma=gamma)

    def get_balance(self):
        """
        Retorna los valores actuales de balance en % float.
        """

        return self.video_bin.get_balance()

    def stop(self):
        """
        Pone el pipe de gst en gst.STATE_NULL
        """

        self.player.set_state(gst.STATE_NULL)
        self.emit("newposicion", 0)

    def load(self, uri):
        """
        Carga un archivo o stream en el pipe de gst.
        """

        if os.path.exists(uri):
            #direccion = gst.filename_to_uri(uri)
            direccion = "file://" + uri
            self.player.set_property("uri", direccion)
            self.progressbar = True
            self.__play()

        else:
            if gst.uri_is_valid(uri):
                self.player.set_property("uri", uri)
                self.progressbar = False
                self.__play()

        return False

    def set_position(self, posicion):
        """
        Permite desplazarse por
        la pista que se esta reproduciendo.
        """

        if not self.progressbar:
            return

        if self.duracion < posicion:
            return

        if self.duracion == 0 or posicion == 0:
            return

        posicion = self.duracion * posicion / 100

        # http://pygstdocs.berlios.de/pygst-reference/gst-constants.html
        #self.player.set_state(gst.STATE_PAUSED)
        # http://nullege.com/codes/show/
        #   src@d@b@dbr-HEAD@trunk@[email protected]/72/gst.SEEK_TYPE_SET
        #self.player.seek(
        #    1.0,
        #    gst.FORMAT_TIME,
        #    gst.SEEK_FLAG_FLUSH,
        #    gst.SEEK_TYPE_SET,
        #    posicion,
        #    gst.SEEK_TYPE_SET,
        #    self.duracion)

        # http://nullege.com/codes/show/
        #   src@c@o@congabonga-HEAD@congaplayer@congalib@[email protected]/
        #   104/gst.SEEK_FLAG_ACCURATE
        event = gst.event_new_seek(
            1.0, gst.FORMAT_TIME,
            gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
            gst.SEEK_TYPE_SET, posicion * 1000000000,
            gst.SEEK_TYPE_NONE, self.duracion * 1000000000)

        self.player.send_event(event)
        #self.player.set_state(gst.STATE_PLAYING)

    def set_volumen(self, volumen):
        """
        Cambia el volúmen de Reproducción. (Recibe float 0.0 - 10.0)
        """

        self.player.set_property('volume', volumen / 10)

    def get_volumen(self):

        return self.player.get_property('volume') * 10
Ejemplo n.º 10
0
class JAMediaReproductor(GObject.GObject):
    """
    Reproductor de Audio, Video y Streaming de
    Radio y Television. Implementado sobre:

        python 2.7.3
        Gtk 3
        Gstreamer 1.0
    """

    __gsignals__ = {
    "endfile": (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, []),
    "estado": (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_STRING,)),
    "newposicion": (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_INT,)),
    "volumen": (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_FLOAT,)),
    "video": (GObject.SIGNAL_RUN_LAST,
        GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN,))}

    # Estados: playing, paused, None

    def __init__(self, ventana_id):
        """
        Recibe el id de un DrawingArea
        para mostrar el video.
        """

        GObject.GObject.__init__(self)

        self.name = "JAMediaReproductor"
        self.ventana_id = ventana_id

        self.estado = None
        self.volumen = 0.10
        self.config = {
            'saturacion': 50.0,
            'contraste': 50.0,
            'brillo': 50.0,
            'hue': 50.0,
            'gamma': 10.0,
            'rotacion': 0}

        self.duracion = 0
        self.posicion = 0
        self.actualizador = False

        self.player = None
        self.bus = None

        from JAMediaBins import JAMedia_Video_Pipeline
        from JAMediaBins import JAMedia_Audio_Pipeline

        # Gestor de la salida de Video del reproductor.
        self.video_pipeline = JAMedia_Video_Pipeline()

        # Gestor de salida de Audio del reproductor.
        self.audio_pipelin = JAMedia_Audio_Pipeline()

        # Debe iniciarse como None (ver señal video)
        self.video_in_stream = None

        self.efectos = []
        #self.config_efectos = {}

        self.__reset()

    def __reset(self):

        # Reproductor.
        self.player = Gst.ElementFactory.make(
            "playbin", "player")
        self.player.set_property(
            'force-aspect-ratio', True)

        # Si no se establecen los valores al original, se produce un error.
        self.video_pipeline.reset_balance()
        self.player.set_property('volume', self.volumen)

        self.player.set_window_handle(self.ventana_id)
        self.player.set_property('video-sink', self.video_pipeline)
        self.player.set_property('audio-sink', self.audio_pipelin)

        self.bus = self.player.get_bus()

        self.bus.enable_sync_message_emission()
        self.bus.connect('sync-message', self.__sync_message)

        #self.video_in_stream = False

    def __re_config(self):
        """
        Luego de que está en play,
        recupera los valores configurados para balance y
        rotación y configura con ellos el balance en el pipe.
        """

        self.player.set_property('volume', self.volumen)
        self.video_pipeline.set_rotacion(self.config['rotacion'])
        self.video_pipeline.set_balance(
            brillo=self.config['brillo'],
            contraste=self.config['contraste'],
            saturacion=self.config['saturacion'],
            hue=self.config['hue'],
            gamma=self.config['gamma'])
        self.emit('volumen', self.volumen)

        return False

    def __play(self):
        """
        Pone el pipe de Gst en Gst.State.PLAYING
        """

        self.player.set_state(Gst.State.PLAYING)

    def __pause(self):
        """
        Pone el pipe de Gst en Gst.State.PAUSED
        """

        self.player.set_state(Gst.State.PAUSED)

    def __new_handle(self, reset):
        """
        Elimina o reinicia la funcion que
        envia los datos de actualizacion para
        la barra de progreso del reproductor.
        """

        if self.actualizador:
            GLib.source_remove(self.actualizador)
            self.actualizador = False

        if reset:
            self.actualizador = GLib.timeout_add(500, self.__handle)

    def __handle(self):
        """
        Envia los datos de actualizacion para
        la barra de progreso del reproductor.
        """

        bool1, valor1 = self.player.query_duration(Gst.Format.TIME)
        bool2, valor2 = self.player.query_position(Gst.Format.TIME)

        duracion = float(valor1)
        posicion = float(valor2)

        pos = 0
        try:
            pos = int(posicion * 100 / duracion)

        except:
            pass

        if pos < 0 or pos > self.duracion:
            return True

        if self.duracion != duracion:
            self.duracion = duracion

        if pos != self.posicion:
            self.posicion = pos
            self.emit("newposicion", self.posicion)
            # print "***", gst.video_convert_frame(
            #   self.player.get_property("frame"))

        return True

    def __sync_message(self, bus, mensaje):
        """
        Captura los mensajes en el bus del pipe Gst.
        """

        """
        # Esto no es necesario si:
        # self.player.set_window_handle(self.ventana_id)
        try:
            if mensaje.get_structure().get_name() == 'prepare-window-handle':
                mensaje.src.set_window_handle(self.ventana_id)
                return

        except:
            pass"""

        if mensaje.type == Gst.MessageType.STATE_CHANGED:
            old, new, pending = mensaje.parse_state_changed()

            if old == Gst.State.PAUSED and new == Gst.State.PLAYING:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "playing")
                    self.__new_handle(True)
                    # Si se llama enseguida falla.
                    GLib.idle_add(self.__re_config)

            elif old == Gst.State.READY and new == Gst.State.PAUSED:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "paused")
                    self.__new_handle(False)

            elif old == Gst.State.READY and new == Gst.State.NULL:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "None")
                    self.__new_handle(False)

            elif old == Gst.State.PLAYING and new == Gst.State.PAUSED:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "paused")
                    self.__new_handle(False)

            """
            elif old == Gst.State.NULL and new == Gst.State.READY:
                pass

            elif old == Gst.State.PAUSED and new == Gst.State.READY:
                pass

            else:
                pass"""

        elif mensaje.type == Gst.MessageType.TAG:
            taglist = mensaje.parse_tag()
            datos = taglist.to_string()

            if 'audio-codec' in datos and not 'video-codec' in datos:
                if self.video_in_stream == True or \
                    self.video_in_stream == None:

                    self.video_in_stream = False
                    self.emit("video", False)
                    #self.audio_pipelin.agregar_visualizador('monoscope')

            elif 'video-codec' in datos:
                if self.video_in_stream == False or \
                    self.video_in_stream == None:

                    self.video_in_stream = True
                    self.emit("video", True)
                    #self.audio_pipelin.quitar_visualizador()

            #self.duracion = int(taglist.to_string().split(
            #   "duration=(guint64)")[1].split(',')[0])

            #Ejemplo:
                # taglist,
                # duration=(guint64)780633000000,
                # video-codec=(string)H.264,
                # audio-codec=(string)"MPEG-4\ AAC"

        elif mensaje.type == Gst.MessageType.WARNING:
            print "\n Gst.MessageType.WARNING:"
            print mensaje.parse_warning()

        elif mensaje.type == Gst.MessageType.LATENCY:
            # http://cgit.collabora.com/git/farstream.git/tree/examples/gui/fs-gui.py
            print "\n Gst.MessageType.LATENCY"
            self.player.recalculate_latency()

        elif mensaje.type == Gst.MessageType.STREAM_START:
            #print "\n Gst.MessageType.STREAM_START:"
            #print mensaje.parse_stream_status()
            pass

        elif mensaje.type == Gst.MessageType.STREAM_STATUS:
            #print "\n Gst.MessageType.STREAM_STATUS:"
            #print mensaje.parse_stream_status()
            pass

        elif mensaje.type == Gst.MessageType.STRUCTURE_CHANGE:
            #print "\n Gst.MessageType.STRUCTURE_CHANGE:"
            #print mensaje.parse_structure_change()
            pass

        elif mensaje.type == Gst.MessageType.TOC:
            #print "\n Gst.MessageType.TOC:"
            #print mensaje.parse_toc()
            pass

        elif mensaje.type == Gst.MessageType.UNKNOWN:
            #print "\n Gst.MessageType.UNKNOWN:"
            pass

        elif mensaje.type == Gst.MessageType.DURATION_CHANGED:
            print "\n Gst.MessageType.DURATION_CHANGED:"

        elif mensaje.type == Gst.MessageType.ASYNC_DONE:
            #print "\n Gst.MessageType.ASYNC_DONE:"
            #print mensaje.parse_async_done()
            pass

        elif mensaje.type == Gst.MessageType.ASYNC_START:
            #print "\n Gst.MessageType.ASYNC_START:"
            pass

        elif mensaje.type == Gst.MessageType.NEW_CLOCK:
            #print "\n Gst.MessageType.NEW_CLOCK:"
            pass

        elif mensaje.type == Gst.MessageType.CLOCK_PROVIDE:
            #print "\n Gst.MessageType.CLOCK_PROVIDE:"
            #print mensaje.parse_clock_provide()
            pass

        elif mensaje.type == Gst.MessageType.CLOCK_LOST:
            #print "\n Gst.MessageType.CLOCK_LOST:"
            #print mensaje.parse_clock_lost()
            pass

        elif mensaje.type == Gst.MessageType.QOS:
            print "\n Gst.MessageType.QOS:"
            #print mensaje.parse_qos()
            #print mensaje.parse_qos_stats()
            #print mensaje.parse_qos_values()

        elif mensaje.type == Gst.MessageType.BUFFERING:
            print "\n Gst.MessageType.BUFFERING:"
            print mensaje.parse_buffering()
            print mensaje.parse_buffering_stats()
            '''
            buf = int(message.structure["buffer-percent"])
            if buf < 100 and self.estado == gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__pause()
            elif buf > 99 and self.estado != gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.play()
            '''

        elif mensaje.type == Gst.MessageType.RESET_TIME:
            #print "\n Gst.MessageType.RESET_TIME:"
            pass

        elif mensaje.type == Gst.MessageType.ELEMENT:
            print "\n Gst.MessageType.ELEMENT:"

        elif mensaje.type == Gst.MessageType.INFO:
            print "\n Gst.MessageType.INFO:"

        elif mensaje.type == Gst.MessageType.PROGRESS:
            print "\n Gst.MessageType.PROGRESS:"

        elif mensaje.type == Gst.MessageType.REQUEST_STATE:
            print "\n Gst.MessageType.REQUEST_STATE:"

        elif mensaje.type == Gst.MessageType.SEGMENT_DONE:
            #print "\n Gst.MessageType.SEGMENT_DONE:"
            pass

        elif mensaje.type == Gst.MessageType.SEGMENT_START:
            #print "\n Gst.MessageType.SEGMENT_START:"
            pass

        elif mensaje.type == Gst.MessageType.STATE_DIRTY:
            #print "\n Gst.MessageType.STATE_DIRTY:"
            pass

        elif mensaje.type == Gst.MessageType.STEP_DONE:
            #print "\n Gst.MessageType.STEP_DONE:"
            pass

        elif mensaje.type == Gst.MessageType.STEP_START:
            #print "\n Gst.MessageType.STEP_START:"
            pass

        elif mensaje.type == Gst.MessageType.ANY:
            #print "\n Gst.MessageType.ANY:"
            pass

        elif mensaje.type == Gst.MessageType.APPLICATION:
            #print "\n Gst.MessageType.APPLICATION:"
            pass

        elif mensaje.type == Gst.MessageType.HAVE_CONTEXT:
            #print "\n Gst.MessageType.HAVE_CONTEXT:"
            pass

        elif mensaje.type == Gst.MessageType.NEED_CONTEXT:
            #print "\n Gst.MessageType.NEED_CONTEXT:"
            pass

        elif mensaje.type == Gst.MessageType.EOS:
            #self.video_pipeline.seek_simple(Gst.Format.TIME,
            #Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0)
            print "\n Gst.MessageType.EOS:"
            self.__new_handle(False)
            self.emit("endfile")

        elif mensaje.type == Gst.MessageType.ERROR:
            print "\n Gst.MessageType.ERROR:"
            print mensaje.parse_error()
            self.__new_handle(False)

        else:
            print mensaje.type

        return True

    def pause_play(self):
        """
        Llama a play() o pause()
        segun el estado actual del pipe de Gst.
        """

        if self.estado == Gst.State.PAUSED \
            or self.estado == Gst.State.NULL \
            or self.estado == Gst.State.READY:
            self.__play()

        elif self.estado == Gst.State.PLAYING:
            self.__pause()

    def rotar(self, valor):
        """
        Rota el Video.
        """
        self.video_pipeline.rotar(valor)
        self.config['rotacion'] = self.video_pipeline.get_rotacion()

    def set_balance(self, brillo=None, contraste=None,
        saturacion=None, hue=None, gamma=None):
        """
        Seteos de balance en video.
        Recibe % en float y convierte a los valores del filtro.
        """
        if brillo:
            self.config['brillo'] = brillo

        if contraste:
            self.config['contraste'] = contraste

        if saturacion:
            self.config['saturacion'] = saturacion

        if hue:
            self.config['hue'] = hue

        if gamma:
            self.config['gamma'] = gamma

        self.video_pipeline.set_balance(
            brillo=brillo,
            contraste=contraste,
            saturacion=saturacion,
            hue=hue,
            gamma=gamma)

    def get_balance(self):
        """
        Retorna los valores actuales de balance en % float.
        """
        # No funciona llamar a los valores reales.
        #return self.video_pipeline.get_balance()
        return self.config

    def stop(self):
        """
        Pone el pipe de Gst en Gst.State.NULL
        """
        self.player.set_state(Gst.State.NULL)

    def load(self, uri):
        """
        Carga un archivo o stream en el pipe de Gst.
        """
        self.stop()
        self.__reset()

        GLib.idle_add(self.__load, uri)

    def __load(self, uri):
        if os.path.exists(uri):
            # Archivo
            direccion = Gst.filename_to_uri(uri)
            self.player.set_property("uri", direccion)
            self.__play()
        else:
            # Streaming
            if Gst.uri_is_valid(uri):
                self.player.set_property("uri", uri)
                self.__play()

    def set_position(self, posicion):
        """
        Permite desplazarse por
        la pista que se esta reproduciendo.
        """
        if self.duracion < posicion:
            self.emit("newposicion", self.posicion)
            return

        posicion = self.duracion * posicion / 100

        self.player.seek_simple(
            Gst.Format.TIME,
            Gst.SeekFlags.FLUSH |
            Gst.SeekFlags.KEY_UNIT,
            posicion)

    def set_volumen(self, valor):
        """
        Cambia el volúmen de Reproducción.
        """
        self.volumen = float(valor / 100)
        self.player.set_property('volume', self.volumen)

    def agregar_efecto(self, nombre_efecto):
        self.__new_handle(False)
        self.stop()

        self.efectos.append(nombre_efecto)
        #self.config_efectos[nombre_efecto] = {}
        self.video_pipeline.agregar_efecto(nombre_efecto)

        self.__play()
        # FIXME: Verificar. self.__new_handle(True) solo debiera
        # estar en los mensajes del bus.
        self.__new_handle(True)

    def quitar_efecto(self, indice_efecto):
        if type(indice_efecto) == int:
            self.efectos.remove(self.efectos[indice_efecto])
            #if self.efectos[indice_efecto] in self.config_efectos.keys():
            #    del (self.config_efectos[self.efectos[indice_efecto]])
        elif type(indice_efecto) == str:
            for efecto in self.efectos:
                if efecto == indice_efecto:
                    self.efectos.remove(efecto)
                    #if efecto in self.config_efectos.keys():
                    #    del (self.config_efectos[efecto])
                    #break

        self.__new_handle(False)
        self.stop()

        self.video_pipeline.quitar_efecto(indice_efecto)

        self.__play()
        self.__new_handle(True)

    def configurar_efecto(self, nombre_efecto, propiedad, valor):
        """
        Configura un efecto en el pipe.
        """
        self.video_pipeline.configurar_efecto(nombre_efecto, propiedad, valor)
Ejemplo n.º 11
0
class JAMediaReproductor(GObject.GObject):
    """
    Reproductor de Audio, Video y Streaming de
    Radio y Television. Implementado sobre:

        python 2.7.3
        Gtk 3
        Gstreamer 1.0
    """

    __gsignals__ = {
        "endfile": (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, []),
        "estado":
        (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_STRING, )),
        "newposicion":
        (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_INT, )),
        "volumen":
        (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_FLOAT, )),
        "video":
        (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, (GObject.TYPE_BOOLEAN, ))
    }

    # Estados: playing, paused, None

    def __init__(self, ventana_id):
        """
        Recibe el id de un DrawingArea
        para mostrar el video.
        """

        GObject.GObject.__init__(self)

        self.name = "JAMediaReproductor"
        self.ventana_id = ventana_id

        self.estado = None
        self.volumen = 0.10
        self.config = {
            'saturacion': 50.0,
            'contraste': 50.0,
            'brillo': 50.0,
            'hue': 50.0,
            'gamma': 10.0,
            'rotacion': 0
        }

        self.duracion = 0
        self.posicion = 0
        self.actualizador = False

        self.player = None
        self.bus = None

        from JAMediaBins import JAMedia_Video_Pipeline
        from JAMediaBins import JAMedia_Audio_Pipeline

        # Gestor de la salida de Video del reproductor.
        self.video_pipeline = JAMedia_Video_Pipeline()

        # Gestor de salida de Audio del reproductor.
        self.audio_pipelin = JAMedia_Audio_Pipeline()

        # Debe iniciarse como None (ver señal video)
        self.video_in_stream = None

        self.efectos = []
        #self.config_efectos = {}

        self.__reset()

    def __reset(self):

        # Reproductor.
        self.player = Gst.ElementFactory.make("playbin", "player")
        self.player.set_property('force-aspect-ratio', True)

        # Si no se establecen los valores al original, se produce un error.
        self.video_pipeline.reset_balance()
        self.player.set_property('volume', self.volumen)

        self.player.set_window_handle(self.ventana_id)
        self.player.set_property('video-sink', self.video_pipeline)
        self.player.set_property('audio-sink', self.audio_pipelin)

        self.bus = self.player.get_bus()

        self.bus.enable_sync_message_emission()
        self.bus.connect('sync-message', self.__sync_message)

        #self.video_in_stream = False

    def __re_config(self):
        """
        Luego de que está en play,
        recupera los valores configurados para balance y
        rotación y configura con ellos el balance en el pipe.
        """

        self.player.set_property('volume', self.volumen)
        self.video_pipeline.set_rotacion(self.config['rotacion'])
        self.video_pipeline.set_balance(brillo=self.config['brillo'],
                                        contraste=self.config['contraste'],
                                        saturacion=self.config['saturacion'],
                                        hue=self.config['hue'],
                                        gamma=self.config['gamma'])
        self.emit('volumen', self.volumen)

        return False

    def __play(self):
        """
        Pone el pipe de Gst en Gst.State.PLAYING
        """

        self.player.set_state(Gst.State.PLAYING)

    def __pause(self):
        """
        Pone el pipe de Gst en Gst.State.PAUSED
        """

        self.player.set_state(Gst.State.PAUSED)

    def __new_handle(self, reset):
        """
        Elimina o reinicia la funcion que
        envia los datos de actualizacion para
        la barra de progreso del reproductor.
        """

        if self.actualizador:
            GLib.source_remove(self.actualizador)
            self.actualizador = False

        if reset:
            self.actualizador = GLib.timeout_add(500, self.__handle)

    def __handle(self):
        """
        Envia los datos de actualizacion para
        la barra de progreso del reproductor.
        """

        bool1, valor1 = self.player.query_duration(Gst.Format.TIME)
        bool2, valor2 = self.player.query_position(Gst.Format.TIME)

        duracion = float(valor1)
        posicion = float(valor2)

        pos = 0
        try:
            pos = int(posicion * 100 / duracion)

        except:
            pass

        if pos < 0 or pos > self.duracion:
            return True

        if self.duracion != duracion:
            self.duracion = duracion

        if pos != self.posicion:
            self.posicion = pos
            self.emit("newposicion", self.posicion)
            # print "***", gst.video_convert_frame(
            #   self.player.get_property("frame"))

        return True

    def __sync_message(self, bus, mensaje):
        """
        Captura los mensajes en el bus del pipe Gst.
        """
        """
        # Esto no es necesario si:
        # self.player.set_window_handle(self.ventana_id)
        try:
            if mensaje.get_structure().get_name() == 'prepare-window-handle':
                mensaje.src.set_window_handle(self.ventana_id)
                return

        except:
            pass"""

        if mensaje.type == Gst.MessageType.STATE_CHANGED:
            old, new, pending = mensaje.parse_state_changed()

            if old == Gst.State.PAUSED and new == Gst.State.PLAYING:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "playing")
                    self.__new_handle(True)
                    # Si se llama enseguida falla.
                    GLib.idle_add(self.__re_config)

            elif old == Gst.State.READY and new == Gst.State.PAUSED:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "paused")
                    self.__new_handle(False)

            elif old == Gst.State.READY and new == Gst.State.NULL:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "None")
                    self.__new_handle(False)

            elif old == Gst.State.PLAYING and new == Gst.State.PAUSED:
                if self.estado != new:
                    self.estado = new
                    self.emit("estado", "paused")
                    self.__new_handle(False)
            """
            elif old == Gst.State.NULL and new == Gst.State.READY:
                pass

            elif old == Gst.State.PAUSED and new == Gst.State.READY:
                pass

            else:
                pass"""

        elif mensaje.type == Gst.MessageType.TAG:
            taglist = mensaje.parse_tag()
            datos = taglist.to_string()

            if 'audio-codec' in datos and not 'video-codec' in datos:
                if self.video_in_stream == True or \
                    self.video_in_stream == None:

                    self.video_in_stream = False
                    self.emit("video", False)
                    #self.audio_pipelin.agregar_visualizador('monoscope')

            elif 'video-codec' in datos:
                if self.video_in_stream == False or \
                    self.video_in_stream == None:

                    self.video_in_stream = True
                    self.emit("video", True)
                    #self.audio_pipelin.quitar_visualizador()

            #self.duracion = int(taglist.to_string().split(
            #   "duration=(guint64)")[1].split(',')[0])

            #Ejemplo:
            # taglist,
            # duration=(guint64)780633000000,
            # video-codec=(string)H.264,
            # audio-codec=(string)"MPEG-4\ AAC"

        elif mensaje.type == Gst.MessageType.WARNING:
            print "\n Gst.MessageType.WARNING:"
            print mensaje.parse_warning()

        elif mensaje.type == Gst.MessageType.LATENCY:
            # http://cgit.collabora.com/git/farstream.git/tree/examples/gui/fs-gui.py
            print "\n Gst.MessageType.LATENCY"
            self.player.recalculate_latency()

        elif mensaje.type == Gst.MessageType.STREAM_START:
            #print "\n Gst.MessageType.STREAM_START:"
            #print mensaje.parse_stream_status()
            pass

        elif mensaje.type == Gst.MessageType.STREAM_STATUS:
            #print "\n Gst.MessageType.STREAM_STATUS:"
            #print mensaje.parse_stream_status()
            pass

        elif mensaje.type == Gst.MessageType.STRUCTURE_CHANGE:
            #print "\n Gst.MessageType.STRUCTURE_CHANGE:"
            #print mensaje.parse_structure_change()
            pass

        elif mensaje.type == Gst.MessageType.TOC:
            #print "\n Gst.MessageType.TOC:"
            #print mensaje.parse_toc()
            pass

        elif mensaje.type == Gst.MessageType.UNKNOWN:
            #print "\n Gst.MessageType.UNKNOWN:"
            pass

        elif mensaje.type == Gst.MessageType.DURATION_CHANGED:
            print "\n Gst.MessageType.DURATION_CHANGED:"

        elif mensaje.type == Gst.MessageType.ASYNC_DONE:
            #print "\n Gst.MessageType.ASYNC_DONE:"
            #print mensaje.parse_async_done()
            pass

        elif mensaje.type == Gst.MessageType.ASYNC_START:
            #print "\n Gst.MessageType.ASYNC_START:"
            pass

        elif mensaje.type == Gst.MessageType.NEW_CLOCK:
            #print "\n Gst.MessageType.NEW_CLOCK:"
            pass

        elif mensaje.type == Gst.MessageType.CLOCK_PROVIDE:
            #print "\n Gst.MessageType.CLOCK_PROVIDE:"
            #print mensaje.parse_clock_provide()
            pass

        elif mensaje.type == Gst.MessageType.CLOCK_LOST:
            #print "\n Gst.MessageType.CLOCK_LOST:"
            #print mensaje.parse_clock_lost()
            pass

        elif mensaje.type == Gst.MessageType.QOS:
            print "\n Gst.MessageType.QOS:"
            #print mensaje.parse_qos()
            #print mensaje.parse_qos_stats()
            #print mensaje.parse_qos_values()

        elif mensaje.type == Gst.MessageType.BUFFERING:
            print "\n Gst.MessageType.BUFFERING:"
            print mensaje.parse_buffering()
            print mensaje.parse_buffering_stats()
            '''
            buf = int(message.structure["buffer-percent"])
            if buf < 100 and self.estado == gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.__pause()
            elif buf > 99 and self.estado != gst.STATE_PLAYING:
                self.emit("loading-buffer", buf)
                self.play()
            '''

        elif mensaje.type == Gst.MessageType.RESET_TIME:
            #print "\n Gst.MessageType.RESET_TIME:"
            pass

        elif mensaje.type == Gst.MessageType.ELEMENT:
            print "\n Gst.MessageType.ELEMENT:"

        elif mensaje.type == Gst.MessageType.INFO:
            print "\n Gst.MessageType.INFO:"

        elif mensaje.type == Gst.MessageType.PROGRESS:
            print "\n Gst.MessageType.PROGRESS:"

        elif mensaje.type == Gst.MessageType.REQUEST_STATE:
            print "\n Gst.MessageType.REQUEST_STATE:"

        elif mensaje.type == Gst.MessageType.SEGMENT_DONE:
            #print "\n Gst.MessageType.SEGMENT_DONE:"
            pass

        elif mensaje.type == Gst.MessageType.SEGMENT_START:
            #print "\n Gst.MessageType.SEGMENT_START:"
            pass

        elif mensaje.type == Gst.MessageType.STATE_DIRTY:
            #print "\n Gst.MessageType.STATE_DIRTY:"
            pass

        elif mensaje.type == Gst.MessageType.STEP_DONE:
            #print "\n Gst.MessageType.STEP_DONE:"
            pass

        elif mensaje.type == Gst.MessageType.STEP_START:
            #print "\n Gst.MessageType.STEP_START:"
            pass

        elif mensaje.type == Gst.MessageType.ANY:
            #print "\n Gst.MessageType.ANY:"
            pass

        elif mensaje.type == Gst.MessageType.APPLICATION:
            #print "\n Gst.MessageType.APPLICATION:"
            pass

        elif mensaje.type == Gst.MessageType.HAVE_CONTEXT:
            #print "\n Gst.MessageType.HAVE_CONTEXT:"
            pass

        elif mensaje.type == Gst.MessageType.NEED_CONTEXT:
            #print "\n Gst.MessageType.NEED_CONTEXT:"
            pass

        elif mensaje.type == Gst.MessageType.EOS:
            #self.video_pipeline.seek_simple(Gst.Format.TIME,
            #Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0)
            print "\n Gst.MessageType.EOS:"
            self.__new_handle(False)
            self.emit("endfile")

        elif mensaje.type == Gst.MessageType.ERROR:
            print "\n Gst.MessageType.ERROR:"
            print mensaje.parse_error()
            self.__new_handle(False)

        else:
            print mensaje.type

        return True

    def pause_play(self):
        """
        Llama a play() o pause()
        segun el estado actual del pipe de Gst.
        """

        if self.estado == Gst.State.PAUSED \
            or self.estado == Gst.State.NULL \
            or self.estado == Gst.State.READY:
            self.__play()

        elif self.estado == Gst.State.PLAYING:
            self.__pause()

    def rotar(self, valor):
        """
        Rota el Video.
        """
        self.video_pipeline.rotar(valor)
        self.config['rotacion'] = self.video_pipeline.get_rotacion()

    def set_balance(self,
                    brillo=None,
                    contraste=None,
                    saturacion=None,
                    hue=None,
                    gamma=None):
        """
        Seteos de balance en video.
        Recibe % en float y convierte a los valores del filtro.
        """
        if brillo:
            self.config['brillo'] = brillo

        if contraste:
            self.config['contraste'] = contraste

        if saturacion:
            self.config['saturacion'] = saturacion

        if hue:
            self.config['hue'] = hue

        if gamma:
            self.config['gamma'] = gamma

        self.video_pipeline.set_balance(brillo=brillo,
                                        contraste=contraste,
                                        saturacion=saturacion,
                                        hue=hue,
                                        gamma=gamma)

    def get_balance(self):
        """
        Retorna los valores actuales de balance en % float.
        """
        # No funciona llamar a los valores reales.
        #return self.video_pipeline.get_balance()
        return self.config

    def stop(self):
        """
        Pone el pipe de Gst en Gst.State.NULL
        """
        self.player.set_state(Gst.State.NULL)

    def load(self, uri):
        """
        Carga un archivo o stream en el pipe de Gst.
        """
        self.stop()
        self.__reset()

        GLib.idle_add(self.__load, uri)

    def __load(self, uri):
        if os.path.exists(uri):
            # Archivo
            direccion = Gst.filename_to_uri(uri)
            self.player.set_property("uri", direccion)
            self.__play()
        else:
            # Streaming
            if Gst.uri_is_valid(uri):
                self.player.set_property("uri", uri)
                self.__play()

    def set_position(self, posicion):
        """
        Permite desplazarse por
        la pista que se esta reproduciendo.
        """
        if self.duracion < posicion:
            self.emit("newposicion", self.posicion)
            return

        posicion = self.duracion * posicion / 100

        self.player.seek_simple(Gst.Format.TIME,
                                Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT,
                                posicion)

    def set_volumen(self, valor):
        """
        Cambia el volúmen de Reproducción.
        """
        self.volumen = float(valor / 100)
        self.player.set_property('volume', self.volumen)

    def agregar_efecto(self, nombre_efecto):
        self.__new_handle(False)
        self.stop()

        self.efectos.append(nombre_efecto)
        #self.config_efectos[nombre_efecto] = {}
        self.video_pipeline.agregar_efecto(nombre_efecto)

        self.__play()
        # FIXME: Verificar. self.__new_handle(True) solo debiera
        # estar en los mensajes del bus.
        self.__new_handle(True)

    def quitar_efecto(self, indice_efecto):
        if type(indice_efecto) == int:
            self.efectos.remove(self.efectos[indice_efecto])
            #if self.efectos[indice_efecto] in self.config_efectos.keys():
            #    del (self.config_efectos[self.efectos[indice_efecto]])
        elif type(indice_efecto) == str:
            for efecto in self.efectos:
                if efecto == indice_efecto:
                    self.efectos.remove(efecto)
                    #if efecto in self.config_efectos.keys():
                    #    del (self.config_efectos[efecto])
                    #break

        self.__new_handle(False)
        self.stop()

        self.video_pipeline.quitar_efecto(indice_efecto)

        self.__play()
        self.__new_handle(True)

    def configurar_efecto(self, nombre_efecto, propiedad, valor):
        """
        Configura un efecto en el pipe.
        """
        self.video_pipeline.configurar_efecto(nombre_efecto, propiedad, valor)