Audio y video en Java utilizando ffmpeg, Jffmpeg, y JMF

Introducción

Supongamos que queremos implementar un reproductor multimedia en Java. Si a priori no conocemos los codecs de audio o video que debemos soportar, o si simplemente no existe una implementación de ese codec en Java, podemos interactuar con ffmpeg para reproducir multimedia en un montón de formatos diferentes. Para ello podemos utilizar JMF, Jffmpeg del lado del “mundo Java” interactuando con ffmpeg del lado del “mundo nativo”.

ffmpeg es una solución muy completa, open source y multi plataforma para grabar, convertir y reproducir audio y video. El proyecto está licenciado bajo LGPL o GPL (dependiendo de la configuración).

JMF (Java Media Framework) es una API  que permite agregar audio y video a nuestras aplicaciones y applets implementadas sobre tecnología Java. Además de reproducir, JMF nos permite
capturar, transcodificar o hacer streaming en varios formatos.

Jffmpeg es el puente entre ffmpeg y JMF. Si bien JMF soporta algunos formatos, eventualmente nos cruzaremos con el mensaje de error “Unable to handle format:…”, especialmente al intentar reproducir los formatos más nuevos. Este plugin de JMF un wrapper Java que utiliza JNI para hacer las llamadas directas al código nativo de ffmpeg.

Instalación en Linux

Vamos a instalar y configurar las diferentes partes de la solución para poder reproducir video en Linux. Quizá el post tienda a compilar todo y configurar “a mano”, es debido a que documenta la necesidad de reproducción de pautas publicitarias en un NLPOS, un flavour de Linux de Novell bastante recortado y orientado a puntos de venta.

1. Instalación de ffmpeg

Como primer punto, compilaremos e instalaremos ffmpeg a partir del código fuente. Tenemos varias opciones: hacer un checkout de SVN, hacer un GIT clone,
o bajarnos el código de la última versión estable. Para cualquier opción, contamos con lo que necesitamos aquí.

Es una buena idea instalar codecs externos para luego poder integrarlos con ffmpeg. Entre estos codecs externos tenemos a LAME para MPEG Audio Layer III,  AMR para 3GPP y xvid para los estándares MPEG-4 Simple Profile and Advanced Simple Profile.

La primer parte de este link nos muestra cómo instalar los diferentes tanto los codecs externos como ffmpeg.

Para la instalación más básica, sin codecs externos, basta con hacer un

./configure

en el directorio en donde está ubicado el código de ffmpeg, luego un

make

y finalmente, con permisos de root un

make install

En distribuciones de Linux más “modernas”  seguramente tengamos la opción de instalar ffmpeg desde repositorios de paquetes, sin la necesidad de compilarlo a mano.

2. Instalación de JMF

JMF no tiene mucha ciencia para instalarlo, simplemente bajamos el instalador de aquí y lo corremos en el directorio que queramos instalarlo. Yo lo ejecuté desde /usr/lib para que JMF quede en /usr/lib/JMF-2.1.1e/ (llamaremos ${JMF_HOME} al directorio de instalación), pero no repercute en el funcionamiento. Debemos recordar que ${JMF_HOME}/lib/jmf.jar deberá estar en el classpath de nuestra aplicación.

3. Instalación de Jffmpeg

Jffmpeg tampoco da muchas dificultades para instalarlo. Podemos bajar el JAR y el .so (o .dll) de aquí, y descomprimirlos en el directorio que nos resulte más cómodo. Lo que debemos tener en cuenta después, es que el JAR deberá estar
en el classpath de nuestra aplicación, y el .so en LD_LIBRARY_PATH, o configurado en el path de las librerías de Linux.

Llamaremos ${JFFMPEG_HOME} al directorio en donde tenemos el JAR y el .so.

4. Classpath, LD_LIBRARY_PATH, etc.

Tanto las librerías nativas como los JARs de JMF y Jffmpeg deberán estar referenciadas por nuestra aplicación para ser tenidas en cuenta.

Para los JARs basta con agregarlos a una variable de entorno que luego se referenciará en el classpath de nuestra aplicación.

Para las librerías nativas podemos agregar un archivo de extensión conf en /etc/ld.so.conf.d/ que contenga una línea para cada directorio que deba ser considerado al buscar las librerías.

La otra opción es agregar los directorios a la variable de entorno LD_LIBRARY_PATH. Esta variable contiene una lista de directorio separados por coma, la cual es utilizada por el sistema operativo para buscar librerías antes de recurrir al conjunto predeterminado de directorios.

Si no queremos definir este conjunto de variables a mano, podemos editar el archivo ~/.bashrc agregando las siguientes líneas (quizá las rutas no sean las que correspondan):

# cat ~/.bashrc

export JMF_HOME=/usr/lib/JMF-2.1.1e
export JFFMPEG_HOME=/root/jffmpeg
export CLASSPATH=$ JMF_HOME /lib/jmf.jar:$JFFMPEG_HOME/jffmpeg-1.1.0.jar:.:$CLASSPATH
export LD_LIBRARY_PATH=$ JMF_HOME /lib:$JFFMPEG_HOME:${LD_LIBRARY_PATH}
export JAVA_HOME=/usr/java/jdk1.6.0_14

5. Registro de los codecs

