android Mp3播放器之Mp3 ID3V2 、ID3V1标签解析
2011-08-27 16:21
405 查看
暑假在家学习Android,通过编写一个Mp3播放器学习MediaPalyer。在这里和大家分享一下代码。
新建一个Id3v2Info类
再建立一个Mp3ReadId3v2类,用来提取Mp3中的信息。
Mp3ReadId3v2用到了很多字节查找,字节数组查找等,所以自己实现了个字节索引、操作类ByteUtil。(好像java里没有提供吧)
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相关文章推荐
- android Mp3播放器之Mp3 ID3V2 、ID3V1标签解析
- mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息
- mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换
- MP3标签 ID3v1,ID3v2,APETAGEX
- android开发--mp3播放器项目源代码(xml文件解析,.lrc,.mp3文件下载,同时显示歌词)
- mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换等
- mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换(下)
- mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换(上)
- android webkit 网页标签的解析与预下载的实现
- Android TextView显示Html类解析的网页和图片及自定义标签用法示例
- MP3 ID3v2标签说明
- Android项目之旅三 简易Mp3播放器从获取服务器端Mp3信息
- Android学习札记10:用SAX解析XML文件时,当标签中出现换行符时可能出现读取内容为空的解决方法
- Android 获取服务器数据解析Text数据,存在htmel标签的处理办法
- 使用getID3向.mp3文件写入ID3v2 TXXX标签
- Android学习札记47:TextView显示Html类解析的网页和图片及自定义标签
- Android HTML.fromHtml解析图片标签
- MP3信息格式 ID3v1和ID3v2
- Mp3(ID3v2)格式文件解析
- Android 属性动画(Property Animation) 完全解析 (下) 标签: AndroidProperty Animation