summaryrefslogtreecommitdiffstats
path: root/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java')
-rw-r--r--songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java772
1 files changed, 0 insertions, 772 deletions
diff --git a/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java b/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
deleted file mode 100644
index 54440551a1..0000000000
--- a/songdbj/javazoom/spi/mpeg/sampled/file/MpegAudioFileReader.java
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * MpegAudioFileReader.
- *
- * 12/31/04 : mp3spi.weak system property added to skip controls.
- *
- * 11/29/04 : ID3v2.2, v2.3 & v2.4 support improved.
- * "mp3.id3tag.composer" (TCOM/TCM) added
- * "mp3.id3tag.grouping" (TIT1/TT1) added
- * "mp3.id3tag.disc" (TPA/TPOS) added
- * "mp3.id3tag.encoded" (TEN/TENC) added
- * "mp3.id3tag.v2.version" added
- *
- * 11/28/04 : String encoding bug fix in chopSubstring method.
- *
- * JavaZOOM : mp3spi@javazoom.net
- * http://www.javazoom.net
- *
- *-----------------------------------------------------------------------
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as published
- * by the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *----------------------------------------------------------------------
- */
-
-package javazoom.spi.mpeg.sampled.file;
-
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.AccessControlException;
-import java.util.HashMap;
-
-import javax.sound.sampled.AudioFileFormat;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.UnsupportedAudioFileException;
-
-import javazoom.jl.decoder.Bitstream;
-import javazoom.jl.decoder.Header;
-import javazoom.spi.mpeg.sampled.file.tag.IcyInputStream;
-import javazoom.spi.mpeg.sampled.file.tag.MP3Tag;
-
-import org.tritonus.share.TDebug;
-import org.tritonus.share.sampled.file.TAudioFileReader;
-
-/**
- * This class implements AudioFileReader for MP3 SPI.
- */
-public class MpegAudioFileReader extends TAudioFileReader
-{
- private final int SYNC = 0xFFE00000;
- private String weak = null;
- private final AudioFormat.Encoding[][] sm_aEncodings =
- {
- {MpegEncoding.MPEG2L1, MpegEncoding.MPEG2L2, MpegEncoding.MPEG2L3},
- {MpegEncoding.MPEG1L1, MpegEncoding.MPEG1L2, MpegEncoding.MPEG1L3},
- {MpegEncoding.MPEG2DOT5L1, MpegEncoding.MPEG2DOT5L2, MpegEncoding.MPEG2DOT5L3},
-
- };
-
- private static final int INITAL_READ_LENGTH = 64000;
- private static final int MARK_LIMIT = INITAL_READ_LENGTH + 1;
-
- private static final String[] id3v1genres = {
- "Blues"
- , "Classic Rock"
- , "Country"
- , "Dance"
- , "Disco"
- , "Funk"
- , "Grunge"
- , "Hip-Hop"
- , "Jazz"
- , "Metal"
- , "New Age"
- , "Oldies"
- , "Other"
- , "Pop"
- , "R&B"
- , "Rap"
- , "Reggae"
- , "Rock"
- , "Techno"
- , "Industrial"
- , "Alternative"
- , "Ska"
- , "Death Metal"
- , "Pranks"
- , "Soundtrack"
- , "Euro-Techno"
- , "Ambient"
- , "Trip-Hop"
- , "Vocal"
- , "Jazz+Funk"
- , "Fusion"
- , "Trance"
- , "Classical"
- , "Instrumental"
- , "Acid"
- , "House"
- , "Game"
- , "Sound Clip"
- , "Gospel"
- , "Noise"
- , "AlternRock"
- , "Bass"
- , "Soul"
- , "Punk"
- , "Space"
- , "Meditative"
- , "Instrumental Pop"
- , "Instrumental Rock"
- , "Ethnic"
- , "Gothic"
- , "Darkwave"
- , "Techno-Industrial"
- , "Electronic"
- , "Pop-Folk"
- , "Eurodance"
- , "Dream"
- , "Southern Rock"
- , "Comedy"
- , "Cult"
- , "Gangsta"
- , "Top 40"
- , "Christian Rap"
- , "Pop/Funk"
- , "Jungle"
- , "Native American"
- , "Cabaret"
- , "New Wave"
- , "Psychadelic"
- , "Rave"
- , "Showtunes"
- , "Trailer"
- , "Lo-Fi"
- , "Tribal"
- , "Acid Punk"
- , "Acid Jazz"
- , "Polka"
- , "Retro"
- , "Musical"
- , "Rock & Roll"
- , "Hard Rock"
- , "Folk"
- , "Folk-Rock"
- , "National Folk"
- , "Swing"
- , "Fast Fusion"
- , "Bebob"
- , "Latin"
- , "Revival"
- , "Celtic"
- , "Bluegrass"
- , "Avantgarde"
- , "Gothic Rock"
- , "Progressive Rock"
- , "Psychedelic Rock"
- , "Symphonic Rock"
- , "Slow Rock"
- , "Big Band"
- , "Chorus"
- , "Easy Listening"
- , "Acoustic"
- , "Humour"
- , "Speech"
- , "Chanson"
- , "Opera"
- , "Chamber Music"
- , "Sonata"
- , "Symphony"
- , "Booty Brass"
- , "Primus"
- , "Porn Groove"
- , "Satire"
- , "Slow Jam"
- , "Club"
- , "Tango"
- , "Samba"
- , "Folklore"
- , "Ballad"
- , "Power Ballad"
- , "Rhythmic Soul"
- , "Freestyle"
- , "Duet"
- , "Punk Rock"
- , "Drum Solo"
- , "A Capela"
- , "Euro-House"
- , "Dance Hall"
- , "Goa"
- , "Drum & Bass"
- , "Club-House"
- , "Hardcore"
- , "Terror"
- , "Indie"
- , "BritPop"
- , "Negerpunk"
- , "Polsk Punk"
- , "Beat"
- , "Christian Gangsta Rap"
- , "Heavy Metal"
- , "Black Metal"
- , "Crossover"
- , "Contemporary Christian"
- , "Christian Rock"
- , "Merengue"
- , "Salsa"
- , "Thrash Metal"
- , "Anime"
- , "JPop"
- , "SynthPop"
- };
-
- public MpegAudioFileReader()
- {
- super(MARK_LIMIT, true);
- if (TDebug.TraceAudioFileReader) TDebug.out(">MpegAudioFileReader(1.9.2-FINAL)");
- try
- {
- weak = System.getProperty("mp3spi.weak");
- }
- catch(AccessControlException e)
- {}
- }
-
- /**
- * Returns AudioFileFormat from File.
- */
- public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException
- {
- return super.getAudioFileFormat(file);
- }
-
- /**
- * Returns AudioFileFormat from URL.
- */
- public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException
- {
- if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioFileFormat(URL): begin"); }
- long lFileLengthInBytes = AudioSystem.NOT_SPECIFIED;
- URLConnection conn = url.openConnection();
- // Tell shoucast server (if any) that SPI support shoutcast stream.
- conn.setRequestProperty ("Icy-Metadata", "1");
- InputStream inputStream = conn.getInputStream();
- AudioFileFormat audioFileFormat = null;
- try
- {
- audioFileFormat = getAudioFileFormat(inputStream, lFileLengthInBytes);
- }
- finally
- {
- inputStream.close();
- }
- if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioFileFormat(URL): end"); }
- return audioFileFormat;
- }
-
- /**
- * Returns AudioFileFormat from inputstream and medialength.
- */
- public AudioFileFormat getAudioFileFormat(InputStream inputStream, long mediaLength) throws UnsupportedAudioFileException, IOException
- {
- if (TDebug.TraceAudioFileReader) TDebug.out(">MpegAudioFileReader.getAudioFileFormat(InputStream inputStream, long mediaLength): begin");
- HashMap aff_properties = new HashMap();
- HashMap af_properties = new HashMap();
- int mLength = (int) mediaLength;
- int size = inputStream.available();
- PushbackInputStream pis = new PushbackInputStream(inputStream, MARK_LIMIT);
- byte head[] = new byte[12];
- pis.read(head);
- if (TDebug.TraceAudioFileReader)
- {
- TDebug.out("InputStream : "+inputStream + " =>" + new String(head));
- }
- /*
- * Check for WAV, AU, and AIFF file formats.
- *
- * Next check for Shoutcast (supported) and OGG (unsupported) streams.
- *
- * Note -- the check for WAV files will reject Broadcast WAV files.
- * This may be incorrect as broadcast WAV files may contain MPEG data.
- * Need to investigate.
- *
- */
- if ((head[0] == 'R') && (head[1] == 'I') && (head[2] == 'F') && (head[3] == 'F') && (head[8] == 'W') && (head[9] == 'A') && (head[10] == 'V') && (head[11] == 'E'))
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("WAV stream found");
- if (weak == null) throw new UnsupportedAudioFileException("WAV stream found");
- }
- else if ((head[0] == '.') && (head[1] == 's') && (head[2] == 'n') && (head[3] == 'd'))
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("AU stream found");
- if (weak == null) throw new UnsupportedAudioFileException("AU stream found");
- }
- else if ((head[0] == 'F') && (head[1] == 'O') && (head[2] == 'R') && (head[3] == 'M') && (head[8] == 'A') && (head[9] == 'I') && (head[10] == 'F') && (head[11] == 'F'))
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("AIFF stream found");
- if (weak == null) throw new UnsupportedAudioFileException("AIFF stream found");
- }
- // Shoutcast stream ?
- else if (((head[0] == 'I') | (head[0] == 'i')) && ((head[1] == 'C') | (head[1] == 'c')) && ((head[2] == 'Y') | (head[2] == 'y')))
- {
- pis.unread(head);
- // Load shoutcast meta data.
- loadShoutcastInfo(pis, aff_properties);
- }
- // Ogg stream ?
- else if (((head[0] == 'O') | (head[0] == 'o')) && ((head[1] == 'G') | (head[1] == 'g')) && ((head[2] == 'G') | (head[2] == 'g')))
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("Ogg stream found");
- if (weak == null) throw new UnsupportedAudioFileException("Ogg stream found");
- }
- // No, so pushback.
- else
- {
- pis.unread(head);
- }
- // MPEG header info.
- int nVersion = AudioSystem.NOT_SPECIFIED;
- int nLayer = AudioSystem.NOT_SPECIFIED;
- int nSFIndex = AudioSystem.NOT_SPECIFIED;
- int nMode = AudioSystem.NOT_SPECIFIED;
- int FrameSize = AudioSystem.NOT_SPECIFIED;
- int nFrameSize = AudioSystem.NOT_SPECIFIED;
- int nFrequency = AudioSystem.NOT_SPECIFIED;
- int nTotalFrames = AudioSystem.NOT_SPECIFIED;
- float FrameRate = AudioSystem.NOT_SPECIFIED;
- int BitRate = AudioSystem.NOT_SPECIFIED;
- int nChannels = AudioSystem.NOT_SPECIFIED;
- int nHeader = AudioSystem.NOT_SPECIFIED;
- int nTotalMS = AudioSystem.NOT_SPECIFIED;
- boolean nVBR = false;
- AudioFormat.Encoding encoding = null;
- try
- {
- Bitstream m_bitstream = new Bitstream(pis);
- aff_properties.put("mp3.header.pos",new Integer(m_bitstream.header_pos()));
- Header m_header = m_bitstream.readFrame();
- // nVersion = 0 => MPEG2-LSF (Including MPEG2.5), nVersion = 1 => MPEG1
- nVersion = m_header.version();
- if (nVersion == 2) aff_properties.put("mp3.version.mpeg",Float.toString(2.5f));
- else aff_properties.put("mp3.version.mpeg",Integer.toString(2-nVersion));
- // nLayer = 1,2,3
- nLayer = m_header.layer();
- aff_properties.put("mp3.version.layer",Integer.toString(nLayer));
- nSFIndex = m_header.sample_frequency();
- nMode = m_header.mode();
- aff_properties.put("mp3.mode",new Integer(nMode));
- nChannels = nMode == 3 ? 1 : 2;
- aff_properties.put("mp3.channels",new Integer(nChannels));
- nVBR = m_header.vbr();
- af_properties.put("vbr",new Boolean(nVBR));
- aff_properties.put("mp3.vbr",new Boolean(nVBR));
- aff_properties.put("mp3.vbr.scale",new Integer(m_header.vbr_scale()));
- FrameSize = m_header.calculate_framesize();
- aff_properties.put("mp3.framesize.bytes",new Integer(FrameSize));
- if (FrameSize < 0) throw new UnsupportedAudioFileException("Invalid FrameSize : " + FrameSize);
- nFrequency = m_header.frequency();
- aff_properties.put("mp3.frequency.hz",new Integer(nFrequency));
- FrameRate = (float) ((1.0 / (m_header.ms_per_frame())) * 1000.0);
- aff_properties.put("mp3.framerate.fps",new Float(FrameRate));
- if (FrameRate < 0) throw new UnsupportedAudioFileException("Invalid FrameRate : " + FrameRate);
- if (mLength != AudioSystem.NOT_SPECIFIED)
- {
- aff_properties.put("mp3.length.bytes",new Integer(mLength));
- nTotalFrames = m_header.max_number_of_frames(mLength);
- aff_properties.put("mp3.length.frames",new Integer(nTotalFrames));
- }
- BitRate = m_header.bitrate();
- af_properties.put("bitrate",new Integer(BitRate));
- aff_properties.put("mp3.bitrate.nominal.bps",new Integer(BitRate));
- nHeader = m_header.getSyncHeader();
- encoding = sm_aEncodings[nVersion][nLayer - 1];
- aff_properties.put("mp3.version.encoding",encoding.toString());
- if (mLength != AudioSystem.NOT_SPECIFIED)
- {
- nTotalMS = Math.round(m_header.total_ms(mLength));
- aff_properties.put("duration",new Long((long)nTotalMS*1000L));
- }
- aff_properties.put("mp3.copyright",new Boolean(m_header.copyright()));
- aff_properties.put("mp3.original",new Boolean(m_header.original()));
- aff_properties.put("mp3.crc",new Boolean(m_header.checksums()));
- aff_properties.put("mp3.padding",new Boolean(m_header.padding()));
- InputStream id3v2 = m_bitstream.getRawID3v2();
- if (id3v2 != null)
- {
- aff_properties.put("mp3.id3tag.v2",id3v2);
- parseID3v2Frames(id3v2,aff_properties);
- }
- if (TDebug.TraceAudioFileReader) TDebug.out(m_header.toString());
- }
- catch (Exception e)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("not a MPEG stream:" + e.getMessage());
- throw new UnsupportedAudioFileException("not a MPEG stream:" + e.getMessage());
- }
-
- // Deeper checks ?
- int cVersion = (nHeader >> 19) & 0x3;
- if (cVersion == 1)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("not a MPEG stream: wrong version");
- throw new UnsupportedAudioFileException("not a MPEG stream: wrong version");
- }
-
- int cSFIndex = (nHeader >> 10) & 0x3;
- if (cSFIndex == 3)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("not a MPEG stream: wrong sampling rate");
- throw new UnsupportedAudioFileException("not a MPEG stream: wrong sampling rate");
- }
-
- // Look up for ID3v1 tag
- if ((size == mediaLength) && (mediaLength != AudioSystem.NOT_SPECIFIED))
- {
- FileInputStream fis = (FileInputStream) inputStream;
- byte[] id3v1 = new byte[128];
- long bytesSkipped = fis.skip(inputStream.available()-id3v1.length);
- int read = fis.read(id3v1,0,id3v1.length);
- if ((id3v1[0]=='T') && (id3v1[1]=='A') && (id3v1[2]=='G'))
- {
- parseID3v1Frames(id3v1, aff_properties);
- }
- }
-
- AudioFormat format = new MpegAudioFormat(encoding, (float) nFrequency, AudioSystem.NOT_SPECIFIED // SampleSizeInBits - The size of a sample
- , nChannels // Channels - The number of channels
- , -1 // The number of bytes in each frame
- , FrameRate // FrameRate - The number of frames played or recorded per second
- , true
- , af_properties);
- return new MpegAudioFileFormat(MpegFileFormatType.MP3, format, nTotalFrames, mLength,aff_properties);
- }
-
- /**
- * Returns AudioInputStream from file.
- */
- public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("getAudioInputStream(File file)");
- InputStream inputStream = new FileInputStream(file);
- try
- {
- return getAudioInputStream(inputStream);
- }
- catch (UnsupportedAudioFileException e)
- {
- if (inputStream != null) inputStream.close();
- throw e;
- }
- catch (IOException e)
- {
- if (inputStream != null) inputStream.close();
- throw e;
- }
- }
-
- /**
- * Returns AudioInputStream from url.
- */
- public AudioInputStream getAudioInputStream(URL url)
- throws UnsupportedAudioFileException, IOException
- {
- if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioInputStream(URL): begin"); }
- long lFileLengthInBytes = AudioSystem.NOT_SPECIFIED;
- URLConnection conn = url.openConnection();
- // Tell shoucast server (if any) that SPI support shoutcast stream.
- boolean isShout = false;
- int toRead=4;
- byte[] head = new byte[toRead];
-
- conn.setRequestProperty ("Icy-Metadata", "1");
- BufferedInputStream bInputStream = new BufferedInputStream(conn.getInputStream());
- bInputStream.mark(toRead);
- int read = bInputStream.read(head,0,toRead);
- if ((read>2) && (((head[0] == 'I') | (head[0] == 'i')) && ((head[1] == 'C') | (head[1] == 'c')) && ((head[2] == 'Y') | (head[2] == 'y')))) isShout = true;
- bInputStream.reset();
- InputStream inputStream = null;
- // Is is a shoutcast server ?
- if (isShout == true)
- {
- // Yes
- IcyInputStream icyStream = new IcyInputStream(bInputStream);
- icyStream.addTagParseListener(IcyListener.getInstance());
- inputStream = icyStream;
- }
- else
- {
- // No, is Icecast 2 ?
- String metaint = conn.getHeaderField("icy-metaint");
- if (metaint != null)
- {
- // Yes, it might be icecast 2 mp3 stream.
- IcyInputStream icyStream = new IcyInputStream(bInputStream,metaint);
- icyStream.addTagParseListener(IcyListener.getInstance());
- inputStream = icyStream;
- }
- else
- {
- // No
- inputStream = bInputStream;
- }
- }
- AudioInputStream audioInputStream = null;
- try
- {
- audioInputStream = getAudioInputStream(inputStream, lFileLengthInBytes);
- }
- catch (UnsupportedAudioFileException e)
- {
- inputStream.close();
- throw e;
- }
- catch (IOException e)
- {
- inputStream.close();
- throw e;
- }
- if (TDebug.TraceAudioFileReader) {TDebug.out("MpegAudioFileReader.getAudioInputStream(URL): end"); }
- return audioInputStream;
- }
-
- /**
- * Return the AudioInputStream from the given InputStream.
- */
- public AudioInputStream getAudioInputStream(InputStream inputStream) throws UnsupportedAudioFileException, IOException
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("MpegAudioFileReader.getAudioInputStream(InputStream inputStream)");
- if (!inputStream.markSupported()) inputStream = new BufferedInputStream(inputStream);
- return super.getAudioInputStream(inputStream);
- }
-
- /**
- * Parser ID3v1 frames
- * @param frames
- * @param props
- */
- protected void parseID3v1Frames(byte[] frames, HashMap props)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("Parsing ID3v1");
- String tag = null;
- try
- {
- tag = new String(frames, 0, frames.length, "ISO-8859-1");
- }
- catch (UnsupportedEncodingException e)
- {
- tag = new String(frames, 0, frames.length);
- if (TDebug.TraceAudioFileReader) TDebug.out("Cannot use ISO-8859-1");
- }
- if (TDebug.TraceAudioFileReader) TDebug.out("ID3v1 frame dump='"+tag+"'");
- int start = 3;
- String titlev1 = chopSubstring(tag, start, start += 30);
- String titlev2 = (String) props.get("title");
- if (((titlev2==null) || (titlev2.length()==0)) && (titlev1 != null)) props.put("title",titlev1);
- String artistv1 = chopSubstring(tag, start, start += 30);
- String artistv2 = (String) props.get("author");
- if (((artistv2==null) || (artistv2.length()==0)) && (artistv1 != null)) props.put("author",artistv1);
- String albumv1 = chopSubstring(tag, start, start += 30);
- String albumv2 = (String) props.get("album");
- if (((albumv2==null) || (albumv2.length()==0)) && (albumv1 != null)) props.put("album",albumv1);
- String yearv1 = chopSubstring(tag, start, start += 4);
- String yearv2 = (String) props.get("year");
- if (((yearv2==null) || (yearv2.length()==0)) && (yearv1 != null)) props.put("date",yearv1);
- String commentv1 = chopSubstring(tag, start, start += 28);
- String commentv2 = (String) props.get("comment");
- if (((commentv2==null) || (commentv2.length()==0)) && (commentv1 != null)) props.put("comment",commentv1);
- String trackv1 = ""+((int) (frames[126] & 0xff));
- String trackv2 = (String) props.get("mp3.id3tag.track");
- if (((trackv2==null) || (trackv2.length()==0)) && (trackv1 != null)) props.put("mp3.id3tag.track",trackv1);
-
- int genrev1 = (int) (frames[127] & 0xff);
- if ((genrev1 >=0) && (genrev1<id3v1genres.length))
- {
- String genrev2 = (String) props.get("mp3.id3tag.genre");
- if (((genrev2==null) || (genrev2.length()==0))) props.put("mp3.id3tag.genre",id3v1genres[genrev1]);
- }
- if (TDebug.TraceAudioFileReader) TDebug.out("ID3v1 parsed");
- }
-
- /**
- * Extract
- * @param s
- * @param start
- * @param end
- * @return
- */
- private String chopSubstring(String s, int start, int end)
- {
- String str = null;
- // 11/28/04 - String encoding bug fix.
- try
- {
- str = s.substring(start, end);
- int loc = str.indexOf('\0');
- if (loc != -1) str = str.substring(0, loc);
- }
- catch (StringIndexOutOfBoundsException e)
- {
- // Skip encoding issues.
- if (TDebug.TraceAudioFileReader) TDebug.out("Cannot chopSubString "+e.getMessage());
- }
- return str;
- }
- /**
- * Parse ID3v2 frames to add album (TALB), title (TIT2), date (TYER), author (TPE1), copyright (TCOP), comment (COMM) ...
- * @param frames
- * @param props
- */
- protected void parseID3v2Frames(InputStream frames, HashMap props)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("Parsing ID3v2");
- byte[] bframes = null;
- int size = -1;
- try
- {
- size = frames.available();
- bframes = new byte[size];
- frames.mark(size);
- frames.read(bframes);
- frames.reset();
- }
- catch (IOException e)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("Cannot parse ID3v2 :"+e.getMessage());
- }
-
- try
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("ID3v2 frame dump='"+new String(bframes,0,bframes.length)+"'");
- /* ID3 tags : http://www.unixgods.org/~tilo/ID3/docs/ID3_comparison.html */
- String value = null;
- for (int i=0;i<bframes.length-4;i++)
- {
- String code = new String(bframes,i,4);
- String scode = new String(bframes,i,3);
- // ID3v2.3 & v2.4
- if ((code.equals("TALB")) || (code.equals("TIT2")) || (code.equals("TYER")) || (code.equals("TPE1")) || (code.equals("TCOP")) || (code.equals("COMM")) || (code.equals("TCON")) || (code.equals("TRCK")) || (code.equals("TPOS")) || (code.equals("TDRC")) || (code.equals("TCOM")) || (code.equals("TIT1")) || (code.equals("TENC")))
- {
- i=i+10;
- size = (int) (bframes[i-6] << 24) + (bframes[i-5] << 16) + (bframes[i-4] << 8) + (bframes[i-3]);
- if (code.equals("COMM")) value = parseText(bframes, i, size, 5);
- else value = parseText(bframes,i, size, 1);
- if ((value != null) && (value.length()>0))
- {
- if (code.equals("TALB")) props.put("album",value);
- else if (code.equals("TIT2")) props.put("title",value);
- else if (code.equals("TYER")) props.put("date",value);
- // ID3v2.4 date fix.
- else if (code.equals("TDRC")) props.put("date",value);
- else if (code.equals("TPE1")) props.put("author",value);
- else if (code.equals("TCOP")) props.put("copyright",value);
- else if (code.equals("COMM")) props.put("comment",value);
- else if (code.equals("TCON")) props.put("mp3.id3tag.genre",value);
- else if (code.equals("TRCK")) props.put("mp3.id3tag.track",value);
- else if (code.equals("TPOS")) props.put("mp3.id3tag.disc",value);
- else if (code.equals("TCOM")) props.put("mp3.id3tag.composer",value);
- else if (code.equals("TIT1")) props.put("mp3.id3tag.grouping",value);
- else if (code.equals("TENC")) props.put("mp3.id3tag.encoded",value);
- }
- i=i+size-1;
- }
- // ID3v2.2.
- else if ((scode.equals("TAL")) || (scode.equals("TT2")) || (scode.equals("TP1")) || (scode.equals("TYE")) || (scode.equals("TRK")) || (scode.equals("TPA")) || (scode.equals("TCR")) || (scode.equals("TCO")) || (scode.equals("TCM")) || (scode.equals("COM")) || (scode.equals("TT1")) || (scode.equals("TEN")))
- {
- i=i+6;
- size = (int) (0x00000000) + (bframes[i-3] << 16) + (bframes[i-2] << 8) + (bframes[i-1]);
- if (scode.equals("COM")) value = parseText(bframes, i, size, 5);
- else value = parseText(bframes,i, size, 1);
- if ((value != null) && (value.length()>0))
- {
- if (scode.equals("TAL")) props.put("album",value);
- else if (scode.equals("TT2")) props.put("title",value);
- else if (scode.equals("TYE")) props.put("date",value);
- else if (scode.equals("TP1")) props.put("author",value);
- else if (scode.equals("TCR")) props.put("copyright",value);
- else if (scode.equals("COM")) props.put("comment",value);
- else if (scode.equals("TCO")) props.put("mp3.id3tag.genre",value);
- else if (scode.equals("TRK")) props.put("mp3.id3tag.track",value);
- else if (scode.equals("TPA")) props.put("mp3.id3tag.disc",value);
- else if (scode.equals("TCM")) props.put("mp3.id3tag.composer",value);
- else if (scode.equals("TT1")) props.put("mp3.id3tag.grouping",value);
- else if (scode.equals("TEN")) props.put("mp3.id3tag.encoded",value);
- }
- i=i+size-1;
- }
- else if (code.startsWith("ID3"))
- {
- // ID3v2 Header.
- int v2version = (int) (bframes[3] & 0xFF);
- props.put("mp3.id3tag.v2.version",String.valueOf(v2version));
- i=i+4;
- }
- }
- }
- catch (RuntimeException e)
- {
- // Ignore all parsing errors.
- if (TDebug.TraceAudioFileReader) TDebug.out("Cannot parse ID3v2 :"+e.getMessage());
- }
- if (TDebug.TraceAudioFileReader) TDebug.out("ID3v2 parsed");
- }
-
- /**
- * Parse Text Frames.
- * @param bframes
- * @param offset
- * @param size
- * @param skip
- * @return
- */
- protected String parseText(byte[] bframes, int offset, int size, int skip)
- {
- String value = null;
- try
- {
- String[] ENC_TYPES = {"ISO-8859-1", "UTF16","UTF-16BE", "UTF-8"};
- value = new String(bframes,offset+skip,size-skip,ENC_TYPES[bframes[offset]]);
- value = chopSubstring(value,0,value.length());
- }
- catch (UnsupportedEncodingException e)
- {
- if (TDebug.TraceAudioFileReader) TDebug.out("ID3v2 Encoding error :"+e.getMessage());
- }
- return value;
- }
-
- /**
- * Load shoutcast (ICY) info.
- * @param input
- * @param props
- * @throws IOException
- */
- protected void loadShoutcastInfo(InputStream input, HashMap props) throws IOException
- {
- IcyInputStream icy = new IcyInputStream(new BufferedInputStream(input));
- HashMap metadata = icy.getTagHash();
- MP3Tag titleMP3Tag = icy.getTag("icy-name");
- if (titleMP3Tag != null) props.put("title",((String) titleMP3Tag.getValue()).trim());
- MP3Tag[] meta = icy.getTags();
- if (meta != null)
- {
- StringBuffer metaStr = new StringBuffer();
- for (int i=0;i<meta.length;i++)
- {
- String key = meta[i].getName();
- String value = ((String) icy.getTag(key).getValue()).trim();
- props.put("mp3.shoutcast.metadata."+key, value);
- }
- }
- }
-
-} \ No newline at end of file