1. 程式人生 > >Jlayer獲取mp3時長錯誤修改

Jlayer獲取mp3時長錯誤修改

背景

最近使用java來獲取音樂的基本資訊,從網上找了一些支援包,可能是比較老的原因,mp3包讀取總是失敗,所幸http://www.javazoom.net/mp3spi/mp3spi.html 提供的包中是有原始碼的,我所遇到的問題是通過輸入流來獲取音訊時長總是獲取不到。跟蹤程式碼MpegAudioFileReader 的getAudioFileFormat(InputStream inputStream, long mediaLength) 方法,發現

  if (mLength != AudioSystem.NOT_SPECIFIED)
            {
                nTotalMS = Math.round(m_header.total_ms(tmpLength));
                aff_properties.put("duration", new Long((long) nTotalMS * 1000L));
            }

duration (時長)的獲取首先判斷mLength是否賦值,而這個mLength的值來自mediaLength

int mLength = (int) mediaLength;

mediaLength 即檔案的長度,因我之前呼叫的AudioSytem獲取reader再調getAudioFileFormat(InputStream inputStream),而這個過程最後呼叫的是MpegAudioFileReader父類TAudioFileReader的getAudioFileFormat(InputStream inputStream),這個方法

long    lFileLengthInBytes = AudioSystem.NOT_SPECIFIED;
        if (!inputStream.markSupported()) {
            inputStream = new BufferedInputStream(inputStream, getMarkLimit());
        }
        inputStream.mark(getMarkLimit());
        AudioFileFormat audioFileFormat = null;
        try
        {
            audioFileFormat = getAudioFileFormat(inputStream, lFileLengthInBytes);
        }

呼叫子類MpegAudioFileReader getAudioFileFormat時確實沒有指定檔案長度,於是我將呼叫修改一下,之間來調MpegAudioFileReader,但是還是報錯,根據錯誤原因找到程式碼

        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);
            }
        }

如果指定長度例項化FileInputStream fis = (FileInputStream) inputStream; 但是fis什麼也沒幹,註釋掉,程式碼執行OK!