Leer etiquetas ID3 (información de artista, álbum, etc.…) de ficheros MP3 con Java

Os habréis fijado que todos los reproductores de música saben “mágicamente” el artista, el álbum, el año y demás datos de la canción que les damos a reproducir. Los MP3 tienen una sección en la que se almacenan todos estos datos y acceder a ellos desde Java no es difícil haciendo uso de alguna librería de terceros. En este ejemplo usaremos JID3 de “Blinkenlights”, que podéis encontrar en http://jid3.blinkenlights.org/ Para ver cómo funciona crearemos una clase con un par de métodos que lea alguna etiqueta y la muestre por pantalla. Lo cierto es que la forma de escribirlas sería reemplazar las llamadas a “read” por “write”… vamos, que se nos habría ocurrido a todos ;)Lo primero sería añadir la librería (el jar) de blinkenlights a nuestro proyecto… eso depende del IDE que uséis, si tenéis dudas poned un comentario, seguro que alguno de nosotros usa el mismo que vosotros y os echa una mano :)Yo me he creado una clase “EjemploLecturaID3Tags” (que original soy) con un método Main que llama a un método (readTags) pasándole la ruta a un fichero mp3. El código del método es el siguiente:

 public void readTags(String file) {
  MediaFile mediaFile = new MP3File(new File(file));
  try {
   for (Object obj : mediaFile.getTags()) {
    if (obj instanceof ID3V1_0Tag)
     readID3V1Tags(obj);
    else if (obj instanceof ID3V2_3_0Tag)
     readID3V2_3Tags(obj);
   }
  } catch (ID3Exception e1) {
   e1.printStackTrace();
  }
 }

Vamos a analizarlo. Recibe una cadena de texto (file) que es la ruta al MP3 y crea un objeto MediaFile (es requisito de JID3), hasta ahí claro. Ahora llama a mediaFile.getTags() (que devuelve un array de “Tags” por decirlo de alguna forma) y lo recorre. Si alguien no conocía esa estructura, es el “foreach” de java ;)

Lo raro empieza ahora, para cada elemento (cada “tag”) pregunta si es instancia de ID3V1_0Tag o de ID3V2_3_0Tag. Sí, efectivamente, los ficheros mp3 pueden contener Tags en varios formatos. Lo normal es que ya estén todos en la versión 2… pero no está de más implementar la lectura de las versión 1, que sigue habiendo.

Vale, veréis que el método readTags no las lee, sino que delega la lectura en métodos específicos para cada versión. Ahora os los pongo, pero son muy muy parecidos:

 private void readID3V1Tags(Object obj) {
  ID3V1_0Tag oID3V1_0Tag = (ID3V1_0Tag) obj;
  if (oID3V1_0Tag.getTitle() != null)
   System.out.println(oID3V1_0Tag.getTitle());
  if (oID3V1_0Tag.getAlbum() != null)
   System.out.println(oID3V1_0Tag.getAlbum());
  if (oID3V1_0Tag.getArtist() != null)
   System.out.println(oID3V1_0Tag.getArtist());
 }

 private void readID3V2_3Tags(Object obj) {
  ID3V2_3_0Tag oID3V2_3_0Tag = (ID3V2_3_0Tag) obj;
  if (oID3V2_3_0Tag.getTitle() != null)
   System.out.println(oID3V2_3_0Tag.getTitle());
  if (oID3V2_3_0Tag.getAlbum() != null)
   System.out.println(oID3V2_3_0Tag.getAlbum());
  if (oID3V2_3_0Tag.getArtist() != null)
   System.out.println(oID3V2_3_0Tag.getArtist());
 }

El método, aunque algo cutre, funciona. Se basa en preguntar por las etiquetas que queremos y mostrarlas por pantalla en caso de que sean distintas de null, vamos, en caso de que exista.

Si tenéis cualquier duda, ya sabéis, usad los comentarios. ¡Suerte!

Por Carballude

Me llamo Pablo Carballude González, soy graduado en computación con master en HCI y Seguridad Informática. Actualmente trabajo para Amazon en Seattle como Software Developer Engineer. Soy de esas personas que no saben si los textos autobiográficos deben ser en primera o tercera persona. Lo intenté en segunda, pero no le entendí nada :P

21 comentarios

  1. hola sabes tengo q hacer eso mismo en java pero usando netbeans… tengo toda la idea en la mente pero no se como importar la libreria Blinkenlights para usarla y despues de descargarla donde se guarda XD..

    atte Marcelo

    ps uso net Beans 6.1

  2. perdon por la doble replica….

    se me olvidaba como puedo obtener el tiempo total de la cancion?

    se puede obtener con el Player.getMediaDuration(); pero hasta el momento de reproducirla…..

  3. @Ashkro-sama: Lo cierto es que no recuerdo como lo hice en su momento, pero en http://www.onjava.com/pub/a/onjava/2004/08/11/javasound-mp3.html?page=2 explican una forma que parece buena:

    File file = new File(«filename.mp3»);
    AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(file);
    Map properties = baseFileFormat.properties();
    String key_duration = «duration»;
    Long duration = (Long) properties.get(key_duration);

    Duration devuelve el número total de microsegundos del mp3 :)

  4. Por favor, no me aparece ningun error, pero tengo problemas yó creo que con el metodo main que no esta enviando la ruta.

    package readtags;
    import javax.swing.*;

    public class Principal {

    public static void main(String[] args) {

    etiquetas objeto = new etiquetas();

    String file=»»;
    file=JOptionPane.showInputDialog(null, //Crea un cuadro de dialogo para introducir la ruta del archivo
    «Escriba la direccion y el nombre del archivo»+
    «\nPor ejemplo: d:\\welcome.mp3»,
    «Ruta»,
    JOptionPane.QUESTION_MESSAGE);

    objeto.readTags(file);

    }

    }

  5. Hola amigo volvi a hacer todo desde cero y ya me está funcionando a la perfecccion.

    Tengo una pregunta, ¿Tambien se pueden obtener
    el genero, duracion y numero de pista de la cancion?
    gracias…

  6. Hola Carballude he tenido problemas al querer obtener el numero de pista (getTrackNumber) y el año (getYear), porfavor como lo puedo solucionar
    gracias.

  7. El problema que tenía era que no podia obtener ni el numero, ni el año de la pista pero ya me está funcionando lo hice así:

    if (oID3V2_3_0Tag.getGenre() != null) {
    System.out.println(oID3V2_3_0Tag.getGenre());
    }

    if (oID3V2_3_0Tag.getGenre() != null) {
    System.out.println(oID3V2_3_0Tag.getYear());
    }

    if (oID3V2_3_0Tag.getGenre() != null) {
    System.out.println(oID3V2_3_0Tag.getTrackNumber());
    }

    pero no se si esta sea la forma mas adecuada ya que estoy utilizando el .getGenre() tambien para mostrar el numero y el año.

  8. disculpa para modificar el title de la cancion… como podria aser?? trae algun metodo implicito.. desde ya muchas gracias por tu atencion

  9. Carballude :
    @Ashkro-sama: Lo cierto es que no recuerdo como lo hice en su momento, pero en http://www.onjava.com/pub/a/onjava/2004/08/11/javasound-mp3.html?page=2 explican una forma que parece buena:
    File file = new File(“filename.mp3″);
    AudioFileFormat baseFileFormat = AudioSystem.getAudioFileFormat(file);
    Map properties = baseFileFormat.properties();
    String key_duration = “duration”;
    Long duration = (Long) properties.get(key_duration);
    Duration devuelve el número total de microsegundos del mp3 :)

    Estimado.

    Por más que trato de realizar ese trozo de código, me arroja una excepción:

    javax.sound.sampled.UnsupportedAudioFileException: file is not a supported file type

    y el archivo que le paso es efectivamente un MP3 =(

  10. buen post gracias brotherrrrrrrrrrrrrrrrrrrr puxa esto era justo lo k keria , stoy haciendo un reproductor mp3 y esto esta genial gracias por compartir tus conocimientos aaa y en lo del año a mi tbm me sale error cuando iamo a getYear() noc porq .. para evitar ese error mejor iamo a getGenre() XD!!!!!!! si hay alguna forma del obtener el año posteala se te agradeceriaa :P

  11. Hola Pablo, te quería preguntar, mira, has probado a recuperar las carátulas de los mp3, tengo entendido q ese tag se incorporó en la versión 2 de ID3. Estoy intentando desarrollar un reproductor de podcast y me falta, entre otras muchas cosas, la opción de mostrar la carátula.

    Muchas thanks.

  12. Que tal excelente post felicitaciones..!! pero que pasaria si quiesisras obteber un tag de una imagen es decir cuanod una cancion tiene una imagen y cargar no se en un Jlabel.!!

    Gracias Saludos.!!

  13. como va la codificacion para probarlos …el bloque de codigo de public void readTags(String file)…en que parte se escribe..en el main? y el private void readID3V1Tags(Object obj)..en donde..o como puedo hacerlo para ejecutar..soy principaiante en java…y me intersa mucho este ejemplo

Dejar un comentario

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