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 __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 __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 __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 __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()
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
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)
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
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
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)
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)