Aprovecha y usa cualquier librerías de Java

Embed Size (px)

Citation preview

  • 7/31/2019 Aprovecha y usa cualquier libreras de Java.

    1/5

  • 7/31/2019 Aprovecha y usa cualquier libreras de Java.

    2/5

    Python DESARROLLO

    61Nmero 07W W W . L I NUX - M A G A Z I N E . E S

    En Java, en general, para reproducir unsonido es necesario definir varias partes:

    Obtener el stream de audio, descodificar-

    lo, tratarlo y escribirlo en el dispositivo de

    nuestro PC.

    RequisitosComo requisitos fundamentales, vamos a

    necesitar nuestro querido intrprete de

    Jython. Para obtenerlo nos dirigimos a su

    web [1] y descargamos la ultima versin

    (versin 2.1 en el momento de escribir

    esto). Necesitamos la nueva versin de

    Java (JRE 1.5 o JDK 1.5), disponible en

    [3], ya que incorpora algunas novedades

    y mejoras que necesitaremos para nuestro

    pequeo reproductor deMP3. Por ultimo

    necesitamos obtener las libreras que

    vamos a utilizar, MPSPI que podemos

    encontrar en la web de Javazoom (ver

    [2]) y ms concretamente en http://www.

    Javazoom.net/mp3spi/mp3spi.html.

    Una vez instalados el interprete de

    Jython y el JDK 1.5 (o JRE 1.5) debemos

    proceder a instalar las libreras de

    Javazoom. Para ello, descomprimimos elfichero que contiene las libreras de

    Javazoom (ya sabis, unzip -x fichero.zip

    o bien tar xvfz fichero.tar.gz ) y, como en

    la mayora de los casos, se nos crear undirectorio nuevo con el contenido del

    fichero. El primer paso ser copiar las

    libreras que necesitamos al directorio

    lib/ext/de nuestro JRE (Maquina virtual

    de Java). En nuestro caso, despus de ins-

    talar el JDK 1.5, este directorio se encuen-

    tra en/usr/Java/jdk1.5.0_02/jre/lib/ext/y

    debemos copiar aqu (obviamente como

    root) los paquetes mp3spi1.9.2.jar, y den-

    tro del directorio lib, jl1.0.jar y

    tritonus_share.jar.

    Una vez hecho esto, al arrancar el intr-

    prete deJython nos aparecer un mensaje

    por cada archivo que hemos copiado,

    indicando que dicho paquete se est pro-

    cesando para su uso (justo antes de arran-

    car nuestro intrprete). Para confirmar

    que todo es correcto, en el interprete

    introducimos import Javazoom y no debe-

    ra salir ningn mensaje de error (en caso

    de que as fuera, comprobad que los

    archivos estn copiados en el sitio correc-

    to).

    Con estas libreras tenemos ahora un

    descodificador del stream de nuestrosarchivos MP3 adems de algunas otras

    utilidades (libreras para conversin de

    formatos, lector de la informacin de las

    El formato de sonidoMP3 es uno delos mas consolidados dentro de la

    msica. A diario miles de personas

    en todo el mundo comparten y crean

    millones de ficheros enMP3 y los repro-

    ductores de msica, ya sea en el ordena-

    dor, en los equipos de msica o para el

    coche, se han adaptado para reproducir

    este formato. Actualmente la mayora de

    los reproductores de MP3 desarrollados

    para PC (como xmms, etc..) soportan este

    formato de msica. Pero, cmo podemos

    crear nuestro propio reproductor deMP3?

    Programar un reproductor de sonido

    en Java, exceptuando que reproduzca los

    formatos comunes que soporta, es bas-

    tante complicado. Se necesita mucho

    tiempo para realizar el descodificador

    del formato (MP3 en este caso) que pro-

    cese los datos (conocidos como stream

    de audio) que contiene cada cancin

    codificada en este formato. Por eso, lo

    mejor para poder crear nuestro reproduc-

    tor, es utilizar libreras que ya estn pre-

    paradas para descodificar el stream y

    para que podamos reproducirlo. En estecaso utilizaremos libreras bajo la licen-

    cia LGPL (Lesser General Public

    License).

    JUKEBOX CON

    JYTHON

    Aprovecha y usa cualquier libreras de Java.

    JUKEBOX CON

    JYTHON

    Damos otro pequeo avance con Jython: Este mes utilizamos libreras Java y analizamos la reproduccin de

    sonidos desde Java para crear un mini reproductor de MP3donde reproducir nuestra msica.

    POR JOS PEDRO ORANTES Y JOS MARA RUZ

  • 7/31/2019 Aprovecha y usa cualquier libreras de Java.

    3/5

    DESARROLLO Python

    62 Nmero 07 W W W . L I NUX - M A G A Z I N E . E S

    01 import org.tritonus.share.sam-

    pled.TAudioFormat as taf

    02 import org.tritonus.share.sam-

    pled.file.TAudioFileFormat as ftaf

    03 import javax.sound.sampled as

    sampled

    04 import java.io as io

    05 import jarray

    06 import java.util as util

    07 import javax.swing as swing

    08 import java.lang as lang

    09 import java.awt as awt

    10 import java.util as util

    11

    12 class jyMusica(lang.Thread):

    13 def __init__(self):

    14self.panelReproductor()

    15 self.menu()

    16 self.win =

    swing.JFrame("JyMusica",

    size=(150,

    150),windowClosing=self.exit)

    17

    self.win.setJMenuBar(self.menu

    )

    18

    self.win.contentPane.add(self.

    pnlBoton,

    awt.BorderLayout.NORTH)

    19

    self.win.contentPane.add(self.

    pnlBoton2,

    awt.BorderLayout.CENTER)

    20 self.win.show()

    21

    self.win.setResizable(0)

    22 self.win.pack()

    23

    24 def exit(self, event):

    25 lang.System.exit(0)

    2627 def run(self):

    28 archivo =

    io.File(self.nombre)

    29 inp =

    sampled.AudioSystem.getAudioIn

    putStream(archivo)

    30 baseFileFormat = sam-

    pled.AudioSystem.getAudioFileF

    ormat(archivo)

    31 baseFormat =

    baseFileFormat.getFormat()

    32self.getTag(baseFileFormat)

    33 self.player.play()

    34

    35 def getTag(self,

    baseFileFormat):

    36 properties = ftaf.pro-

    perties(baseFileFormat)

    37 key = "author"

    38 val =

    properties.get(key)

    39 key = "title"

    40 tag=

    properties.get(key)

    41 key = "album"

    42 alb =

    properties.get(key)

    43

    self.txtArea.setText("")

    44

    self.txtArea.append("\nAuthor:")

    45

    self.txtArea.append(val +

    "\n")

    46

    self.txtArea.append("title: ")

    47

    self.txtArea.append(tag +"\n")

    48

    self.txtArea.append("Album: ")

    49

    self.txtArea.append(alb +

    "\n")

    50

    51 def

    panelReproductor(self):

    52 self.pnlBoton =

    swing.JPanel(awt.FlowLayout())

    53 self.pnlBoton2 =

    swing.JPanel(awt.FlowLayout())

    54 acciones = ["Play",

    "Stop"]

    55 self.txtArea =

    swing.JTextArea(6,18)

    56 self.areaSrl =swing.JScrollPane(self.txtArea

    )

    57

    self.pnlBoton.add(self.areaSrl

    )

    58 for cadaBoton in

    acciones:

    59

    self.pnlBoton2.add(swing.JButt

    on(cadaBoton,

    actionPerformed=self.accionMen

    u))60

    61 def menu(self):

    62 opciones = ["Play",

    "Stop"]

    63 self.menu =

    swing.JMenuBar()

    64 archivo =

    swing.JMenu("Archivo")

    65 for eachOpcion in

    opciones:

    66

    archivo.add(swing.JMenuItem(ea

    chOpcion,

    actionPerformed=self.accionMen

    u))

    67

    archivo.addSeparator()

    68 self.menu.add(archivo)

    69

    70 def accionMenu(self,event):

    71 self.accion =

    event.getActionCommand()

    72 if self.accion ==

    'Play':

    73 selector =

    swing.JFileChooser()

    74 rtn =

    selector.showOpenDialog(self.w

    in)

    75 archivo = selec-

    tor.getSelectedFile()

    76 self.player =

    pad.AdvancedPlayer(io.FileInpu

    tStream(archivo))

    77 self.nombre=archi-

    vo.toString()

    78 self.play()

    79

    80 elif

    self.accion=='Stop':

    81 self.stop()

    82

    83 def play(self):

    84 self.hilo =lang.Thread(self)

    85 self.hilo.start()

    86

    87 def stop(self):

    88 self.player.stop()

    89 # self.line.drain()

    90 # self.line.stop()

    91 # self.line.close()

    92 # self.din.close()

    93 # self.hilo.interrupt()

    94 # self.hilo.finalize()

    95 #96

    97 if __name__=='__main__':

    98 jyMusica()

    Listado 1: jython-julebox.py

  • 7/31/2019 Aprovecha y usa cualquier libreras de Java.

    4/5

    applets. Una de las limitaciones de CLIP,

    es que necesita cargar el sonido entero en

    memoria antes de reproducirlo lo cual

    aumenta los recursos utilizados, adems

    de que slo est preparada

    para reproducir los formatostpicos enJava (Wav,A-Law,

    U-Law, etc.). Nosotros utili-

    zaremos un SourceDataLine

    y trabajaremos con un

    pequeo Buffer que llenare-

    mos con el stream de sonido

    descodificado que luego

    introduciremos en nuestro

    dispositivo de sonido.

    Los pasos que seguiremos para tratar el

    sonido sern los siguientes. Primero,

    obtendremos el Stream y el formato de

    sonido (utilizando AudioSystem y sus

    mtodos getAudioInputStream, y

    getAudioFileFormat). Adems, del forma-

    to de audio (AudioFormat) leeremos los

    datos del MP3 (el ttulo, el lbum, el

    autor, etc).

    Una vez obtenido

    todo esto (el descodifi-

    cador ya esta haciendo

    su trabajo), necesitare-

    mos crear el buffer,

    que no es otra cosa

    que un array deBytes.Para crear dicho array.

    Jython nos provee de

    un modulo llamado

    jarray que tiene dos

    constructores: zeros y

    array. El primero crea un array inicializa-

    do a 0 del tamao y del tipo que nosotros

    necesitemos y el segundo crea un array ya

    inicializado (por nosotros) de un tipo de

    datos.

    Veamos una ejemplo del uso de Jarray.

    >>> import jarray

    >>> a = jarray.zeros(4,'i')

    >>> print a

    array([0, 0, 0, 0], int)

    >>> b = jarray.array([1,2,3,4],U

    'i')

    >>> print b

    array([1, 2, 3, 4], int)

    Como podis ver el funcionamiento es

    sencillo.Jarray.zeros recibe dos argumen-

    tos que son el numero de elementos y el

    tipo de datos, en este caso 'i' son enteros(integer). Yjarray.array recibe la secuen-

    cia que forma el array y el tipo de datos

    tambin. Para nuestro buffer necesitamos

    un array de 4096 Bytes que crearemos

    usandojarray.zeros(4096,'b'). Si quisira-

    mos que nuestro array fuera de Strings,

    haramos un jarray.zeros(45,Java.

    lang.String). En caso de que necesitra-

    mos (que, de hecho, necesitamos) pasarcomo argumento la longitud de nuestro

    array a un mtodo, haramos len(array)

    ya que los arrays deJython no tienen un

    mtodo como .length() de los arrays de

    Java.

    Por ultimo, crearemos el

    SourceDataLine y desde su mtodo

    write() escribiremos nuestro sonido en

    nuestro dispositivo de audio (entonces ya

    empezaremos a or msica) y luego basta-

    ra con rellenar el buffer (desde nuestro

    AudioInputStream) y volver a escribirlo

    en nuestro dispositivo de sonido hasta

    que lleguemos al final de la cancin o

    hasta que paremos la reproduccin.

    Finalmente, y dado que vamos a usar

    un pequeo interfaz para manejarnos

    (hecho con swing),

    necesitaremos progra-

    mar Java con hilos

    (Thread), por lo que

    nuestro reproductor

    heredara de la clase

    Thread y en el

    momento de reprodu-cir, se lanzar un hilo

    que ser el encargado

    de reproducir la msi-

    ca mientras seguimos

    teniendo el control en

    nuestro pequeo reproductor. Un Thread

    es una secuencia de instrucciones que se

    ejecuta en paralelo con la aplicacin que

    lo invoca, podramos decir que mientras

    nosotros usamos nuestra aplicacin, lan-

    zamos otra pequea aplicacin que repro-

    ducir nuestro sonido sin interferir en la

    primera (ejecucin en paralelo).

    Mtodos y LibrerasVamos a implementar un total de once

    mtodos. Empezaremos describiendo el

    motor del reproductor y terminaremos

    describiendo los de creacin del interfaz.

    Son cuatro mtodos.

    Run(). Desde este mtodo es de

    donde comienza el proceso del

    tratamiento de nuestro fichero

    MP3. Desde aqu obtendremos

    elInputStream y elAudioFormaty una vez que los tengamos,

    pasaremos a llamar al siguiente

    mtodo (Reproducir() ha de lla-

    canciones -artista, lbum, etc.- y algunas

    cosas ms).

    Nos falta un ltimo paso: Debemos eli-

    minar una de las limitaciones deJython.

    Java tiene distintos tipos de

    variables, mtodos, cons-tructores, etc., que pueden

    ser privados (private) o

    pblicos (public). Es impor-

    tante saber que en Jython no

    se pueden declarar variables,

    mtodos, etc., como pblicas

    ni como privadas y cuando

    intentamos acceder, por

    ejemplo, a una interfaz abs-

    tracta privada, nos saltar un mensaje de

    error diciendo que no es posible acceder a

    la interfaz abstracta con el denominador

    public.

    Solventar esta limitacin es sencillo.

    Basta con editar el fichero de registro de

    jython que se encuentra en el direc-

    tor io donde hay amos i n s t a l ado

    jython (en nuestro caso $HOME/

    Desarrol lo/jython-2.1/registry) y bus-

    camos la lnea python.

    security.respectJavaAccessibility = true y

    cambiamos true por false. Ya tenemos

    nuestro sistema preparado.

    Por ltimo, es muy importante tener a

    mano la API (documentacin) de Javadisponible tambin en su web y la de las

    libreras que vamos a utilizar. De

    Javazoom deberis bajar la documenta-

    cin de JLayer (la de MPSPI viene en el

    fichero que bajasteis al principio) y laAPI

    de las libreras tritonus la podis bajar de

    [4] (estn al final de la pgina).

    Sonido en Java?El sonido de Java requiere que los progra-

    madores conozcan como funcionan sus

    clases principales. Las que vamos a utili-

    zar son AudioSystem, AudioFormat y

    SourceDataLine.AudioSystem est conec-

    tada a los dispositivos del sistema de

    forma que podemos acceder a ellos ade-

    ms de que dentro de ella tenemos mto-

    dos para tratar el stream de audio.

    AudioFormatcon el que manejaremos el

    formato de audio que necesitaremos. Y

    SourceDataLine que nos proporciona la

    entrada al dispositivo de sonido, es decir,

    que podremos introducir nuestro sonido

    en el dispositivo y de esta forma escu-

    charlo).Java proporciona una clase ms directa

    que es CLIP. Suele utilizarse ms para

    sonidos pequeos en aplicaciones o en

    Figura 1: Aqu tenemos

    a nuestro pequeo

    reproductor de MP3.

    Figura 2: Este es el selector de

    ficheros (JFileChooser) que se lan-

    zar al ejecutar su mtodo

    showOpenDialog().

    Python DESARROLLO

    63Nmero 07W W W . L I NUX - M A G A Z I N E . E S

  • 7/31/2019 Aprovecha y usa cualquier libreras de Java.

    5/5

    marse run() ya que es una

    implementacin del mtodo

    run() que heredamos de la clase

    Thread. De esta forma al invocar

    el mtodo start() del hilo nuevo,

    directamente ejecutara elmtodo run().

    Reproducir(). Aqu es donde

    creamos el buffer deBytes y el

    SourceDataLine. De esta forma,

    recibimos el AudioInputStream

    (el stream de audio) y creare-

    mos el SourceDataLine (que

    recibimos desde el mtodo

    getLine que definiremos un poco

    ms adelante). Luego entrare-

    mos en un bucle en el que con-

    taremos los bytes que lemos y

    los bytes que escribamos, y

    desde el que leeremos (llenando

    el buffer) desde elAudioInputS-

    tream y luego lo escribiremos en

    el dispositivo de sonido desde el

    SourceDataLine. Finalmente,

    cuando se termina la cancin,

    cerraremos el SourceDataLine y

    elAudioInputSource.

    GetLine(). Desde este mtodo

    creamos el SourceDataLine

    (desdeAudioSystem) a partir del

    stream ya descodificado y nos lodevolver. Usaremos un mtodo

    que implementa el JDK1.5 que

    es el getSourceDataLine(), de

    esta forma nos evitamos hacer

    downcasting desde el mtodo

    getLine() de AudioSystem (que

    nos devuelve unDataLine.info).

    Finalmente tenemos getTag().

    Este mtodo ser el encargado

    de devolvernos la informacin

    de la cancin (autor, titulo,

    etc). Recibir el formato del

    fichero sin descodificar, creara

    una ocurrencia de tipo Map

    desde la cual accederemos a los

    datos que mas nos interesan, en

    este caso, lbum, titulo y autor.

    Para los mtodos de la interfaz (fig1), ten-

    dremos el creador del botn y del cuadro

    de texto (panelReproductor()) desde el

    que crearemos los botones (JButtons) y el

    rea de texto (JTextArea()) que nos mos-

    trar la informacin delMP3, el creador

    del men (menu()) que crear un men

    con dos opciones (play y stop) que reali-zarn las mismas funciones que los boto-

    nes, el recogedor de los eventos del ratn

    (accionMenu()) que ejecutar los meto-

    dos Play y Stop, el mtodoPlay() que ini-

    ciara el hilo que reproducir la cancin,

    adems de lanzar el selector de ficheros y

    el mtodo Stop() que detendr la repro-

    duccin en curso.

    La interfaz es muy simple, una rea detexto (donde se insertarn los datos del

    MP3) el botn Play que abrir un selector

    de ficheros (fig2) desde el que selecciona-

    remos el fichero a reproducir y el botn

    Stop que detendr la reproduccin de la

    msica. Cada vez que pulsemos en Play

    tendremos que seleccionar de nuevo la

    cancin a reproducir. En vosotros queda

    la idea de mejorarlo aadindole una lista

    de reproduccin, botn para pasar a la

    siguiente cancin y a la anterior, etc. En el

    nmero 4 de Linux Magzine, vimos el uso

    de otros componentes como JList y alma-

    cenar datos en ficheros, con eso sabris

    ponerle una lista de reproduccin a nues-

    troplayer.

    Para reducir el tamao de la aplicacin

    hemos omitido algunos puntos como

    recoger las excepciones, esto lo podris

    notar cuando se abra el selector de fiche-

    ros y pulsis el botn cancelar, abris un

    fichero que no contiene MP3, etc.

    Deberis depurarlo.

    Y por ltimo, el mtodo __init__() tpi-

    co en las aplicaciones Python y Jythonque inicializar los valores de la aplica-

    cin creando el panel contenedor de la

    interfaz grfica, e inicializar la variable

    booleana desde la que se controlar la

    parada del reproductor (Stop) y el mtodo

    exit() que permitir a nuestra aplicacin

    salir cuando hagamos clic en el botn de

    cerrar la ventana (la tpica X arriba a la

    derecha).

    Otro punto que debemos comentar es el

    trato que le da Jython a las variables boo-

    leanas ya que no existen los valores true y

    false. Para solucionar este problema, en

    vez de true utilizamos el valor 1 y en vez

    de false utilizaremos el 0, que son los

    valores equivalentes para Java.

    Las libreras que vamos a utilizar son

    las siguientes: org.tritonus.share.sam-

    pled.TAudioFormat y org.tritonus

    .share.sampled.file.TAudioFileFormatque

    vamos a usar para obtener la informacin

    de nuestro MP3. Javax.sound.sampled

    aqu dentro estn nuestras preciadas cla-

    ses SourceDataLine, AudioSystem, etc.

    Java.io para el acceso a ficheros. jarrayque nos permite crear arrays compatibles

    con Java, y por ultimo Java.util,

    Javax.swing, Java.lang, Java.awt,

    Java.util que nos servirn para el resto de

    nuestras tareas.

    En caso de que quisiramos reproducir

    canciones situadas en Internet abriramos la

    ubicacin creando una ocurrencia URL

    (deberemos aadir la libreraJava.net, a lacual le pasamos el protocolo que vamos a

    usar, el host al que tiene que conectarse, el

    puerto de conexin y el nombre del fichero.

    Una vez que tenemos preparada la ubica-

    cin, el objeto URL con el mtodo

    openStream() empieza a extraer el stream de

    ese fichero, ya solo tenemos que pasrselo a

    nuestro reproductor (desde el

    get.AudioInputStream()) y al poco rato

    (dependiendo de la velocidad de conexin y

    el tamao) empezaremos a escuchar msica.

    Todo el programa se puede ver en el

    Listado 1.

    Otro Reproductor es PosibleS, s que tenemos una forma mas fcil de

    crear un reproductor. El cometido de este

    artculo era ver como podamos crear, a

    partir de los elementos que tenemos de

    Java, un reproductor segn nuestras nece-

    sidades (como el tamao del buffer). En

    las libreras que hemos instalado de

    Javazoom, en JLayer concretamente, exis-

    te una clase que crea un reproductor de

    MP3 completo al que nicamente hemosde pasarle el InputStream (con

    FileInputStream) cuando lo creamos, y al

    ejecutar el mtodo .play() (Fig3) de dicho

    reproductor y l se encargar del resto.

    Y El mes que viene volveremos con

    ms scripts en Python y Jython. s

    Jos Pedro Orantes Casado cursa

    3 de Ingeniera Tcnica en

    Informtica de Sistemas y desde

    hace varios aos utiliza linux

    como herramienta de trabajo y

    como sistema de escritorio. Jose

    Mara Ruz est realizando el

    Proyecto Fn de Carrera de

    Ingeniera Tcnica en Informtica

    de Sistemas y lleva mas de 7 aos

    usando y desarrollando Software

    Libre, y desde hace 2 en FreeBSD

    LOS

    AUTORES

    [1] http://www.jython.org

    [2] http://www.Javazoom.net

    [3] http://Java.sun.com

    [4] http://www.tritonus.org

    [5] Descargas de http://www.linux-

    magazine.es

    RECURSOS

    DESARROLLO Python

    64 Nmero 07 W W W . L I NUX - M A G A Z I N E . E S