您的位置:首页 > 移动开发 > Android开发

android Mp3播放器之Mp3 ID3V2 、ID3V1标签解析

2011-08-27 16:21 405 查看
暑假在家学习Android,通过编写一个Mp3播放器学习MediaPalyer。在这里和大家分享一下代码。

1、ID3V2 标签解析

只解析些常见的。{歌名、艺术家、专辑、头像}

新建一个Id3v2Info类

package com.aws.mp3;

public class Id3v2Info {
// 歌名
private String tit2 = null;
// 艺术家
private String tpe1 = null;
// 专辑
private String talb = null;
// 头像
private byte[] apic = null;

public Id3v2Info(String tit2, String tpe1, String talb, byte[] apic) {
setTit2(tit2);
setTpe1(tpe1);
setTalb(talb);
setApic(apic);

}

public void setTit2(String tit2) {
this.tit2 = tit2;
}

public String getTit2() {
return tit2;
}

public void setTpe1(String tpe1) {
this.tpe1 = tpe1;
}

public String getTpe1() {
return tpe1;
}

public void setTalb(String talb) {
this.talb = talb;
}

public String getTalb() {
return talb;
}

public void setApic(byte[] apic) {
this.apic = apic;
}

public byte[] getApic() {
return apic;
}

}

再建立一个Mp3ReadId3v2类,用来提取Mp3中的信息。

package com.aws.mp3;

import java.io.IOException;
import java.io.InputStream;

