MP3文件的ID3v1信息储存的结构可以参考http://www.cnblogs.com/ycoe/archive/2006/08/14/476759.html
本类是自己写的一个操作MP3文件ID3v1信息的类
package com.xu.obj;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import com.xu.exception.MusicInfoOptException;
public class ID3v1Info {
final public static int LENGTH = 128;
private byte[] TAG = new byte[] { 'T', 'A', 'G' };
final public static String ENCODE = "GB2312";
final public static int TITLE_START = 3;
final public static int TITLE_LENGTH = 30;
final public static int ARTIST_START = 33;
final public static int ARTIST_LENGTH = 30;
final public static int ALBUM_START = 63;
final public static int ALBUM_LENGTH = 30;
final public static int YEAR_START = 93;
final public static int YEAR_LENGTH = 4;
final public static int COMMENTS_START = 97;
final public static int COMMENTS_LENGTH_28 = 28;
final public static int COMMENTS_LENGTH_30 = 30;
final public static int RESERVED = 125;
final public static int TRACK = 126;
final public static int GENRE = 127;
private File file = null;
private String title = "";
private String artist = "";
private String album = "";
private String year = "";
private String comment = "";
private String track = "";
private String genre = "";
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public File getFile() {
return file;
}
public void setFile(File file) throws MusicInfoOptException{
if ("mp3".endsWith(file.getName().toLowerCase())) {
throw new MusicInfoOptException("不是MP3文件!");
}
this.file = file;
this.getMusicInfo();
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
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 byte[] getTAG() {
return TAG;
}
public void setTAG(byte[] tag) {
TAG = tag;
}
public String getTrack() {
return track;
}
public void setTrack(String track) {
this.track = track;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public ID3v1Info(File file) throws MusicInfoOptException {
if ("mp3".endsWith(file.getName().toLowerCase()))
throw new MusicInfoOptException("不是MP3文件!");
this.file = file;
this.getMusicInfo();
}
/**
* 从音乐文件里取得3v1版本的音乐信息
*
* @throws MusicInfoOptException
*/
private void getMusicInfo() throws MusicInfoOptException {
byte[] buf = new byte[LENGTH];
RandomAccessFile raf;
try {
raf = new RandomAccessFile(this.file, "r");
} catch (FileNotFoundException e) {
throw new MusicInfoOptException("没有此文件!");
}
try {
raf.seek(raf.length() - LENGTH);
raf.readFully(buf);
raf.read(buf);
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
try {
if (!"TAG".equals(new String(buf, 0, 3, ENCODE)))
throw new MusicInfoOptException("音乐文件中不包含3v1版本信息!");
this.setAlbum(new String(buf, ALBUM_START, ALBUM_LENGTH, ENCODE)
.trim());
this.setComment(new String(buf, COMMENTS_START, COMMENTS_LENGTH_28,
ENCODE).trim());
this.setGenre(new String(buf, GENRE, 1, ENCODE).trim());
this.setTitle(new String(buf, TITLE_START, TITLE_LENGTH, ENCODE)
.trim());
this.setArtist(new String(buf, ARTIST_START, ARTIST_LENGTH, ENCODE)
.trim());
this.setTrack(new String(buf, TRACK, 1, ENCODE).trim());
this.setYear(new String(buf, YEAR_START, YEAR_LENGTH, ENCODE)
.trim());
} catch (UnsupportedEncodingException e) {
throw new MusicInfoOptException(e.getMessage());
}
try {
raf.close();
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
}
/**
* 将3v1信息保存进音乐文件中
*
* @throws MusicInfoOptException
*
* @throws Exception
*/
public void save(MusicInfo musicInfo) throws MusicInfoOptException {
this.setAlbum(musicInfo.getAlbum());
this.setArtist(musicInfo.getArtist());
this.setComment(musicInfo.getComment());
this.setGenre(musicInfo.getGenre());
this.setTitle(musicInfo.getTitle());
this.setTrack(musicInfo.getTrack());
this.setYear(musicInfo.getYear());
RandomAccessFile raf = null;
byte[] buf = new byte[LENGTH];
try {
raf = new RandomAccessFile(this.file, "rwd");
} catch (FileNotFoundException e) {
throw new MusicInfoOptException(e.getMessage());
}
try {
raf.seek(raf.length() - LENGTH);
// raf.readFully(buf);
raf.read(buf);
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
boolean have3v1 = true;// 是否有3v1信息
try {
if (!"TAG".equals(new String(buf, 0, 3, ENCODE))) {
// 如果没有3v1信息
buf = new byte[LENGTH];
buf[0] = 'T';
buf[1] = 'A';
buf[2] = 'G';
have3v1 = false;
}
} catch (UnsupportedEncodingException e) {
throw new MusicInfoOptException(e.getMessage());
}
// 将信息填充到buf中去
int count = 0;// 写入字符长度
// 写入歌手名
count = artist.getBytes().length;
if (count > ARTIST_LENGTH)
count = ARTIST_LENGTH;
for (int ii = 0; ii < count; ++ii) {
buf[ARTIST_START + ii] = artist.getBytes()[ii];
}
// 写入歌曲名
count = title.getBytes().length;
if (count > TITLE_LENGTH)
count = TITLE_LENGTH;
for (int ii = 0; ii < count; ++ii) {
buf[TITLE_START + ii] = title.getBytes()[ii];
}
// 写入专辑信息
count = album.getBytes().length;
for (int ii = 0; ii < count; ++ii) {
buf[ALBUM_START + ii] = album.getBytes()[ii];
}
// 写入备注
count = comment.getBytes().length;
for (int ii = 0; ii < count; ++ii) {
buf[COMMENTS_START + ii] = comment.getBytes()[ii];
}
// 写入年代信息
count = year.getBytes().length;
for (int ii = 0; ii < count; ++ii) {
buf[YEAR_START + ii] = year.getBytes()[ii];
}
// 写入轨道信息
buf[TRACK] = (byte) Integer.parseInt(track);
// 写入风格
buf[GENRE] = (byte) Integer.parseInt(genre);
// 写入音乐文件
try {
if (have3v1) {
raf.write(buf, 0, LENGTH);
} else {
raf.seek(raf.length());
raf.write(buf);
}
raf.close();
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
}
// ==============测试程序=================
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
File file = new File("c:/01.mp3");
ID3v1Info mp = new ID3v1Info(file);
System.out.println(mp.getArtist());
}
}
ID3v1Info类提供了ID3v1信息的修改与获取的方法,而MusicInfoOptException类则只是简单地继承了Exception类import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import com.xu.exception.MusicInfoOptException;
public class ID3v1Info {
final public static int LENGTH = 128;
private byte[] TAG = new byte[] { 'T', 'A', 'G' };
final public static String ENCODE = "GB2312";
final public static int TITLE_START = 3;
final public static int TITLE_LENGTH = 30;
final public static int ARTIST_START = 33;
final public static int ARTIST_LENGTH = 30;
final public static int ALBUM_START = 63;
final public static int ALBUM_LENGTH = 30;
final public static int YEAR_START = 93;
final public static int YEAR_LENGTH = 4;
final public static int COMMENTS_START = 97;
final public static int COMMENTS_LENGTH_28 = 28;
final public static int COMMENTS_LENGTH_30 = 30;
final public static int RESERVED = 125;
final public static int TRACK = 126;
final public static int GENRE = 127;
private File file = null;
private String title = "";
private String artist = "";
private String album = "";
private String year = "";
private String comment = "";
private String track = "";
private String genre = "";
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public File getFile() {
return file;
}
public void setFile(File file) throws MusicInfoOptException{
if ("mp3".endsWith(file.getName().toLowerCase())) {
throw new MusicInfoOptException("不是MP3文件!");
}
this.file = file;
this.getMusicInfo();
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
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 byte[] getTAG() {
return TAG;
}
public void setTAG(byte[] tag) {
TAG = tag;
}
public String getTrack() {
return track;
}
public void setTrack(String track) {
this.track = track;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public ID3v1Info(File file) throws MusicInfoOptException {
if ("mp3".endsWith(file.getName().toLowerCase()))
throw new MusicInfoOptException("不是MP3文件!");
this.file = file;
this.getMusicInfo();
}
/**
* 从音乐文件里取得3v1版本的音乐信息
*
* @throws MusicInfoOptException
*/
private void getMusicInfo() throws MusicInfoOptException {
byte[] buf = new byte[LENGTH];
RandomAccessFile raf;
try {
raf = new RandomAccessFile(this.file, "r");
} catch (FileNotFoundException e) {
throw new MusicInfoOptException("没有此文件!");
}
try {
raf.seek(raf.length() - LENGTH);
raf.readFully(buf);
raf.read(buf);
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
try {
if (!"TAG".equals(new String(buf, 0, 3, ENCODE)))
throw new MusicInfoOptException("音乐文件中不包含3v1版本信息!");
this.setAlbum(new String(buf, ALBUM_START, ALBUM_LENGTH, ENCODE)
.trim());
this.setComment(new String(buf, COMMENTS_START, COMMENTS_LENGTH_28,
ENCODE).trim());
this.setGenre(new String(buf, GENRE, 1, ENCODE).trim());
this.setTitle(new String(buf, TITLE_START, TITLE_LENGTH, ENCODE)
.trim());
this.setArtist(new String(buf, ARTIST_START, ARTIST_LENGTH, ENCODE)
.trim());
this.setTrack(new String(buf, TRACK, 1, ENCODE).trim());
this.setYear(new String(buf, YEAR_START, YEAR_LENGTH, ENCODE)
.trim());
} catch (UnsupportedEncodingException e) {
throw new MusicInfoOptException(e.getMessage());
}
try {
raf.close();
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
}
/**
* 将3v1信息保存进音乐文件中
*
* @throws MusicInfoOptException
*
* @throws Exception
*/
public void save(MusicInfo musicInfo) throws MusicInfoOptException {
this.setAlbum(musicInfo.getAlbum());
this.setArtist(musicInfo.getArtist());
this.setComment(musicInfo.getComment());
this.setGenre(musicInfo.getGenre());
this.setTitle(musicInfo.getTitle());
this.setTrack(musicInfo.getTrack());
this.setYear(musicInfo.getYear());
RandomAccessFile raf = null;
byte[] buf = new byte[LENGTH];
try {
raf = new RandomAccessFile(this.file, "rwd");
} catch (FileNotFoundException e) {
throw new MusicInfoOptException(e.getMessage());
}
try {
raf.seek(raf.length() - LENGTH);
// raf.readFully(buf);
raf.read(buf);
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
boolean have3v1 = true;// 是否有3v1信息
try {
if (!"TAG".equals(new String(buf, 0, 3, ENCODE))) {
// 如果没有3v1信息
buf = new byte[LENGTH];
buf[0] = 'T';
buf[1] = 'A';
buf[2] = 'G';
have3v1 = false;
}
} catch (UnsupportedEncodingException e) {
throw new MusicInfoOptException(e.getMessage());
}
// 将信息填充到buf中去
int count = 0;// 写入字符长度
// 写入歌手名
count = artist.getBytes().length;
if (count > ARTIST_LENGTH)
count = ARTIST_LENGTH;
for (int ii = 0; ii < count; ++ii) {
buf[ARTIST_START + ii] = artist.getBytes()[ii];
}
// 写入歌曲名
count = title.getBytes().length;
if (count > TITLE_LENGTH)
count = TITLE_LENGTH;
for (int ii = 0; ii < count; ++ii) {
buf[TITLE_START + ii] = title.getBytes()[ii];
}
// 写入专辑信息
count = album.getBytes().length;
for (int ii = 0; ii < count; ++ii) {
buf[ALBUM_START + ii] = album.getBytes()[ii];
}
// 写入备注
count = comment.getBytes().length;
for (int ii = 0; ii < count; ++ii) {
buf[COMMENTS_START + ii] = comment.getBytes()[ii];
}
// 写入年代信息
count = year.getBytes().length;
for (int ii = 0; ii < count; ++ii) {
buf[YEAR_START + ii] = year.getBytes()[ii];
}
// 写入轨道信息
buf[TRACK] = (byte) Integer.parseInt(track);
// 写入风格
buf[GENRE] = (byte) Integer.parseInt(genre);
// 写入音乐文件
try {
if (have3v1) {
raf.write(buf, 0, LENGTH);
} else {
raf.seek(raf.length());
raf.write(buf);
}
raf.close();
} catch (IOException e) {
throw new MusicInfoOptException(e.getMessage());
}
}
// ==============测试程序=================
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
File file = new File("c:/01.mp3");
ID3v1Info mp = new ID3v1Info(file);
System.out.println(mp.getArtist());
}
}
MusicInfo类是一个标准的JavaBean类,提供ID3v1中信息的属性的getter和setter方法