|
Multimedia en MIDP 2.0 |
|
En este tutorial estudiamos uno de los aspectos más interesantes de MIDP 2.0: las nuevas capacidades multimedia que ofrece a través de los paquetes javax.microedition.media y javax.microedition.media.control. El nuevo API multimedia que definen estos paquetes es un subconjunto del MMAPI (Mobile Media API) enteramente compatible con el API completo. El API Multimedia constituye una interfaz flexible, simple y potente para el manejo de capacidades multimedia. Mientras que MMAPI permite reproducir y grabar tanto datos de audio como de video, los paquetes aquí estudiados ofrecen un número reducido de acciones relacionados con la reproducción de audio. Como ya se ha comentado, el hecho de poder trabajar con datos multimedia constituye una de los aspectos más novedosos y ventajosos de MIDP 2.0 frente a la versión 1.0. En los últimos tiempos hemos podido constatar la gran evolución que han experimentado los terminales móviles. Es posible desde cualquier terminal móvil reproducir secuencias de tonos con una calidad infinitamente superior a cualquier dispositivo con algunos meses de antigüedad. Por tanto, el hecho de que MIDP 2.0 responda a esta demanda de una herramienta adecuada para poder explotar estas nuevas capacidades, supone un gran acierto y abre nuevas vías al programador. Sin embargo, como veremos a continuación, el conjunto de acciones que podemos llevar a cabo puede parecer excesivamente limitado. En este punto debemos recordar que la definición de MIDP 2.0 abarca un rango de dispositivos considerable y que no todos ellos tienen la misma capacidad para reproducir audio o vídeo. Por este motivo MIDP 2.0 se limita a definir cuál es el mínimo que todos ellos deben satisfacer pudiendo, individualmente, en función del tipo de dispositivo y del fabricante, utilizar el MMAPI completo. Para definir la arquitectura del API multimedia debemos saber que su funcionamiento se basa en los siguientes conceptos básicos:
Así, una vez expuesta la filosofía básica de este API podemos pasar a analizar cuáles son sus clases y métodos. |
|||
|
Manager es como ya se ha dicho el punto de partida para procesar o reproducir datos multimedia. Se nos ofrecen dos opciones:
Los métodos de los que dispone esta clase son:
|
|||
|
Dado que
Player es un interfaz no podemos instanciar objetos directamente sino que, como ya hemos podido ver, debemos
obtenerlos a partir de un objeto
Manager. Ya sabemos cómo podemos hacer esto así que a partir de ahora nos centraremos en conocer que funcionalidad
nos ofrece este interfaz. La acción más sencilla que podemos llevar a cabo es ejecutar el método
start() que dará comienzo a la reproducción lo antes posible. Veremos más adelante todos los pormenores de este
y del resto de métodos del interfaz.
Player nos permite no sólo reproducir audio sino que además permite controlar dicha reproducción e incluso su propio ciclo de vida. CICLO DE VIDA DEL REPRODUCTOR Resulta de gran utilidad definir un ciclo de vida para los reproductores ya que de esta manera el programador será capaz de tener cierto control sobre una serie de operaciones que son susceptibles de consumir gran cantidad de recursos. El ciclo de vida de un objeto Player consta de cinco estados:
El siguiente estado por el que pasaría es el de PREFETCHED. Se llega a él cuando el reproductor ha recibido suficiente cantidad de datos para comenzar con la reproducción. La utilidad de definir este estado radica en que llegan a él los reproductores que están listos para empezar con la reproducción de datos. De esta manera se reduce el tiempo de latencia desde que se indica que se inicie la reproducción y el instante en que realmente comienza. En este punto, cuando haya dado comienzo la reproducción se llegaría al estado STARTED. En la secuencia de estados que acabamos de describir no aparece el estado CLOSED. El reproductor puede llegar a este estado desde cualquiera de los anteriores cuando se indique que no va a ser utilizado nunca más. En este caso el reproductor liberará la mayoría de los recursos que tenía reservados.
El interfaz Player ofrece una serie de métodos que permiten realizar las transiciones anteriormente descritas (en ambos sentidos) a nivel de programador. Además de estos métodos encontramos otros que permiten acceder a la información del reproductor. A la hora de utilizar estos métodos debemos observar cuidadosamente el estado en que se encuentre el objeto Player ya que la información disponible en cada uno de los estados no es la misma. API DEL INTERFAZ Player Los métodos que en este caso tenemos a nuestra disposición son:
|
|||
|
En el apartado anterior en el que analizamos con detalle el interfaz
Player
apareció el concepto de
PlayerListener. Este interfaz implementa un mecanismo de detección de eventos síncronos generados por los reproductores
que nos permiten tener acceso a su estado y control sobre las acciones que ejecuta. Es un mecanismo muy útil ya que
de no disponer de él no podríamos saber cómo y cuándo se produce la transición entre estados de un reproductor.
Para que una aplicación pueda trabajar con este tipo de eventos debe implementar el interfaz PlayerListener y debe asociar un listener a un Player concreto utilizando el método addPlayerListener(PlayerListener listener) que vimos anteriormente. Este interfaz define una serie de eventos definidos como Strings. Sin embargo se permite la definición de eventos propietarios, es decir, eventos definidos por una implementación concreta, aunque estos tendrán una definición diferente para evitar colisiones con los anteriores. Este interfaz consta de un único método:
|
|||
|
Ya pudimos ver en la introducción de este tutorial que uno de los elementos básicos de la arquitectura del API multimedia
es el Controlador o Control. Por tanto necesitamos una entidad que nos permita acceder a dicho controlador y dicha entidad
será la interfaz
Controllable, que nos permite acceder a los controles de los objetos que la implementen (en nuestro caso se tratará
del objeto
Player).
Los métodos que encontramos en esta clase son:
|
|||
|
Este interfaz nos permite definir unos objetos que proporciona una agrupación lógica de una serie de funciones de procesado
multimedia. Como pudimos ver en la introducción este objeto controlador estará asociado a un reproductor concreto y será
utilizado para extender sus funciones de procesado multimedia. La manera de acceder a los controladores es a partir del interfaz
Controllable.
Así,
Player
heredará de
Controllable de manera que podamos obtener como hemos dicho los controladores asociados al reproductor. Además un
mismo reproductor puede implementar más de un tipo de
Control.
MIDP 2.0 define dos subinterfaces de Control: Estos dos nuevos interfaces pertenecen al paquete javax.microedition.media.control (que junto al paquete javax.microedition.media conforma el API multimedia de MIDP 2.0). |
|||
|
ToneControl es un interfaz que permite la reproducción de secuencias de tonos definidas por el programador. Estas
secuencias se definen como una lista de pares (nota - duración). Esta lista se codifica como un array de bytes.
Al tratarse de una interfaz no disponemos de un método constructor sino que se debe obtener utilizando el método
getControl(String controlType) del interfaz
Controllable
(o de
Player como subinterfaz del anterior )
El método que nos ofrece este interfaz para el manejo de secuencias de tonos es:
Ejemplo: ToneControl c = (ToneControl)player.getControl("ToneControl"); c.setSequence(mySequence); |
|||
|
Este interfaz que permite manipular el volumen del audio reproducido por un
Player. Los aspectos más destacados de
VolumeControl
son:
|
|||
|
Ejemplo de utilizacion de las clases e interfaces anteriormente descritas | |||
|
API MIDP/CLDC | |||
|