android,java獲取MP3文件信息(作者,專輯等)

接著上一篇文章, 上一篇把ndk開發(fā)遍歷手機文件分享了一下。遍歷出來的MP3文件,我需要展示在android的listview里面,想展示的好看一點,結果發(fā)現(xiàn)又是一個坑。

根據(jù)mp3文件,獲取作者啊專輯啊,不難,但是會出現(xiàn)各種亂碼,煩不勝煩。

1,先普及下這個的知識,MP3文件本身是沒有這些信息的,但是很顯然沒有信息,用戶體驗不行,所以在某某年(百度百科ID3)有人就加了一個ID3V1放在MP3文件的后面;再后來因為某某原因,有人把這個升級了,變成ID3V2放在了MP3的前面(當然ID3V1還在的)。所以現(xiàn)在有些文件是V1的,有些文件是V2的,在獲取信息之前要先判斷,是V1,還是V2, 當然還有一些MP3是兩個都不存在的,一般就是我們看到的未知。如下圖

獲取不到信息的情況

2,然后我們講一下網絡上面的資源

(1),https://sourceforge.net/projects/javamusictag/

這個地址是一個好資源,里面有jar工具包,也有源代碼;

(2),http://www.ulduzsoft.com/2012/07/parsing-id3v2-tags-in-the-mp3-files/

這里面是一個java文件,解析V2的,沒有解析V1。

以上兩個都是需要做修改的才能被我們使用,否則就是要么亂碼,要么不解析。

我們先說第一個資源吧:

(1),這個是比較全面的JAR,還可以寫信息到文件里面去,如果你使用這個jar的時候,獲取ID3V1出現(xiàn)亂碼了,你需要修改的是org.farng.mp3.id3.ID3v1_1或者org.farng.mp3.id3.ID3v1里面的read方法,默認里面是ISO-8859-1不是適合所有人的,比如我就改成了GBK。? ? ? ? ? 如果你使用這個jar來獲取ID3V2,那么就需要對org.farng.mp3.object.AbstractMP3Object這個文件做修改,他里面的readByteArray(byte[] arr, int offset)這個方法解析我的音樂文件,都是亂碼(可能別人可以使用),具體改動是把里面的方法內容替換成以下:

String charset;

int charcode = arr[0];//獲取編碼標志?

if ( charcode == 0 ){

charset = "GBK";

}else if ( charcode == 3 ){

charset = "UTF-8";

}else{

charset = "UTF-16" ;

}

try {

String con = new String(arr, 1, arr.length - 1, charset);//編碼

//這以下都是為了解碼不錯而寫的,沒有依據(jù)

offset--;

if (offset >= con.length()) {

offset = con.length() - 1;

}

if (offset < 0) {

offset = 0;

}

if ((offset == 0) && (con.length() == 0)) {

con = " ";

}

//這以上都是為了解碼不錯而寫的,沒有依據(jù)

readString(con, offset);//jar里面 的方法

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

修改后以后,重新打包成jar,就可以使用這個新的jar了。

(2)如果你使用第二個網絡資源,這個資源只有一個java文件,也比較簡單,只是解析了V2.如果我們需要全面一點,讓他也可以解析V1,就需要對他做改動

這個文件里面有一個parse方法,這個方法里面有一段如下:

if( headerbuf[0] !='I'|| headerbuf[1] !='D'|| headerbuf[2] !='3'){

? ? ? ?file.close();

? ? ? ?returnfalse;

}

這一段是為了判斷是不是V2(如果是V2的話,開頭三個字符應該是ID3,另,V1部分開頭三個字符是TAG),從上面的代碼可以看出,如果不是V2,就直接結束了,而我們想要的是,如果不是V2,我們就再去試試,是不是V1,如果也不是V1,那么我們只好把作者啊專輯啊,都寫成未知了。所以,我們在file.close();前面加一個方法getID3V1(file);

方法內容如下(從網上拷貝的):

private void getID3V1(RandomAccessFile file) {

byte[] buf = new byte[128];// 初始化標簽信息的byte數(shù)組

try {

file.seek(file.length() - 128);// 移動到文件MP3末尾

file.read(buf);// 讀取標簽信息

file.close();// 關閉文件

} catch (FileNotFoundException e) {

e.printStackTrace();

}// 隨機讀寫方式打開MP3文件

catch (IOException e) {

e.printStackTrace();

}

if (buf.length != 128) {// 數(shù)據(jù)長度是否合法

try {

throw new Exception("MP3標簽信息數(shù)據(jù)長度不合法!");

} catch (Exception e) {

e.printStackTrace();

}

}

String tag = "";

try {

tag = new String(buf, 0, 3, "gbk");

} catch (UnsupportedEncodingException e1) {

e1.printStackTrace();

}

if (!"TAG".equalsIgnoreCase(tag)) {// 標簽頭是否存在

try {

throw new Exception("MP3標簽信息數(shù)據(jù)格式不正確!");

} catch (Exception e) {

e.printStackTrace();

}

}

try {

m_title = new String(buf, 3, 30, "gbk").trim();

m_artist = new String(buf, 33, 30, "gbk").trim();// 歌手名字

m_floder = new String(buf, 63, 30, "gbk").trim();// 專輯名稱

m_tyer = new String(buf, 93, 4, "gbk").trim();// 出品年份

m_comm = new String(buf, 97, 28, "gbk").trim();// 備注信息

System.out.println("作者:" + m_artist);

System.out.println("標題:" + m_title);

System.out.println("專集:" + m_floder);

System.out.println("音軌:" + m_trck);

System.out.println("年代:" + m_tyer);

System.out.println("類型:" + m_tcon);

System.out.println("備注1:" + m_comm);

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

}

當然從我貼的代碼可以看到,我又使用了GBK編碼,這個資源2里面的有一個方法parseTextField里面也有ISO-8859-1,在我這邊,我也改成了GBK,然后可以使用。

總結下,網絡上面的資源其實很多,但是很亂,比如我們想要找一個可以解決編碼問題的資源,你不會那么巧,剛剛好就找到了你想要的,你需要有耐心,慢慢找,一個個的測試,最后你覺得最靠譜的方法,你再去不斷的調試,不斷的修改。最終肯定能把資源變成適合你的資源。

本文和上一篇文章使用的是一個項目

地址:http://download.csdn.net/detail/xiaodousa/9618128

其實這次經歷中有很多不明白的地方,比如,int charcode = arr[0];//獲取編碼標志?

以及offset是否有什么依據(jù),望大神指教

以上

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • 一. Java基礎部分.................................................
    wy_sure閱讀 4,012評論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • 2017年5月17日 Kylin_Wu 標注(★☆)為考綱明確給出考點(必考) 常見手機系統(tǒng)(★☆) And...
    Azur_wxj閱讀 1,960評論 0 10
  • 今天在看一個開源項目的時候,發(fā)現(xiàn)作者使用一個ssdb的數(shù)據(jù)庫,第一反應是ssd硬盤,當時很詫異。后面了解后才知道,...
    若與閱讀 8,880評論 4 7

友情鏈接更多精彩內容