/**
* <b>MP3的ID3V2信息解析类</b>
*
* @QQ QQ:951868171
* @version 1.0
* @email xi_yf_001@126.com
* */
public class Mp3ReadId3v2 {

private InputStream mp3ips;
public String charset = "GBK"; // 预设编码为GBK
private Id3v2Info info;

public Mp3ReadId3v2(InputStream in) {
this.mp3ips = in;
info = new Id3v2Info("未知", "未知", "未知", null);
}

public void readId3v2() throws Exception {
try {
readId3v2(1024*100);		//读取前100KB
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* */
public void readId3v2(int buffSize) throws Exception {
try {
if(buffSize > mp3ips.available()){
buffSize = mp3ips.available();
}
byte[] buff = new byte[buffSize];
mp3ips.read(buff, 0, buffSize);

if (ByteUtil.indexOf("ID3".getBytes(), buff, 1, 512) == -1)
throw new Exception("未发现ID3V2");
//获取头像
if (ByteUtil.indexOf("APIC".getBytes(), buff, 1, 512) != -1) {
int searLen = ByteUtil.indexOf(new byte[] { (byte) 0xFF,
(byte) 0xFB }, buff);
int imgStart = ByteUtil.indexOf(new byte[] { (byte) 0xFF,
(byte) 0xD8 }, buff);
int imgEnd = ByteUtil.lastIndexOf(new byte[] { (byte) 0xFF,
(byte) 0xD9 }, buff, 1, searLen) + 2;
byte[] imgb = ByteUtil.cutBytes(imgStart, imgEnd, buff);
info.setApic(imgb);
}
if (ByteUtil.indexOf("TIT2".getBytes(), buff, 1, 512) != -1) {
info.setTit2(new String(readInfo(buff, "TIT2"), charset));
System.out.println("info:" + info.getTit2());
}
if (ByteUtil.indexOf("TPE1".getBytes(), buff, 1, 512) != -1) {
info.setTpe1(new String(readInfo(buff, "TPE1"), charset));
System.out.println("info:" + info.getTpe1());

}
if (ByteUtil.indexOf("TALB".getBytes(), buff, 1, 512) != -1) {
info.setTalb(new String(readInfo(buff, "TALB"), charset));
System.out.println("info:" + info.getTalb());
}
} catch (IOException e) {
e.printStackTrace();
}finally{

mp3ips.close();
}

}

/**
*读取文本标签
**/
private byte[] readInfo(byte[] buff, String tag) {
int len = 0;
int offset = ByteUtil.indexOf(tag.getBytes(), buff);
len = buff[offset + 4] & 0xFF;
len = (len << 8) + (buff[offset + 5] & 0xFF);
len = (len << 8) + (buff[offset + 6] & 0xFF);
len = (len << 8) + (buff[offset + 7] & 0xFF);
len = len - 1;
return ByteUtil.cutBytes(ByteUtil.indexOf(tag.getBytes(), buff) + 11,
ByteUtil.indexOf(tag.getBytes(), buff) + 11 + len, buff);

}

public void setInfo(Id3v2Info info) {
this.info = info;
}

public Id3v2Info getInfo() {
return info;
}

public String getName() {
return getInfo().getTit2();

}

public String getAuthor() {

return getInfo().getTpe1();

}

public String getSpecial() {
return getInfo().getTalb();
}

public byte[] getImg() {
return getInfo().getApic();
}
}



Mp3ReadId3v2用到了很多字节查找,字节数组查找等,所以自己实现了个字节索引、操作类ByteUtil。(好像java里没有提供吧)

package com.aws.mp3;

/**
* 字节操作类
* */
public class ByteUtil {

/**
* 正向索引
* */
public static int indexOf(byte[] tag, byte[] src) {
return indexOf(tag, src, 1);
}

/**
* 获取第index个的位置<br />
* index从1开始
* */
public static int indexOf(byte[] tag, byte[] src, int index) {
return indexOf(tag, src, 1, src.length);
}

/**
* 获取第index个的位置<br />
* index从1开始
*
* */
public static int indexOf(byte[] tag, byte[] src, int index, int len) {
if (len > src.length) {
try {
throw new Exception("大于总个数");
} catch (Exception e) {
e.printStackTrace();
}
}
int size = 0;
int tagLen = tag.length;
byte[] tmp = new byte[tagLen];
for (int j = 0; j < len - tagLen + 1; j++) {
for (int i = 0; i < tagLen; i++) {
tmp[i] = src[j + i];
}
// 判断是否相等
for (int i = 0; i < tagLen; i++) {
if (tmp[i] != tag[i])
break;
if (i == tagLen - 1) {
size++;
return j;
}
}

}
return -1;
}

/**
* 倒序索引<br />
*
* */
public static int lastIndexOf(byte[] tag, byte[] src) {

return lastIndexOf(tag, src, 1);
}

/**
* 倒序获取第index个的位置<br />
* index从1开始
* */
public static int lastIndexOf(byte[] tag, byte[] src, int index) {
return lastIndexOf(tag, src, src.length);
}

/**
* 倒序获取第index个的位置<br />
* index从1开始
* */
public static int lastIndexOf(byte[] tag, byte[] src, int index, int len) {
if (len > src.length) {
try {
throw new Exception("大于总个数");
} catch (Exception e) {
e.printStackTrace();
}
}
int size = 0;
int tagLen = tag.length;
byte[] tmp = new byte[tagLen];
for (int j = len - tagLen; j >= 0; j--) {
for (int i = 0; i < tagLen; i++) {
tmp[i] = src[j + i];

}
for (int i = 0; i < tagLen; i++) {
if (tmp[i] != tag[i])
break;
if (i == tagLen - 1) {
size++;
return j;
}
}

}
return -1;
}

/**
* 统计个数
* */
public static int size(byte[] tag, byte[] src) {
int size = 0;
int tagLen = tag.length;
int srcLen = src.length;
byte[] tmp = new byte[tagLen];
for (int j = 0; j < srcLen - tagLen + 1; j++) {
for (int i = 0; i < tagLen; i++) {
tmp[i] = src[j + i];
}
for (int i = 0; i < tagLen; i++) {
if (tmp[i] != tag[i])
break;
if (i == tagLen - 1) {
size++;
}
}
// 速度较慢
// if (Arrays.equals(tmp, tag)) {
// size++;
// }
}
return size;
}

/**
* 截取byte[]
* */
public static byte[] cutBytes(int start, int end, byte[] src) {
if (end <= start || start < 0 || end > src.length) {
try {
throw new Exception("参数错误");
} catch (Exception e) {
e.printStackTrace();
}
}
byte[] tmp = new byte[end - start];
for (int i = 0; i < end - start; i++) {
tmp[i] = src[start + i];
}
return tmp;
}

}




2、ID3V1 标签解析

v1标签解析比较简单,就是操作mp3后128个字节。懒得贴代码。

3、资源下载地址

播放器源码下载http://download.csdn.net/source/3553639
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: