Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/MplayerReproductor.py
diff options
context:
space:
mode:
Diffstat (limited to 'MplayerReproductor.py')
-rw-r--r--MplayerReproductor.py346
1 files changed, 346 insertions, 0 deletions
diff --git a/MplayerReproductor.py b/MplayerReproductor.py
new file mode 100644
index 0000000..366fb1d
--- /dev/null
+++ b/MplayerReproductor.py
@@ -0,0 +1,346 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# MplayerReproductor.py por:
+# Flavio Danesse <fdanesse@gmail.com>
+# CeibalJAM! - Uruguay
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import time
+import os
+import subprocess
+#import platform
+
+import gi
+from gi.repository import GObject
+
+STDOUT = "/tmp/jamediaout%d" % time.time()
+STDERR = "/dev/null"
+MPLAYER = "mplayer"
+
+#if "olpc" in platform.platform(): MPLAYER = "./mplayer"
+#if "Strawberry" in platform.platform(): MPLAYER = "./mplayer"
+
+class MplayerReproductor(GObject.GObject):
+ """
+ Reproductor de Audio, Video y Streaming de
+ Radio y Television. Implementado sobre:
+
+ python 2.7.3
+ Gtk 3
+ mplayer (a traves de python.subprocess)
+ """
+
+ __gsignals__ = {"endfile":(GObject.SIGNAL_RUN_FIRST,
+ GObject.TYPE_NONE, []),
+ "estado":(GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE,
+ (GObject.TYPE_STRING,)),
+ "newposicion":(GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE,
+ (GObject.TYPE_INT,)),
+ "volumen":(GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE,
+ (GObject.TYPE_FLOAT,))}
+
+ # 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 = "MplayerReproductor"
+ self.ventana_id = ventana_id
+ self.mplayer = None
+ self.salida = None
+ self.entrada = None
+ self.estado = None
+ self.duracion = 0
+ self.posicion = 0
+ self.volumen = 0
+ self.actualizador = None
+ self.uri = None
+
+ def stop(self):
+ """Detiene todo."""
+
+ try:
+ if self.entrada:
+ self.entrada.write('%s 0\n' % "quit")
+ self.entrada.flush()
+ self.new_handle(False)
+ except Exception, e:
+ #print "HA OCURRIDO UN ERROR EN QUIT DEL REPRODUCTOR", e
+ pass
+ self.posicion = 0
+ if os.path.exists(STDOUT): os.unlink(STDOUT)
+ import commands
+ commands.getoutput('killall mplayer')
+ self.estado = None
+ self.emit("estado", "None")
+
+ def load(self, uri):
+ """Carga y Reproduce un archivo o streaming."""
+
+ self.stop()
+ self.uri = uri
+ if os.path.exists(self.uri):
+ uri = "%s%s%s" % ("\"", self.uri, "\"")
+
+ cache_pantalla = "%s -cache %i -wid %i" % (MPLAYER, 1024, self.ventana_id)
+ estructura = "%s -slave -idle -nolirc -rtc -nomouseinput -noconsolecontrols -nojoystick" % (cache_pantalla)
+ self.mplayer = subprocess.Popen(estructura, shell = True, stdin = subprocess.PIPE,
+ stdout = open(STDOUT,"w+b"), stderr=open(STDOUT,"r+b"), universal_newlines=True)
+ self.entrada = self.mplayer.stdin
+ self.salida = open(STDOUT,"r")
+ self.entrada.write("loadfile %s 0\n" % uri)
+ self.entrada.flush()
+ self.new_handle(True)
+
+ def handle(self):
+ """Consulta el estado y progreso del
+ la reproduccion actual."""
+
+ if not self.entrada.closed:
+ # Control por tiempo
+ #self.entrada.write("%s 0\n" % ("get_time_length"))
+ #self.entrada.flush()
+ #duracion = self.salida.readline()
+ #if "ANS_LENGTH" in duracion:
+ # duracion = float(duracion.split("=")[1]) # Duración en Segundos
+ # print "dur", duracion
+
+ #self.entrada.write("%s 0\n" % ("get_time_pos"))
+ #self.entrada.flush()
+ #posicion = self.salida.readline()
+ #if "ANS_TIME_POSITION" in posicion:
+ # posicion = float(posicion.split("=")[1]) # Posición en Segundos
+ # print "pos", posicion
+
+ self.entrada.write("%s 0\n" % ("get_property percent_pos"))
+ self.entrada.flush()
+ linea = self.salida.readline()
+ if linea:
+ if "ANS_percent_pos" in linea:
+ "Información sobre el porcentaje Reproducido hasta el momento. Ejemplo:"
+ "ANS_percent_pos=0"
+ self.get_progress_in_mplayer(linea)
+ self.get_volumen()
+
+ elif "Video: no video" in linea or "Audio only file format detected" in linea:
+ "Cuando no hay video en la fuente. Ejemplo"
+ "Audio only file format detected."
+ "Video: no video"
+ #self.emit("video", False)
+ pass
+
+ elif "Cache" in linea:
+ "Información Sobre Carga de caché. Ejemplo:"
+ "Cache fill: 6.25% (65536 bytes)"
+ #self.get_progress_cache_in_mplayer(linea)
+ pass
+
+ elif "Movie-Aspect" in linea:
+ "Información sobre el aspecto del video. Ejemplo:"
+ "Movie-Aspect is 1.78:1 - prescaling to correct movie aspect."
+ #self.emit("video", True)
+ pass
+
+ elif "Starting playback" in linea:
+ "Cuando comienza la Reproducción. Ejemplo:"
+ "Starting playback..."
+ self.estado = "playing"
+ self.emit("estado", "playing")
+
+ elif "AO:" in linea:
+ "Información Sobre Audio en la pista. Ejemplo:"
+ "AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample)"
+ pass
+
+ elif "VO:" in linea:
+ "Información sobre Video en la pista. Ejemplo:"
+ "VO: [xv] 428x240 => 428x240 Planar YV12"
+ pass
+
+ elif "Resolving" in linea:
+ "Información sobre Resolución de Streamings. Ejemplo:"
+ "Resolving radio1.oceanofm.com for AF_INET6..."
+ pass
+
+ elif "Connecting" in linea:
+ "Información sobre Conexión a un Streaming. Ejemplo:"
+ "Connecting to server main-office.rautemusik.fm[87.230.101.9]: 80..."
+ pass
+
+ elif "Name" in linea:
+ "El nombre de una streaming de Radio. Ejemplo:"
+ "Name : #MUSIK.MAIN - WWW.RAUTEMUSIK.FM - 24H TOP 40 POP HITS 80S 90S DANCE HOUSE ROCK RNB AND MORE!"
+ pass
+
+ elif "Playing" in linea:
+ "La Pista que se está reproduciendo. Ejemplo:"
+ "Playing /media/4E432D364BC64012/E - Videos/Tylor swift/Back to December-Taylor Swift Lyrics."
+ pass
+
+ elif "Genre" in linea or "Website" in linea or "Bitrate" in linea:
+ "Información Sobre un Streaming de Radio. Ejemplo:"
+ "Genre : Pop Rock Top 40 RnB 80s"
+ "Website: http://www.RauteMusik.FM/"
+ "Bitrate: 128kbit/s"
+ pass
+
+ elif "Opening" in linea or "AUDIO" in linea or "Selected" in linea:
+ "Información sobre Codecs Utilizados. Ejemplo:"
+ "Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family"
+ "Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)"
+ "Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders"
+ "AUDIO: 44100 Hz, 2 ch, s16le, 98.6 kbit/6.99% (ratio: 12323->176400)"
+ "Selected audio codec: [ffaac] afm: ffmpeg (FFmpeg AAC (MPEG-2/MPEG-4 Audio))"
+ pass
+
+ else:
+ "Información Diversa. Ejemplo:"
+ "Failed to open /dev/rtc: Permission denied (it should be readable by the us"
+ "Unsupported PixelFormat 61"
+ "Unsupported PixelFormat 53"
+ "Unsupported PixelFormat 81"
+ "eo (h264), -vid 0"
+ "[lavf] stream 1: audio (aac), -aid 0"
+ "VIDEO: [H264] 640x480 0bpp 30.000 fps 218.3 kbps (26.6 kbyte/s)"
+ "Clip info:"
+ "starttime: 0"
+ "totalduration: 226"
+ "totaldatarate: 338"
+ "bytelength: 9570679"
+ "canseekontime: true"
+ "sourcedata: BC8280065HH1341966475963833"
+ "purl: "
+ "pmsg: "
+ "Load subtitles in /media/4E432D364BC64012/E - Videos/Tylor swift/"
+ "=========================================================================="
+ "libavcodec version 53.35.0 (external)"
+ "Mismatching header version 53.32.2"
+ "=========================================================================="
+ "=========================================================================="
+ "=========================================================================="
+ "A: 0.0 V: 0.0 A-V: 0.014 ct: 0.000 0/ 0 ??% ??% ??,?% 0 0 90%"
+ "A: 123.2 V: 123.2 A-V: -0.000 ct: 0.033 0/ 0 2% 1% 0.4% 0 0 50%"
+
+ "Cuando no se puede Acceder a un Streaming. Ejemplo:"
+ "Failed to get value of property 'percent_pos'."
+ "Failed to get value of property 'percent_ANS_ERFailed to get value of"
+ "prANS_ERROR=PROPERTY_UNAFailed toANS_ERROR=PROPERTY_UNAVAILABLE"
+ "ANS_ERROR=PROPERTY_UNAVAILABLE"
+ pass
+
+ return True
+
+ def get_progress_in_mplayer(self, linea):
+ """Obtiene el progreso de la reproduccion y lo
+ envia en una señal para actualizar la barra de
+ progreso."""
+
+ pos = 0
+ try:
+ if "Cache size" in linea: return
+ pos = int(linea.split('=')[1])
+ if pos != self.posicion:
+ self.posicion = pos
+ self.emit("newposicion", self.posicion)
+ if self.posicion >= 100:
+ self.emit("endfile")
+ except Exception, e:
+ print "Error en Progreso de Reproducción: %s" % (e)
+
+ def pause_play(self):
+ """Llama a play() o pause()
+ segun el estado actual del reproductor."""
+
+ try:
+ if self.entrada:
+ if self.estado == "playing": # pausa
+ self.pause()
+ elif self.estado == "paused":
+ self.pause(True)
+ self.estado = "playing"
+ self.emit("estado", "playing")
+ else:
+ #if self.uri: self.load(self.uri)
+ pass
+ except Exception, e:
+ print "HA OCURRIDO UN ERROR EN PAUSE_PLAY DEL REPRODUCTOR", e
+
+ def pause(self, reset = False):
+ """Pone en pause o unpause a mplayer"""
+
+ self.entrada.write('pause 0\n')
+ self.entrada.flush()
+ self.new_handle(reset)
+ self.estado = "paused"
+ self.emit("estado", "paused")
+
+ def play(self):
+ """No hace nada. mplayer utiliza:
+ pause, unpause y load en lugar de play."""
+
+ pass
+
+ 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 = None
+ if reset:
+ self.actualizador = GObject.timeout_add(35, self.handle)
+
+ def set_position(self, posicion):
+ """Funcion que permite desplazarse por
+ el archivo que se esta reproduciendo."""
+
+ # FIXME: Actualmente no funciona bien
+ posicion = int(posicion)
+ if posicion != self.posicion:
+ self.posicion = posicion
+ self.entrada.write('seek %s %i 0\n' % (posicion, 1))
+ self.entrada.flush()
+
+ def get_volumen(self):
+ """Obtiene el volumen de reproducción.
+ Lo hace solo al reproducir el primer archivo
+ o streaming y envía el dato para actualizar
+ el control de volúmen."""
+
+ if self.volumen != 0: return
+ if self.entrada:
+ self.entrada.write("%s 0\n" % ("get_property volume"))
+ self.entrada.flush()
+ linea = self.salida.readline()
+ if "ANS_volume" in linea:
+ valor = float(linea.split("=")[1])
+ if self.volumen == 0:
+ self.volumen = valor
+ self.emit('volumen', valor)
+
+ def set_volumen(self, valor):
+ """Cambia el volúmen de Reproducción."""
+
+ if self.entrada:
+ if valor != self.volumen:
+ self.volumen = valor
+ self.entrada.write("%s %s0\n" % ("set_property volume", valor))
+ self.entrada.flush()
+ \ No newline at end of file