关于mp3的id3v2信息解析.docx_第1页
关于mp3的id3v2信息解析.docx_第2页
关于mp3的id3v2信息解析.docx_第3页
关于mp3的id3v2信息解析.docx_第4页
关于mp3的id3v2信息解析.docx_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java关于ID3v2信息解析一个mp3的ID3v2信息如下图:BlocksFieldsBytesContentHeaderID3v2 Identifier3ID3ID3v2 Version2$03 00ID3v2 Flags1%abc00000ID3v2 Size4%0xxxxxxxExtended HeaderExtended Header Size4$xx xx xx xxExtended Flags2$xx xxSize of padding4$xx xx xx xxFrameFrame ID4AENC/APIC/COMM/.Frame Size4$xx xx xx xxFlags2%abc00000 %ijk00000DATAFrame Size$xx .FrameFrame ID4AENC/APIC/COMM/.Frame Size4$xx xx xx xxFlags2%abc00000 %ijk00000DATAFrame Size$xx .Padding$00 .以下是关于一个Java版的ID3v2信息解析,代码有很多不足之处,多多指正,修改。附源代码:/* * AENC Audio encryption * APIC Attached picture * COMM Comments * COMR Commercial frame * ENCR Encryption method registration * EQUA Equalization * ETCO Event timing codes * GEOB General encapsulated object * GRID Group identification registration * IPLS Involved people list * LINK Linked information * MCDI Music CD identifier * MLLT MPEG location lookup table * OWNE Ownership frame * PRIV Private frame * PCNT Play counter * POPM Popularimeter * POSS Position synchronisation frame * RBUF Recommended buffer size * RVAD Relative volume adjustment * RVRB Reverb * SYLT Synchronized lyric/text * SYTC Synchronized tempo codes * TALB Album/Movie/Show title * TBPM BPM (beats per minute) * TCOM Composer * TCON Content type * TCOP Copyright message * TDAT Date * TDLY Playlist delay * TENC Encoded by * TEXT Lyricist/Text writer * TFLT File type * TIME Time * TIT1 Content group description * TIT2 Title/songname/content description * TIT3 Subtitle/Description refinement * TKEY Initial key * TLAN Language(s) * TLEN Length * TMED Media type * TOAL Original album/movie/show title * TOFN Original filename * TOLY Original lyricist(s)/text writer(s) * TOPE Original artist(s)/performer(s) * TORY Original release year * TOWN File owner/licensee * TPE1 Lead performer(s)/Soloist(s) * TPE2 Band/orchestra/accompaniment * TPE3 Conductor/performer refinement * TPE4 Interpreted, remixed, or otherwise modified by * TPOS Part of a set * TPUB Publisher * TRCK Track number/Position in set * TRDA Recording dates * TRSN Internet radio station name * TRSO Internet radio station owner * TSIZ Size * TSRC ISRC (international standard recording code) * TSSE Software/Hardware and settings used for encoding * TYER Year * TXXX User defined text information frame * UFID Unique file identifier * USER Terms of use * USLT Unsychronized lyric/text transcription * WCOM Commercial information * WCOP Copyright/Legal information * WOAF Official audio file webpage * WOAR Official artist/performer webpage * WOAS Official audio source webpage * WORS Official internet radio station homepage * WPAY Payment * WPUB Publishers official webpage * WXXX User defined URL link frame * author moon.lee *帧信息 */public class FrameInfo /* * 用四个字符标识一个帧,说明其内容 * 用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下: * TIT2=标题 表示内容为这首歌的标题,下同 * TPE1=作者 * TALB=专集 * TRCK=音轨 格式:N/M 其中N为专集中的第N首,M为专集中共M首,N和M为ASCII码表示的数字 * TYER=年代 是用ASCII码表示的数字 * TCON=类型 直接用字符串表示 * COMM=备注 格式:eng0备注内容,其中eng表示备注所使用的自然语言 */private String frameId;/* * 帧内容的大小,不包括帧头,不得小于1 * 这个可没有标签头的算法那么麻烦,每个字节的8位全用,格式如下 * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx * 算法如下: * int FSize; * FSize = Size0*0x1000000 * +Size1*0x10000 * +Size2*0x100 * +Size3; */private int frameContentSize;/* * 存放标志,只定义了6位 * 只定义了6位,另外的10位为0,但大部分的情况下16位都为0就可以了。格式如下: * abc00000 ijk00000 * a - 标签保护标志,设置时认为此帧作废 * b - 文件保护标志,设置时认为此帧作废 * c - 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志) * i - 压缩标志,设置时一个字节存放两个BCD码表示数字 * j - 加密标志,(没有见过哪个MP3文件的标签用了加密) * k - 组标志,设置时说明此帧和其他的某帧是一组 * 值得一提的是winamp在保存和读取帧内容的时候会在内容前面加个0,并把这个字节计算在帧内容的大小中。 * */private byteflag;/* * */private byte content=null;public FrameInfo() / TODO Auto-generated constructor stubsuper();public String getFrameId() return frameId;public void setFrameId(String frameId) this.frameId = frameId;public int getFrameContentSize() return frameContentSize;public void setFrameContentSize(int frameContentSize) this.frameContentSize = frameContentSize;public byte getFlag() return flag;public void setFlag(byte flag) this.flag = flag;public byte getContent() return content;public void setContent(byte content) this.content = content;import java.io.File;import java.io.RandomAccessFile;import java.util.HashMap;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;/* * 每个ID3V2.3的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3文件的首部。 * author moon.lee * */public class MusicInfo private String path=;private boolean isAnalysis=false;/* * 必须为ID3否则认为标签不存在 * 3个字节 */private final int HEADER_SIZE=3;private byte header;private String HEAHER_START=ID3;/* * 版本号;ID3V2.3就记录03,ID3V2.4就记录04 * 一个字节 */private byte version;/* * 副版本号;此版本记录为00 * 一个字节 */private byte reVersion;/* * 标志字节一般为0,定义如下: * 一个字节 * abc00000 * a - 表示是否使用不同步(一般不设置) * b - 表示是否有扩展头部,一般没有(至少Winamp没有记录),所以一般也不设置 * c - 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置) */private byte flag;/* * 标签大小,包括标签帧和扩展标签头。(不包括标签头的10个字节) * 一共四个字节,但每个字节只用7位,最高位不使用恒为0。所以格式如下 * 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx * 计算大小时要将0去掉,得到一个28位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如下: * int total_size; * total_size = Size0*0x200000 * +Size1*0x4000 * +Size2*0x80 * +Size3 */private int SIZE_SIZE=4;private byte size;private Map frameInfos;private int LABEL_SIZE=10;public MusicInfo() / TODO Auto-generated constructor stubsuper();frameInfos=new HashMap();public String getPath() return path;public void setPath(String path) this.path = path;public boolean isAnalysis() return isAnalysis;public void setAnalysis(boolean isAnalysis) this.isAnalysis = isAnalysis;public byte getHeader() return header;public void setHeader(byte header) this.header = header;public byte getVersion() return version;public void setVersion(byte version) this.version = version;public byte getReVersion() return reVersion;public void setReVersion(byte reVersion) this.reVersion = reVersion;public byte getFlag() return flag;public void setFlag(byte flag) this.flag = flag;public byte getSize() return size;public void setSize(byte size) this.size = size;public Map getFrameInfos() return frameInfos;/* * 解析信息 * return 0表示成功 1表示不是mp3文件 2表示文件不存在 */public int parseMusic()return parseMusic(UTF-16);/* * 解析信息 * param charset 编码方式 * return 0表示成功 1表示不是mp3文件 2表示文件不存在 3表示解析时异常 */public int parseMusic(String charset)File file=new File(path);if(!file.exists()return 2;if(!file.getName().endsWith(.mp3)return 1;try RandomAccessFile raf=new RandomAccessFile(file, r);/* * 头部信息 */header=new byteHEADER_SIZE;raf.read(header, 0, HEADER_SIZE);/System.out.println(header:+new String(header);if(new String(header).equals(HEAHER_START)/* * 版本 */version=raf.readByte();System.out.println(version:+version);/* * 副版本 */reVersion=raf.readByte();System.out.println(reVersion:+reVersion);/* * 标志 */flag=raf.readByte();System.out.println(flag:+flag);/* * 标签大小 */size=new byteSIZE_SIZE;raf.read(size);for(int i=0;isize.length;i+)System.out.println(size+i+:0x+parseDecimalToBinary(sizei);/int total_size=size0*0x200000/+size1*0x4000/+size2*0x80/+size3;/* * 标签信息 */byte label=new byteLABEL_SIZE;raf.read(label);/* * 遍历标签信息 */FrameInfo frameInfo=null;while (frameInfo=decodeFrame(label)!=null) /* * 根据标签内容大小获取标签内容 */int frameContentSize=frameInfo.getFrameContentSize();byte content=new byteframeContentSize;/* * 跳过一个字节 0 */raf.skipBytes(1);/* * 读取帧内容 */raf.read(content);/System.out.println(new String(content,charset);frameInfo.setContent(content);/* * 将帧内容加入到歌曲信息 */frameInfos.put(frameInfo.getFrameId(), frameInfo);raf.read(label);/* * 信息解析完成关闭管道 */raf.close();return 0; catch (Exception e) / TODO Auto-generated catch blocke.printStackTrace();return 3;/* * 返回图片数据信息 * * return 图片map 键mime 图片类型 键data 图片数据 * 返回空值表示没有解析到图片 * */public Map getImage()if(frameInfos=null)return null;FrameInfo apicInfo=frameInfos.get(APIC);if(apicInfo=null)return null;/* * 图片数据 */byteapic=apicInfo.getContent();boolean isMIMEComplte=false;int i=0;int start=0;/* * 查找图片数据起始位置 */Mapmap=new HashMap();for(;iapic.length;i+)/* * 寻找MIME结束位置 */if(!isMIMEComplte&apici=0)byte mime=new String(apic, 0, i).getBytes();map.put(mime, mime);isMIMEComplte=!isMIMEComplte;/* *寻找图片数据存储其实位置 */if(apici=(byte) 0xff)&apici+1=(byte) 0xd8)byte data=new byteapic.length-i;for(int j=0;jdata.length;j+)dataj=apici+j;map.put(data, data);return map;return null;public String getTitle(String charset)if(frameInfos=null)return null;FrameInfo titleInfo=frameInfos.get(TIT2);if(titleInfo=null)return null;try String title=new String(titleInfo.getContent(), charset);return title; catch (Exception e) / TODO Auto-generated catch blocke.printStackTrace();return null;public String getTitle()return getTitle(UTF-16);public String getPerformer(String charset)if(frameInfos=null)return null;FrameInfo performerInfo=frameInfos.get(TPE1);if(performerInfo=null)return null;try String performer=new String(performerInfo.getContent(), charset);return performer; catch (Exception e) / TODO Auto-generated catch blocke.printStackTrace();return null;public String getPerformer()return getPerformer(UTF-16);public String getAlbum(String charset)if(frameInfos=null)return null;FrameInfo albumInfo=frameInfos.get(TALB);if(albumInfo=null)return null;try String album=new String(albumInfo.getContent(), charset);return album; catch (Exception e) / TODO Auto-generated catch blocke.printStackTrace();return null;public String getAlbum()return getAlbum(UTF-16);/* * * 十进制转二进制字符串 * param decimal十进制byte * return 8位二进制字符串 */private String parseDecimalToBinary(byte decimal)int temp=decimal;String tempStr=;for(int j=0;jj)&1;tempStr=x+tempStr;return tempStr;/* * 解析帧标签信息 * param frameHead帧标签 10字节 * return */private FrameInfo decodeFrame(byteframeHead)if(frameHead.length!=LABEL_SIZE)return null;try /* * 将读取到的开头四个字节匹配字符串A-Z3A-Z0-91 * 匹配不成功就返回空标签 */String frameId=new String(frameHead,0,4);Pattern pattern=Ppile(A-Z3A-Z0-91);Matcher matcher=pattern.matcher(frameId);if(!matcher.matches()return null;/* * 匹配成功就解析帧标签 */System.out.println(frameID:+frameId);/* * 标签内容大小 减去 0之后的标签内容大小 */int qw=frameHead4;int bw=frameHead5;int sw=frameHead6;int gw=frameHead7;if(qw0)qw=Math.abs(qw)+128;if(bw0)bw=Math.abs(bw)+128;if(sw0)sw=Math.abs(sw)+128;if(gw0)gw=Math.abs(gw)+128;/int frameContentSize=new Integer(new String(frameHead,4,4);int frameContentSize= qw*0x1000000+bw*0x10000+sw*0x100+gw-1;/* * 解析标志信息 */byte flag=new byte2;flag0=frameHead8;flag1=frameHead9;FrameInfo frameInfo=new FrameInfo();frameInfo.setFrameId(frameId);frameInfo.setFrameContentSize(frameContentSize);frameInfo.setFlag(flag);return frameInfo; catch (NumberFormatException e) / TODO Auto-generated catch blocke.printStackTrace();return null;Ove

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论