Logo Search packages:      
Sourcecode: jclic version File versions  Download package

MpegAudioFileReader.java

/*
 * MpegAudioFileReader.
 * 
 * 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.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.
 */
00055 public class MpegAudioFileReader extends TAudioFileReader
{
      private final int       SYNC = 0xFFE00000;
      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()");
      }

      /**
       * Returns AudioFileFormat from File.
       */
00229       public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException
      {           
            return super.getAudioFileFormat(file);
      }
      
      /**
       * Returns AudioFileFormat from URL.
       */
00237       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.
       */
00261       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");
                  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");
                  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");
                  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");
                  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.
       */
00438       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.
       */
00461       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.
       */
00526       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
       */
00538       protected void parseID3v1Frames(byte[] frames, HashMap props)
      {
            String tag = new String(frames, 0, frames.length); 
            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("year",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]);   
            }           
      }
      
      private String chopSubstring(String s, int start, int end) 
      {
            String str = s.substring(start, end);
            int loc = str.indexOf('\0');        
            if (loc != -1) str = str.substring(0, loc);
            return str;
      }
      /**
       * Parse ID3v2 frames to add album (TALB), title (TIT2), date (TYER), author (TPE1), copyright (TCOP), comment (COMM).
       * @param frames
       * @param props
       */
00581       protected void parseID3v2Frames(InputStream frames, HashMap props)
      {
            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
            {
                  String value = null;
                  for (int i=0;i<bframes.length-4;i++)
                  {
                        String code = new String(bframes,i,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")))
                        {
                              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);
                                    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);
                              } 
                              i=i+size-1;
                        }
                  }
            }
            catch (RuntimeException e)
            {
                  // Ignore all parsing errors.
                  if (TDebug.TraceAudioFileReader) TDebug.out("Cannot parse ID3v2 :"+e.getMessage());
            }
      }

      /**
       * Parse Text Frames.
       * @param bframes
       * @param offset
       * @param size
       * @param skip
       * @return
       */
00640       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]]);                   
            }
            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
       */
00661       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);                              
              }
        }
      }
      
}

Generated by  Doxygen 1.6.0   Back to index