Para agregar los codecs de Jffmpeg en JMF utilizaremos la herramienta JMFRegistry que viene con el Java Media Framework. Podemos ejecutarlo por consola tipeando “java JMFRegistry” o desde las preferencias del JMStudio, otra herramienta de JMF que hace de Media Player.

Para cada cambio que listamos a continuación, debemos hacer clickear el botón de commit.

En la pestaña de “Mime types” registramos las siguientes extensiones:

  1. video/vob -> vob
  2. audio/ogg -> ogg

Bajo la pestaña “
Plugins” registramos los siguientes “Demultiplexers”:

  1. net.sourceforge.jffmpeg.demux.vob.VobDemux
  2. net.sourceforge.jffmpeg.demux.ogg.OggDemux

Y bajo la pestaña “Codec” registramos los siguientes codecs:

  1. net.sourceforge.jffmpeg.VideoDecoder
  2. net.sourceforge.jffmpeg.AudioDecoder

6. Parámetros de la aplicación

Como último paso, debemos recordar agregar ya sea la variable $CLASSPATH al classpath de nuestra aplicación, o cada JAR por separado (${JMF_HOME}libjmf.jar,   ${JFFMPEG_HOME}jffmpeg-1.1.0.jar).

Conclusión

Si bien no es “soplar y hacer botellas”, en Java tenemos la posibilidad de agregar contenido multimedia a nuestras aplicaciones o applets utilizando la potencialidad que nos dan los codecs implementados como código nativo al sistema operativo.

En este post vimos un ejemplo en instalación y configuración en Linux; la configuración en Windows no es demasiado diferente.

Referencias

http://jffmpeg.sourceforge.net/download.html

http://downloads.xvid.org/downloads/xvidcore-1.2.2.tar.bz2

http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/download.html

http://www.ffmpeg.org/

http://jffmpeg.sourceforge.net/

http://www.hiteshagrawal.com/ffmpeg/installing-ffmpeg-easily-on-linux

http://www.elctech.com/articles/installing-ffmpeg-with-faac-and-x264-encoders-from-source-on-ubuntu

http://www.luniks.net/luniksnet/html/java/jtvd/doc/jmf.html

http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Etiquetado , , , , . Bookmark the permalink.

8 respuestas a Audio y video en Java utilizando ffmpeg, Jffmpeg, y JMF

  1. Richard says:

    Una pregunta, la dll para windows sabes si es necesaria? Porque no se encuentra en el sitio oficial de descarga. Otra cosa, te ha pasado que cuando queres agregar el codec te sale un mensaje de error que no se puede agregar el item?

    • jarrarte says:

      Buenas Richard, primero que nada gracias por tu comentario. Te confirmo que la DLL es necesaria, dado que la parte java es simplemente un wrapper de toda la funcionalidad que nos ofrece ffmpeg. Puedes descargar una compilación hecha para Windows en http://ffmpeg.arrozcru.org/builds/ (te sirve la “shared”, es con las librerías de los codecs por separado). No lo probé, pero pienso que bajándote uno de los ffmpeg-r*-gpl-shared-win32.tar.bz2, y agregando las DLLs que están en /bin a tu LD_LIBRARY_PATH debería funcionar. Es muy posible que el no tener las librerías sea la causa del error al intentar agregar el codec. ¡Mucha suerte!

  2. Richard says:

    Lo que hice fue agregar en la variable de entorno CLASSPATH de Windows la ubicación del jar de JFFMPEG y de esa manera pude agregar los codec e importarlo al momento de compilar el proyecto pero gracias de todas maneras, supongo que la DLL no es necesaria porque no he tenido problemas además no esta para descargar en el sitio oficial del proyecto de JFFMPEG.

  3. CPJ says:

    Una pregunta… Estoy intentando hacer una aplicación Java (con Eclipse) que reproduzca el máximo número de formatos de audio y video posibles.
    Una vez descartado el JMF, estoy usando jffmpeg. Mi intención es que la aplicación sea independiente del SO, así que no tengo la dll. He importado en mi proyecto el .jar de jffmpeg. Cuando quiero reproducir un video MPEG 4 me da un error, y en teoría es un formato válido. ¿Podéis darme alguna idea sobre cómo usar las distintas implementaciones de códecs que trae el JFFMPEG?
    Gracias!

    • jarrarte says:

      ¿Cómo estás? Recuerda que Jffmpeg no implementa todas las funcionalidades de ffmpeg. Si bien tiene unos cuantos codecs portados a Java puro, para otros es simplemente un wrapper, invocando mediante JNI a los codecs implementados por ffmpeg.

      En http://jffmpeg.sourceforge.net/formats.html hay una lista de formatos implementados en Java, pero capaz que lo mejor es pensar en incluir ffmpeg como parte de tu aplicativo, o como requerimiento previo. Me da la impresión de que es un proyecto que evoluciona más rápido que Jffmpeg en lo que respecta a nuevos codecs, mejoras de performance, bugs, etc. (la última actualización de jffpmeg fue en enero de 2006, mientras que el proyecto de ffmpeg sigue activo).

      Quedo a las órdenes ¡Mucha suerte!

  4. Sergio says:

    Quisiera saber como puedo editar un audio en fomato mp3 utilizando ffmpeg.Gracias d

  5. leonardo says:

    Amigo, un par de preguntas… ya tiene tiempo que no uso JMF, ya soporta JRE y JDK de 64 bits?, funciona con openJDK?

    Espero que aun tengas este post “vivo”, graicas.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *