All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.org.retep.util.io.MP3 Maven / Gradle / Ivy

There is a newer version: 10.6
Show newest version
/*
 * 

Copyright (c) 1998-2007, Peter T Mount
* All rights reserved.

* *

Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:

* *
    *
  • Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
  • * *
  • Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution.
  • * *
  • Neither the name of the retep.org.uk nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission.
  • * *
* *

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/ package uk.org.retep.util.io; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * This class reads in the TAG's contained within an MP3 audio files header. * This could then be used to populate a database with your MP3 collection. * * @author Peter T Mount * @version 1.0 */ public class MP3 implements Serializable { static final long serialVersionUID = 3046921477852383265L; private Map props = new HashMap( ); /** * Tag name containing the year the track was produced */ public static final String YEAR = "TYER"; /** * Tag name containing the album name */ public static final String ALBUM = "TALB"; /** * Tag name containing the source media */ public static final String MED = "TMED"; /** * The track number (ie 01-99 for tracks on a cd) */ public static final String TRACK = "TRCK"; /** * The track length in bytes */ public static final String LENGTH = "TLEN"; /** * The URL for the artist */ public static final String URL_ARTIST = "WOAR"; /** * The URL to buy the cd */ public static final String URL_BUYCD = "WCOM"; /** * The URL for audio? */ public static final String URL_AUDIO = "WOAF"; /** * The title of this track */ public static final String TITLE = "TIT2"; /** * The Lyrics for this track */ public static final String LYRICS = "USLT"; /** * The Genre */ public static final String GENRE = "TCON"; /** * This is unique to MusicMatch. The Situation (ie Dance, Romantic etc) */ public static final String SITUATION = "MusicMatch_Situation"; /** * This is unique to MusicMatch. The Tempo */ public static final String TEMPO = "MusicMatch_Tempo"; /** * This is unique to MusicMatch? Notes */ public static final String NOTES = "notes"; /** * This is unique to MusicMatch. The Mood. */ public static final String MOOD = "MusicMatch_Mood"; /** * This is unique to MusicMatch. The Biography */ public static final String BIO = "MusicMatch_Bio"; /** * Empty Constructor. Does nothing inparticular. */ public MP3( ) { } /** * Construct and read data in from a file * @param aFile File pointing to an MP3 file * @exception IOException */ public MP3( File aFile ) throws IOException { read( aFile ); } /** * Construct and read data in from a file * @param raf RandomAccessFile pointing to an MP3 file * @exception IOException */ public MP3( RandomAccessFile raf ) throws IOException { read( raf ); } /** * @param tag A tag name from within the MP3 file * @return the value of that tag, null if not present. */ public String get( String tag ) { return props.get( tag ); } /** * Obtains an Iterator of tag names in the MP3 file. * @return Iterator */ public Iterator getTags( ) { return props.keySet( ).iterator( ); } /** * Read data in from a file * @param aFile File pointing to an MP3 file * @exception IOException */ public void read( File aFile ) throws IOException { RandomAccessFile raf = new RandomAccessFile( aFile, "r" ); read( raf ); raf.close( ); } /** * Read data in from a file * @param raf RandomAccessFile pointing to an MP3 file * @exception IOException */ public void read( RandomAccessFile raf ) throws IOException { props.clear( ); byte[] b = new byte[2048]; // File header - this bit is dubious // Skip the first part of the header raf.seek( 0 ); raf.read( b, 0, 3 ); raf.read( b, 0, 7 ); // Read in the tags into props while( ripTag( raf, b ) ) { ; } } /** * Helper method for read. Reads in a tag, and returns true if there was a tag * and false if that was the last one. */ private boolean ripTag( RandomAccessFile raf, byte[] b ) throws IOException { // The first 4 bytes form the tag name if( raf.read( b, 0, 4 ) < 4 ) { return false; } if( b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0 ) { return false; } String key = new String( b, 0, 4 ); // The next 4 are the length. int l = raf.readInt( ); // Now there are 2 more scrap bytes here. I don't know what they are for raf.read( b, 0, 2 ); // Now the data byte[] r = new byte[l]; raf.read( r ); // Now The tag COMM is a comment, but MusicMatch adds its own tags using COMM if( key.equals( "COMM" ) ) { if( r[0] == 0 && r[1] == 0 && r[2] == 0 && r[3] == 0 ) { // Find the next 0 int p = 4; while( p < r.length && r[p] != 0 ) { p++; } int q = p; while( p < r.length && r[p] == 0 ) { p++; } // Now form a new key value. This enables MusicMatch's own tags to be // read. if( p > 3 && p < r.length ) { key = new String( r, 4, q - 4 ); byte[] s = new byte[l - p]; System.arraycopy( r, p, s, 0, s.length ); r = s; } } } // Store the result int p = 0; while( p < r.length && r[p] == 0 ) { p++; } props.put( key, new String( r, p, r.length - p ) ); return true; } /** * A simple example application. This reads all mp3 files given on the command * line, and writes their TAG's to System.out. * @param args * @throws java.lang.Exception */ public static void main( String[] args ) throws Exception { for( int i = 0; i < args.length; i++ ) { MP3 mp3 = new MP3( new File( args[i] ) ); System.out.println( "Details about file: " + args[i] + "\n===================" ); Iterator it = mp3.getTags( ); while( it.hasNext( ) ) { String tag = (String) it.next(); System.out.println( tag + "\t\"" + mp3.get( tag ) + "\"" ); } System.out.println( ); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy