闇�瑕乄MA鏍煎紡鐨凾AG淇℃伅锛屾暣鐞嗕簡涓�涓嬶紝鍦ㄨ繖閲屼笌澶у鍒嗕韩涓�涓嬨�傚弬鑰冭浆鑷細http://blog.csdn.net/werocpp/article/details/5594067銆�
棣栧厛浠嬬粛涓媁MA鏂囦欢澶寸殑缁撴瀯锛屽涓嬪浘
/*************************************************************************
// 鍒嗕负鏂囦欢澶村拰鍚勪釜甯ф暟鎹紙鏂囦欢澶村墠16涓瓧鑺俉MA鏍煎紡鏄浐瀹氱殑锛�8涓瓧鑺傜殑澶у皬鏄珮浣嶅瓨鍦ㄥ悗闈紝浠ュ悗閬囧埌澶у皬閮芥槸楂樹綅瀛樺湪鍚庨潰锛�
+--------------------------------------------------------------+
|聽聽聽聽聽 Header (30 bytes)聽聽 HeadFlag:16; HeadSize:8; Unknow:6聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 Frames (1....n)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
// 鎵�鏈夌殑TAG淇℃伅瀛樻斁鍦ㄦ爣鍑嗗抚鍜屾墿灞曞抚涓紝鍏朵粬甯у彲浠ヤ笉浜堣�冭檻锛屾爣鍑嗗抚浠ュ強鎵╁睍甯х殑16涓瓧鑺傛爣璇嗗ご閮芥槸鍥哄畾鐨�
// 鎵�鏈夌殑淇℃伅閮芥槸UNICODE缂栫爜
// 鏍囧噯甯х粨鏋�
+--------------------------------------------------------------+
|聽聽聽聽聽 Header (24 bytes)聽聽 HeadFlag:16; HeadSize:8;聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鏍囬淇℃伅澶у皬锛�2 bytes锛壜犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅� |
+--------------------------------------------------------------+
|聽聽聽聽聽 鑹烘湳瀹朵俊鎭ぇ灏忥紙2 bytes锛壜犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅� |
+--------------------------------------------------------------+
|聽聽聽聽聽 鐗堟潈淇℃伅澶у皬锛�2 bytes锛壜犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅� |
+--------------------------------------------------------------+
|聽聽聽聽聽 澶囨敞淇℃伅澶у皬锛�2 bytes锛壜犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅� |
+--------------------------------------------------------------+
|聽聽聽聽聽 鏈煡淇℃伅澶у皬锛�2 bytes锛壜犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅� |
+--------------------------------------------------------------+
|聽聽聽聽聽 鏍囬淇℃伅鍐呭(0x00 0x00缁撴潫)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鑹烘湳瀹朵俊鎭唴瀹�(0x00 0x00缁撴潫)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鐗堟潈淇℃伅鍐呭(0x00 0x00缁撴潫)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 澶囨敞淇℃伅鍐呭(0x00 0x00缁撴潫)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鏈煡淇℃伅鍐呭(0x00 0x00缁撴潫)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
// 鎵╁睍甯х粨鏋�
+--------------------------------------------------------------+
|聽聽聽聽聽 Header (24 bytes)聽聽 HeadFlag:16; HeadSize:8;聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鎵╁睍淇℃伅涓暟EXNO锛�2 bytes锛壜犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅犅� |
+--------------------------------------------------------------+
|聽聽聽聽聽 EXINFO (1....EXNO)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
// 姣忎釜鎵╁睍淇℃伅EXINFO缁撴瀯
+--------------------------------------------------------------+
|聽聽聽聽聽 EXINFO NAME Size (2 bytes)聽聽 鎵╁睍淇℃伅鍚嶅瓧澶у皬聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鎵╁睍淇℃伅鍚嶇О聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鏍囧織FLAG聽聽 (2 bytes)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 鍊肩殑澶у皬聽聽 (2 bytes)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
|聽聽聽聽聽 瀹為檯鐨勫�悸犅� (鑻ユ槸鍥剧墖鏍煎紡鍙傝�僆D3V2.3)聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 |
+--------------------------------------------------------------+
褰撴墿灞曚俊鎭悕瀛椾负WMFSDKVersion鏃讹紝杩欎釜鍊艰〃绀虹殑鏄繖涓猈MA鏂囦欢鐨勭増鏈紱
褰撴墿灞曚俊鎭悕瀛椾负WM/AlbumTitle鏃讹紝杩欎釜鍊间唬琛ㄧ殑灏辨槸涓撹緫鍚嶏紱
褰撴墿灞曚俊鎭悕瀛椾负WM/Genre鏃讹紝杩欎釜鍊间唬琛ㄧ殑灏辨槸娴佹淳锛�
涓嬮潰鍐嶆潵鐪嬬湅閭d釜鏍囧織Flag锛岃繖涓熀鏈笂鏄负娌′粈涔堢敤鐨勶紙閫氬父鍊间负0锛夛紝
瀵筗M/TrackNumber鍜學M/Track杩欎袱涓墿灞曚俊鎭悕瀛楁湁鐢紝
褰揊lag涓�3鐨勬椂鍊欏悗闈㈢殑鍊硷紙涔熷氨鏄洸鐩俊鎭級鏄互4涓瓧鑺傜殑鏁存暟鐨勫舰寮忚〃绀猴紝
褰揊lag涓�0鐨勬椂鍊欙紝鏇茬洰淇℃伅鏄互鏅�氱殑瀛楃涓插舰寮忚〃绀虹殑銆�
// 鏌ョ湅http://msdn.microsoft.com/en-us/library/ms867702.aspx
Java浠g爜锛�
public classWmaReadId3 {
private static finalStringTAG="id3";
private int[]header= {0x30,0x26,0xB2,0x75,0x8e,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,
0x6C};
private int[]WMA_STANDTAG= {0x33,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,
0xCE,0x6C};// 鏍囧噯甯�
private int[]WMA_EXTAG= {0x40,0xA4,0xD0,0xD2,0x07,0xE3,0xD2,0x11,0x97,0xF0,0x00,0xA0,0xC9,0x5E,
0xA8,0x50};// 鎵╁睍甯�
private int[]ALBUM= {0x57,0x00,0x4d,0x00,0x41,0x00,0x6c,0x00,0x62,0x00,0x75,0x00,0x6d,0x00,0x54,
0x00,0x69,0x00,0x74,0x00,0x6c,0x00,0x65,0x00};
private int[]YEAR= {0x57,0x00,0x4d,0x00,0x59,0x00,0x65,0x00,0x61,0x00,0x72,0x00};
private int[]APIC_TAG= {0x69,0x00,0x6D,0x00,0x61,0x00,0x67,0x00,0x65,0x00,0x2F,0x00,0x6A,0x00,0x70,
0x00,0x65,0x00,0x67,0x00,0x00,0x00,0x00,0x00};
privateInputStreammp3ips;
publicStringcharset="UTF-8";// 棰勮缂栫爜涓篏BK
privateId3v2Infoinfo;
publicWmaReadId3(InputStream inputStream) {
this.mp3ips= inputStream;
info=newId3v2Info();
}
publicId3v2InforeadId3() {
if(mp3ips!=null) {
try{
intreslen =mp3ips.available();// 鑾峰彇瀛楄妭鎬婚暱
mp3ips.skip(0);
byte[] wmadata =new byte[16];
mp3ips.read(wmadata);
booleanisWmaFile = compareArrays(wmadata,header);
if(!isWmaFile) {
returninfo;
}
byte[] hDataSize =new byte[8];
mp3ips.read(hDataSize);
intheadSize =0;
for(inti =0;i < hDataSize.length;i++) {
headSize |= (((int) hDataSize[i] &0xff) << (8* i));
}
mp3ips.skip(6);
intoffset =30;// 鍋忕Щ閲�
while(offset < headSize) {
byte[] tagHead =new byte[16];// 甯уご
mp3ips.read(tagHead);
offset += tagHead.length;
byte[] tagSize =new byte[8];// 甯ч暱搴�
mp3ips.read(tagSize);
offset += tagSize.length;
intframeSize =0;
for(inti =0;i < tagSize.length;i++) {
frameSize |= (((int) tagSize[i] &0xff) << (8* i));
}
if(compareArrays(tagHead,WMA_STANDTAG)) {// 鏄爣鍑嗗抚澶�
byte[] tmpbuf =new byte[10];
mp3ips.read(tmpbuf);
int[] Tagsize =new int[5];
for(inti =0;i <5;i++) {
Tagsize[i] = (((int) tmpbuf[i *2] &0xff) | ((int) tmpbuf[i *2+1] &0xff) <<8);
}
// read 5 tag.
for(inti =0;i <5;i++) {
if(Tagsize[i] >0) {
byte[] tempData =new byte[Tagsize[i]];
mp3ips.read(tempData);
offset += tempData.length;
switch(i) {
case0:// Title
String title = Byte2Unicode(tempData);
info.setTit2(title);
break;
case1:// Artist
String artist = Byte2Unicode(tempData);
info.setTpe1(artist);
break;
}
}
}
}else if(compareArrays(tagHead,WMA_EXTAG)) {// 鏄墿灞曞抚澶�
byte[] extSize =new byte[2];
mp3ips.read(extSize);
offset += extSize.length;
intexTagNum =0;
for(inti =0;i < extSize.length;i++) {
exTagNum |= (((int) extSize[i] &0xff) << (8* i));
}
for(inti =0;i < exTagNum;i++) {
byte[] size1Date =new byte[2];
mp3ips.read(size1Date);
offset += size1Date.length;
intsize1 =0;
for(intj =0;j < size1Date.length;j++) {
size1 |= (((int) size1Date[j] &0xff) << (8* j));
}
byte[] extTagName =new byte[size1];// 鎵╁睍淇℃伅鍚�
mp3ips.read(extTagName);
offset += extTagName.length;
String name =newString(removeZero(extTagName));//Byte2Unicode(extTagName);
byte[] flagData =new byte[2];
mp3ips.read(flagData);
offset += flagData.length;
intflag =0;
for(intj =0;j < flagData.length;j++) {
flag |= (((int) flagData[j] &0xff) << (8* j));
}
byte[] exValueSizeData =new byte[2];
mp3ips.read(exValueSizeData);
offset += exValueSizeData.length;
intexValueSize =0;
for(intj =0;j < exValueSizeData.length;j++) {
exValueSize |= (((int) exValueSizeData[j] &0xff) << (8* j));
}
if(flag !=3) {
byte[] exValueData =new byte[exValueSize];
mp3ips.read(exValueData);
offset += exValueData.length;
if("WM/AlbumTitle".equals(name)) {
String album = Byte2Unicode(exValueData);
info.setTalb(album);
}else if("WM/AlbumArtist".equals(name)) {
String artist = Byte2Unicode(exValueData);
info.setTpe1(artist);
}else if("WM/Picture".equals(name)) {// 涓撹緫鍥�
LogUtils.d(TAG,"----涓撹緫鍥�----");
byte[] apicTag =new byte[APIC_TAG.length];
System.arraycopy(exValueData,5,apicTag,0,apicTag.length);
if(compareArrays(apicTag,APIC_TAG)) {
byte[] imgData =new byte[exValueData.length-5- apicTag.length];
System.arraycopy(exValueData,5+ apicTag.length,imgData,0,imgData.length);
info.setApic(imgData);
}
}
}else{
mp3ips.skip(4);
offset +=4;
}
}
}else{
mp3ips.skip(frameSize -16-8);
offset += (frameSize -16-8);
}
}
}catch(IOException e) {
e.printStackTrace();
}
}
returninfo;
}
// for (int j = 0; j < extTagName.length; j++) {
// String temp = Integer.toHexString(extTagName[j] &
// 0xff);
// if (temp.length() == 1) {
// temp = "0" + temp;
// }
// LogUtils.d(TAG, "鎵╁睍淇℃伅鍚� extTagName[" + j + "]:" +
// temp);
// }
public voidsetInfo(Id3v2Info info) {
this.info= info;
}
publicId3v2InfogetInfo() {
returninfo;
}
publicStringgetName() {
returngetInfo().getTit2();
}
publicStringgetAuthor() {
returngetInfo().getTpe1();
}
publicStringgetSpecial() {
returngetInfo().getTalb();
}
public byte[]getImg() {
returngetInfo().getApic();
}
public booleancompareArrays(byte[] data1, int[] data2) {
if(data1.length== data2.length) {
for(inti =0;i < data2.length;i++) {
if((data1[i] &0xff) != (data2[i] &0xff)) {
return false;
}
}
return true;
}else{
return false;
}
}
public byte[]removeZero(byte[] a) {
intj =0;
// 杩欎釜for寰幆璁$畻鍑轰綘浼犲叆鐨勮繖涓暟缁勫幓鎺�0鍚庣殑闀垮害
for(inti =0;i < a.length;i++) {
if(a[i] !=0) {
j++;
}
}
// 瀹氫箟鏁扮粍鐨勯暱搴�
byte[] newarr =new byte[j];
j =0;
// 灏嗕笉涓洪浂鐨刢opy鍒版柊鏁扮粍涓幓
for(inti =0;i < a.length;i++) {
if(a[i] !=0) {
newarr[j] = a[i];
j++;
}
}
returnnewarr;
}
publicStringByte2Unicode(byteabyte[], intst, intbEnd)// 涓嶅寘鍚玝End
{
StringBuffer sb =newStringBuffer("");
for(intj = st;j < bEnd;) {
intlw = abyte[j++];
if(lw <0)
lw +=256;
inthi = abyte[j++];
if(hi <0)
hi +=256;
charc = (char) (lw + (hi <<8));
sb.append(c);
}
returnsb.toString();
}
publicStringByte2Unicode(byteabyte[], intlen) {
returnByte2Unicode(abyte,0,len);
}
publicStringByte2Unicode(byteabyte[]) {
returnByte2Unicode(abyte,0,abyte.length);
}
public byte[]Unicode2Byte(String s) {
intlen = s.length();
byteabyte[] =new byte[len <<1];
intj =0;
for(inti =0;i < len;i++) {
charc = s.charAt(i);
abyte[j++] = (byte) (c &0xff);
abyte[j++] = (byte) (c >>8);
}
returnabyte;
}
}