Android/Java 讀、寫MP3檔案ID3V1資訊
阿新 • • 發佈:2018-12-07
MP3的歌曲資訊一般分兩個大版本,分別是ID3V1和ID3V2,其中V2又分為好幾個版本,具體百度一下,下方的程式碼僅僅是支援ID3V1。
需要用到的一個輔助工具(juniversalchardet)用於解決亂碼問題,具體看部落格:https://my.oschina.net/u/1462828/blog/2877749
具體看程式碼:
/** * 獲取MP3檔案資訊 * * @param path MP3檔案物件 */ public static MusicInfoV1Entity getMusicInfoV1(String path) { if (path == null) { return null; } return getMusicInfoV1(new File(path)); } public static MusicInfoV1Entity getMusicInfoV1(File musicFile) { if (musicFile == null) { return null; } MusicInfoV1Entity v1Entity; try { RandomAccessFile randomAccessFile = new RandomAccessFile(musicFile, "r"); byte[] buffer = new byte[128]; randomAccessFile.seek(randomAccessFile.length() - 128); randomAccessFile.read(buffer); if (buffer.length == 128) { v1Entity = new MusicInfoV1Entity(); String tag = new String(buffer, 0, 3); UniversalDetector detector = new UniversalDetector(null); detector.handleData(buffer, 0, buffer.length); detector.dataEnd(); String charset = detector.getDetectedCharset(); detector.reset(); // 只有前三個位元組是TAG才處理後面的位元組 if (tag.equalsIgnoreCase("TAG")) { // 歌曲名 String songName = new String(buffer, 3, 30, charset).trim(); // 藝術家 String artist = new String(buffer, 33, 30, charset).trim(); // 所屬唱片 String album = new String(buffer, 63, 30, charset).trim(); // 發行年 String year = new String(buffer, 93, 4, charset).trim(); // 備註 String comment = new String(buffer, 97, 28, charset).trim(); v1Entity.setTitle(songName); v1Entity.setArtist(artist); v1Entity.setAlbum(album); v1Entity.setYear(year); v1Entity.setComment(comment); ALog.e("歌曲名:" + songName); ALog.e("藝術家:" + artist); ALog.e("所屬唱片:" + album); ALog.e("發行年:" + year); ALog.e("備註:" + comment); return v1Entity; } else { ALog.e("無效的歌曲資訊..."); return null; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 寫入mp3的ID3V1檔案資訊 * * @param path * @param v1Entity */ public static void setMusicInfoV1(String path, MusicInfoV1Entity v1Entity) { try { byte[] bufferAll = new byte[128]; byte[] buffTag; byte[] buffSoundName = new byte[30]; byte[] buffArtist = new byte[30]; byte[] buffAlbum = new byte[30]; byte[] buffYear = new byte[4]; byte[] buffComment = new byte[28]; byte[] buffFoot; buffTag = "TAG".getBytes(); byte[] cache; if (v1Entity.getTitle() != null) { cache = v1Entity.getTitle().getBytes("GBK"); System.arraycopy(cache, 0, buffSoundName, 0, cache.length); } if (v1Entity.getArtist() != null) { cache = v1Entity.getArtist().getBytes("GBK"); System.arraycopy(cache, 0, buffArtist, 0, cache.length); } if (v1Entity.getAlbum() != null) { try { cache = v1Entity.getAlbum().getBytes("GBK"); System.arraycopy(cache, 0, buffAlbum, 0, cache.length); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } if (v1Entity.getYear() != null) { cache = v1Entity.getYear().getBytes("GBK"); System.arraycopy(cache, 0, buffYear, 0, cache.length); } if (v1Entity.getComment() != null) { cache = v1Entity.getComment().getBytes("GBK"); int num = 28; if (cache.length <= num) { num = cache.length; } System.arraycopy(cache, 0, buffComment, 0, num); } buffFoot = "111".getBytes(); System.arraycopy(buffTag, 0, bufferAll, 0, 3); System.arraycopy(buffSoundName, 0, bufferAll, 3, 30); System.arraycopy(buffArtist, 0, bufferAll, 33, 30); System.arraycopy(buffAlbum, 0, bufferAll, 63, 30); System.arraycopy(buffYear, 0, bufferAll, 93, 4); System.arraycopy(buffComment, 0, bufferAll, 97, 28); System.arraycopy(buffFoot, 0, bufferAll, 125, 3); RandomAccessFile randomAccessFile = new RandomAccessFile(new File(path), "rw"); long len = randomAccessFile.length(); if (getMusicInfoV1(path) != null) { //有v1了,需要把後面的128刪掉 len = randomAccessFile.length() - 128; } randomAccessFile.seek(len); randomAccessFile.write(bufferAll, 0, bufferAll.length); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
附上實體類:
public class MusicInfoV1Entity { //歌曲名字 String title; // 藝術家 String artist; // 作曲家(ID3V1不支援這個欄位) String composer; // 所屬唱片 String album; // 發行年 String year; // 備註 String comment; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getComposer() { return composer; } public void setComposer(String composer) { this.composer = composer; } public String getAlbum() { return album; } public void setAlbum(String album) { this.album = album; } public String getYear() { return year; } public void setYear(String year) { this.year = year; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } }
當然,鑑於各種操作比較複雜,所以還是習慣性拿來主義,
推薦使用一個叫Jaudiotagger的jar包,支援mp3/m4a/wav/flac等格式的音訊資訊讀寫。
官網地址:http://www.jthink.net/jaudiotagger/index.jsp