Jlayer獲取mp3時長錯誤修改
阿新 • • 發佈:2018-12-26
背景
最近使用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!