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

http://blog.csdn.net/toni001/article/details/6724785


暑假在家学习Android,通过编写一个Mp3播放器学习MediaPalyer。在这里和大家分享一下代码。

1、ID3V2 标签解析

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

新建一个Id3v2Info类

  1. package com.aws.mp3;  
  2.   
  3.   
  4. public class Id3v2Info {  
  5.     // 歌名  
  6.     private String tit2 = null;  
  7.     // 艺术家  
  8.     private String tpe1 = null;  
  9.     // 专辑  
  10.     private String talb = null;  
  11.     // 头像  
  12.     private byte[] apic = null;  
  13.   
  14.     public Id3v2Info(String tit2, String tpe1, String talb, byte[] apic) {  
  15.         setTit2(tit2);  
  16.         setTpe1(tpe1);  
  17.         setTalb(talb);  
  18.         setApic(apic);  
  19.   
  20.     }  
  21.   
  22.     public void setTit2(String tit2) {  
  23.         this.tit2 = tit2;  
  24.     }  
  25.   
  26.     public String getTit2() {  
  27.         return tit2;  
  28.     }  
  29.   
  30.     public void setTpe1(String tpe1) {  
  31.         this.tpe1 = tpe1;  
  32.     }  
  33.   
  34.     public String getTpe1() {  
  35.         return tpe1;  
  36.     }  
  37.   
  38.     public void setTalb(String talb) {  
  39.         this.talb = talb;  
  40.     }  
  41.   
  42.     public String getTalb() {  
  43.         return talb;  
  44.     }  
  45.   
  46.     public void setApic(byte[] apic) {  
  47.         this.apic = apic;  
  48.     }  
  49.   
  50.     public byte[] getApic() {  
  51.         return apic;  
  52.     }  
  53.   
  54. }  

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

  1. package com.aws.mp3;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5.   
  6. /** 
  7.  * <b>MP3的ID3V2信息解析类</b> 
  8.  *  
  9.  * @QQ QQ:951868171 
  10.  * @version 1.0 
  11.  * @email xi_yf_001@126.com 
  12.  * */  
  13. public class Mp3ReadId3v2 {  
  14.   
  15.     private InputStream mp3ips;  
  16.     public String charset = "GBK"// 预设编码为GBK  
  17.     private Id3v2Info info;  
  18.   
  19.     public Mp3ReadId3v2(InputStream in) {  
  20.         this.mp3ips = in;  
  21.         info = new Id3v2Info("未知""未知""未知"null);  
  22.     }  
  23.   
  24.     public void readId3v2() throws Exception {  
  25.         try {  
  26.             readId3v2(1024*100);        //读取前100KB  
  27.         } catch (IOException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.     }  
  31.     /** 
  32.      *  
  33.      * */  
  34.     public void readId3v2(int buffSize) throws Exception {  
  35.         try {  
  36.             if(buffSize > mp3ips.available()){  
  37.                 buffSize = mp3ips.available();  
  38.             }  
  39.             byte[] buff = new byte[buffSize];  
  40.             mp3ips.read(buff, 0, buffSize);  
  41.   
  42.             if (ByteUtil.indexOf("ID3".getBytes(), buff, 1512) == -1)  
  43.                 throw new Exception("未发现ID3V2");  
  44.             //获取头像  
  45.             if (ByteUtil.indexOf("APIC".getBytes(), buff, 1512) != -1) {  
  46.                 int searLen = ByteUtil.indexOf(new byte[] { (byte0xFF,  
  47.                         (byte0xFB }, buff);  
  48.                 int imgStart = ByteUtil.indexOf(new byte[] { (byte0xFF,  
  49.                         (byte0xD8 }, buff);  
  50.                 int imgEnd = ByteUtil.lastIndexOf(new byte[] { (byte0xFF,  
  51.                         (byte0xD9 }, buff, 1, searLen) + 2;  
  52.                 byte[] imgb = ByteUtil.cutBytes(imgStart, imgEnd, buff);  
  53.                 info.setApic(imgb);  
  54.             }  
  55.             if (ByteUtil.indexOf("TIT2".getBytes(), buff, 1512) != -1) {  
  56.                 info.setTit2(new String(readInfo(buff, "TIT2"), charset));  
  57.                 System.out.println("info:" + info.getTit2());  
  58.             }  
  59.             if (ByteUtil.indexOf("TPE1".getBytes(), buff, 1512) != -1) {  
  60.                 info.setTpe1(new String(readInfo(buff, "TPE1"), charset));  
  61.                 System.out.println("info:" + info.getTpe1());  
  62.   
  63.             }  
  64.             if (ByteUtil.indexOf("TALB".getBytes(), buff, 1512) != -1) {  
  65.                 info.setTalb(new String(readInfo(buff, "TALB"), charset));  
  66.                 System.out.println("info:" + info.getTalb());  
  67.             }  
  68.         } catch (IOException e) {  
  69.             e.printStackTrace();  
  70.         }finally{  
  71.               
  72.             mp3ips.close();  
  73.         }  
  74.   
  75.     }  
  76.   
  77.     /** 
  78.      *读取文本标签 
  79.      **/  
  80.     private byte[] readInfo(byte[] buff, String tag) {  
  81.         int len = 0;  
  82.         int offset = ByteUtil.indexOf(tag.getBytes(), buff);  
  83.         len = buff[offset + 4] & 0xFF;  
  84.         len = (len << 8) + (buff[offset + 5] & 0xFF);  
  85.         len = (len << 8) + (buff[offset + 6] & 0xFF);  
  86.         len = (len << 8) + (buff[offset + 7] & 0xFF);  
  87.         len = len - 1;  
  88.         return ByteUtil.cutBytes(ByteUtil.indexOf(tag.getBytes(), buff) + 11,  
  89.                 ByteUtil.indexOf(tag.getBytes(), buff) + 11 + len, buff);  
  90.   
  91.     }  
  92.   
  93.     public void setInfo(Id3v2Info info) {  
  94.         this.info = info;  
  95.     }  
  96.   
  97.     public Id3v2Info getInfo() {  
  98.         return info;  
  99.     }  
  100.   
  101.     public String getName() {  
  102.         return getInfo().getTit2();  
  103.   
  104.     }  
  105.   
  106.     public String getAuthor() {  
  107.   
  108.         return getInfo().getTpe1();  
  109.   
  110.     }  
  111.   
  112.     public String getSpecial() {  
  113.         return getInfo().getTalb();  
  114.     }  
  115.   
  116.     public byte[] getImg() {  
  117.         return getInfo().getApic();  
  118.     }  
  119. }  
Mp3ReadId3v2用到了很多字节查找,字节数组查找等,所以自己实现了个字节索引、操作类ByteUtil。(好像java里没有提供吧)
  1. package com.aws.mp3;  
  2.   
  3. /** 
  4.  * 字节操作类 
  5.  * */  
  6. public class ByteUtil {  
  7.   
  8.     /** 
  9.      * 正向索引 
  10.      * */  
  11.     public static int indexOf(byte[] tag, byte[] src) {  
  12.         return indexOf(tag, src, 1);  
  13.     }  
  14.   
  15.     /** 
  16.      * 获取第index个的位置<br /> 
  17.      * index从1开始 
  18.      * */  
  19.     public static int indexOf(byte[] tag, byte[] src, int index) {  
  20.         return indexOf(tag, src, 1, src.length);  
  21.     }  
  22.   
  23.     /** 
  24.      * 获取第index个的位置<br /> 
  25.      * index从1开始 
  26.      *  
  27.      * */  
  28.     public static int indexOf(byte[] tag, byte[] src, int index, int len) {  
  29.         if (len > src.length) {  
  30.             try {  
  31.                 throw new Exception("大于总个数");  
  32.             } catch (Exception e) {  
  33.                 e.printStackTrace();  
  34.             }  
  35.         }  
  36.         int size = 0;  
  37.         int tagLen = tag.length;  
  38.         byte[] tmp = new byte[tagLen];  
  39.         for (int j = 0; j < len - tagLen + 1; j++) {  
  40.             for (int i = 0; i < tagLen; i++) {  
  41.                 tmp[i] = src[j + i];  
  42.             }  
  43.             // 判断是否相等  
  44.             for (int i = 0; i < tagLen; i++) {  
  45.                 if (tmp[i] != tag[i])  
  46.                     break;  
  47.                 if (i == tagLen - 1) {  
  48.                     size++;  
  49.                     return j;  
  50.                 }  
  51.             }  
  52.   
  53.         }  
  54.         return -1;  
  55.     }  
  56.   
  57.     /** 
  58.      * 倒序索引<br /> 
  59.      *  
  60.      * */  
  61.     public static int lastIndexOf(byte[] tag, byte[] src) {  
  62.   
  63.         return lastIndexOf(tag, src, 1);  
  64.     }  
  65.   
  66.     /** 
  67.      * 倒序获取第index个的位置<br /> 
  68.      * index从1开始 
  69.      * */  
  70.     public static int lastIndexOf(byte[] tag, byte[] src, int index) {  
  71.         return lastIndexOf(tag, src, src.length);  
  72.     }  
  73.   
  74.     /** 
  75.      * 倒序获取第index个的位置<br /> 
  76.      * index从1开始 
  77.      * */  
  78.     public static int lastIndexOf(byte[] tag, byte[] src, int index, int len) {  
  79.         if (len > src.length) {  
  80.             try {  
  81.                 throw new Exception("大于总个数");  
  82.             } catch (Exception e) {  
  83.                 e.printStackTrace();  
  84.             }  
  85.         }  
  86.         int size = 0;  
  87.         int tagLen = tag.length;  
  88.         byte[] tmp = new byte[tagLen];  
  89.         for (int j = len - tagLen; j >= 0; j--) {  
  90.             for (int i = 0; i < tagLen; i++) {  
  91.                 tmp[i] = src[j + i];  
  92.   
  93.             }  
  94.             for (int i = 0; i < tagLen; i++) {  
  95.                 if (tmp[i] != tag[i])  
  96.                     break;  
  97.                 if (i == tagLen - 1) {  
  98.                     size++;  
  99.                     return j;  
  100.                 }  
  101.             }  
  102.   
  103.         }  
  104.         return -1;  
  105.     }  
  106.   
  107.     /** 
  108.      * 统计个数 
  109.      * */  
  110.     public static int size(byte[] tag, byte[] src) {  
  111.         int size = 0;  
  112.         int tagLen = tag.length;  
  113.         int srcLen = src.length;  
  114.         byte[] tmp = new byte[tagLen];  
  115.         for (int j = 0; j < srcLen - tagLen + 1; j++) {  
  116.             for (int i = 0; i < tagLen; i++) {  
  117.                 tmp[i] = src[j + i];  
  118.             }  
  119.             for (int i = 0; i < tagLen; i++) {  
  120.                 if (tmp[i] != tag[i])  
  121.                     break;  
  122.                 if (i == tagLen - 1) {  
  123.                     size++;  
  124.                 }  
  125.             }  
  126.             // 速度较慢  
  127.             // if (Arrays.equals(tmp, tag)) {  
  128.             // size++;  
  129.             // }  
  130.         }  
  131.         return size;  
  132.     }  
  133.   
  134.     /** 
  135.      * 截取byte[] 
  136.      * */  
  137.     public static byte[] cutBytes(int start, int end, byte[] src) {  
  138.         if (end <= start || start < 0 || end > src.length) {  
  139.             try {  
  140.                 throw new Exception("参数错误");  
  141.             } catch (Exception e) {  
  142.                 e.printStackTrace();  
  143.             }  
  144.         }  
  145.         byte[] tmp = new byte[end - start];  
  146.         for (int i = 0; i < end - start; i++) {  
  147.             tmp[i] = src[start + i];  
  148.         }  
  149.         return tmp;  
  150.     }  
  151.   
  152. }  


2、ID3V1 标签解析

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

3、资源下载地址

播放器源码下载http://download.csdn.net/source/3553639


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值