java解析ape,YOYOPlayer开发手记(三)APEv2标签读写

/** To change this template, choose Tools | Templates

* and open the template in the editor.*/packagecom.hadeslee.audiotag.tag.ape;importcom.hadeslee.audiotag.tag.FieldDataInvalidException;importcom.hadeslee.audiotag.tag.KeyNotFoundException;importcom.hadeslee.audiotag.tag.Tag;importcom.hadeslee.audiotag.tag.TagField;importcom.hadeslee.audiotag.tag.TagFieldKey;importjava.io.ByteArrayOutputStream;importjava.io.File;importjava.io.IOException;importjava.io.RandomAccessFile;importjava.io.UnsupportedEncodingException;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importjava.util.logging.Level;importjava.util.logging.Logger;importjavax.sound.sampled.UnsupportedAudioFileException;/***

*@authorhadeslee*/publicclassAPEv2TagimplementsTag {privatestaticLogger log=Logger.getLogger(APEv2Tag.class.getName());privateFile input;privateTagHead head;privateTagBody body;privateString artist="";privateString album="";privateString title="";privateString year="";privateString comment="";privateString track="";privateString genre="";privateintfieldCount;privateMapmap;publicAPEv2Tag(File file)throwsIOException, UnsupportedAudioFileException {this.input=file;

map=newHashMap();

load();

}publicAPEv2Tag() {

map=newHashMap();

}protectedvoidload()throwsIOException, UnsupportedAudioFileException {

RandomAccessFile raf=newRandomAccessFile(input,"r");//先查看最后32个字节try{

raf.seek((int) (input.length()-32));byte[] buffer=newbyte[32];

raf.read(buffer);

head=newTagHead(buffer);if(head.isValid()) {

log.log(Level.INFO,"读取:最后32个字节有标签!");intsize=head.getTagSize();

raf.seek((int) (input.length()-size));

buffer=newbyte[size-32];intread=0;while(read

read+=raf.read(buffer, read, buffer.length-read);

}

body=newTagBody(buffer);

Listlist=body.getItems();for(TagItem item : list) {

log.log(Level.INFO, item.toString());

}

}else{//再查看128前面的32个字节raf.seek((int) (input.length()-32-128));

raf.read(buffer);

head=newTagHead(buffer);if(head.isValid()) {

log.log(Level.INFO,"读取:ID3v1前面的字节有标签!");intsize=head.getTagSize();

raf.seek((int) (input.length()-size-128));

buffer=newbyte[size-32];intread=0;while(read

read+=raf.read(buffer, read, buffer.length-read);

}

body=newTagBody(buffer);

Listlist=body.getItems();for(TagItem item : list) {

log.log(Level.INFO, item.toString());

}

}else{thrownewUnsupportedAudioFileException("读取:找不到APEv2格式的标签!");

}

}

}finally{try{

raf.close();

readTag();

}catch(Exception exe) {thrownewUnsupportedAudioFileException("读取:找不到APEv2格式的标签!");

}

}

}privatevoidreadTag() {for(TagItem item : body.getItems()) {

map.put(item.getId(), item.getContent());

}this.album=map.get(APEv2FieldKey.Album.name());this.artist=map.get(APEv2FieldKey.Artist.name());this.comment=map.get(APEv2FieldKey.Comment.name());this.genre=map.get(APEv2FieldKey.Genre.name());this.title=map.get(APEv2FieldKey.Title.name());this.track=map.get(APEv2FieldKey.Track.name());this.year=map.get(APEv2FieldKey.Year.name());

}protectedListreturnFieldToList(TagItem field) {

Listfields=newArrayList();

fields.add(field);returnfields;

}/*** 写出APE标签到文件里面去

*@paramraf 随机文件流

*@paramhasID3v1 是否有ID3v1标签

*@throwsjava.io.IOException*/publicvoidwrite(RandomAccessFile raf,booleanhasID3v1)throwsIOException {//如果有ID3标签,则先把它缓存起来,总共128个字节byte[] temp=null;intdeleteLength=0;if(hasID3v1) {

temp=newbyte[128];

raf.seek(raf.length()-128);

raf.read(temp);

deleteLength+=128;

}

TagHead header=checkTag(raf);//如果有标头,则说明有APE的标签,还要多删一些if(header!=null) {

log.log(Level.INFO,"原来存在APEv2标签,先删除之

9b8a8a44dd1c74ae49c20a7cd451974e.png");intlength=header.getTagSize();if(header.hasHeader()) {//如果有标头的话,长度还要加32个字节length+=32;

}

deleteLength+=length;

}else{

log.log(Level.INFO,"以前不存在APEv2标签,直接添加

9b8a8a44dd1c74ae49c20a7cd451974e.png");

}

raf.setLength(raf.length()-deleteLength);//把该截掉的都截了以后,就开始写标签了,先写APE的,再看//有没有ID3的,有就写,没有就不写了raf.seek(raf.length());byte[] data=getTagBytes();

raf.write(data);if(temp!=null) {

raf.write(temp);

}

log.log(Level.INFO,"APEv2标签写出完毕

9b8a8a44dd1c74ae49c20a7cd451974e.png");

}/*** 得到标签所代表的字节数组

*@return标签所代表的字节数组*/privatebyte[] getTagBytes()throwsUnsupportedEncodingException, IOException {intitemCount=map.size();

body=newTagBody();for(Map.Entryen : map.entrySet()) {

body.addTagItem(newTagItem(en.getKey(), en.getValue()));

}byte[] bodyData=body.getBytes();

log.log(Level.SEVERE,"BODYSIZE="+bodyData.length);

TagHead header=newTagHead();

header.setFlag(TagHead.HEAD);

header.setItemCount(itemCount);

header.setTagSize(bodyData.length+32);

header.setVersion(TagHead.V2);

TagHead foot=newTagHead();

foot.setFlag(TagHead.FOOT);

foot.setItemCount(itemCount);

foot.setTagSize(bodyData.length+32);

foot.setVersion(TagHead.V2);

ByteArrayOutputStream bout=newByteArrayOutputStream();

bout.write(header.getBytes());

bout.write(bodyData);

bout.write(foot.getBytes());

bout.flush();returnbout.toByteArray();

}/*** 检查是否已经存在APE的标签了,主要查两个地方

* 一个是最后的字节,还有一个是最后128字节以上的字节

* 因为最后的字节可能写入了ID3v1标签

*@paramraf 文件

*@return得到标签头

*@throwsjava.io.IOException*/privateTagHead checkTag(RandomAccessFile raf)throwsIOException {

raf.seek((int) (raf.length()-32));byte[] buffer=newbyte[32];

raf.read(buffer);

TagHead header=newTagHead(buffer);if(header.isValid()) {

header.setIndex(0);returnheader;

}else{

raf.seek((int) (raf.length()-32-128));

raf.read(buffer);

header=newTagHead(buffer);if(header.isValid()) {

header.setIndex(128);returnheader;

}else{returnnull;

}

}

}/*** 删除标签,如果存在ID3v1的话,就要先保存它然后删除后面部份

* 把它写回来

*@paramraf 写出文件

*@paramhasID3v1 是否有ID3v1标签

*@throwsjava.io.IOException*/publicvoiddelete(RandomAccessFile raf,booleanhasID3v1)throwsIOException {//如果有ID3标签,则先把它缓存起来,总共128个字节byte[] temp=null;intdeleteLength=0;if(hasID3v1) {

temp=newbyte[128];

raf.seek(raf.length()-128);

raf.read(temp);

deleteLength+=128;

}

TagHead header=checkTag(raf);//如果有标头,则说明有APE的标签,还要多删一些if(header!=null) {

log.log(Level.INFO,"原来存在APEv2标签,先删除之

9b8a8a44dd1c74ae49c20a7cd451974e.png");intlength=header.getTagSize();if(header.hasHeader()) {//如果有标头的话,长度还要加32个字节length+=32;

}

deleteLength+=length;

}

raf.setLength(raf.length()-deleteLength);

log.log(Level.INFO,"APEv2标签删除完毕

9b8a8a44dd1c74ae49c20a7cd451974e.png");

}publicvoidadd(TagField field)throwsFieldDataInvalidException {

}publicvoidaddAlbum(String album)throwsFieldDataInvalidException {

setAlbum(album);

}publicvoidaddArtist(String artist)throwsFieldDataInvalidException {

setArtist(artist);

}publicvoidaddComment(String comment)throwsFieldDataInvalidException {

setComment(comment);

}publicvoidaddGenre(String genre)throwsFieldDataInvalidException {

setGenre(genre);

}publicvoidaddTitle(String title)throwsFieldDataInvalidException {

setTitle(title);

}publicvoidaddTrack(String track)throwsFieldDataInvalidException {

setTrack(track);

}publicvoidaddYear(String year)throwsFieldDataInvalidException {

setYear(year);

}publicListget(String id) {returnnull;

}publicListgetAlbum() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Album.name(), getFirstAlbum());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicListgetArtist() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Artist.name(), getFirstArtist());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicListgetComment() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Comment.name(), getFirstComment());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicListgetGenre() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Genre.name(), getFirstGenre());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicListgetTitle() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Title.name(), getFirstTitle());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicListgetTrack() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Track.name(), getFirstTrack());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicListgetYear() {if(getFirstAlbum().length()>0) {

TagItem field=newTagItem(APEv2FieldKey.Year.name(), getFirstYear());returnreturnFieldToList(field);

}else{returnnewArrayList();

}

}publicString getFirstAlbum() {returnthis.album;

}publicString getFirstArtist() {returnartist;

}publicString getFirstComment() {returncomment;

}publicString getFirstGenre() {returngenre;

}publicString getFirstTitle() {returntitle;

}publicString getFirstTrack() {returntrack;

}publicString getFirstYear() {returnyear;

}publicbooleanhasCommonFields() {returntrue;

}publicbooleanhasField(String id) {thrownewUnsupportedOperationException("Not supported yet.");

}publicbooleanisEmpty() {thrownewUnsupportedOperationException("Not supported yet.");

}publicvoidset(TagField field)throwsFieldDataInvalidException {

TagFieldKey genericKey=TagFieldKey.valueOf(field.getId());switch(genericKey) {caseARTIST:

setArtist(field.toString());break;caseALBUM:

setAlbum(field.toString());break;caseTITLE:

setTitle(field.toString());break;caseGENRE:

setGenre(field.toString());break;caseYEAR:

setYear(field.toString());break;caseCOMMENT:

setComment(field.toString());break;

}

}publicvoidsetAlbum(String s)throwsFieldDataInvalidException {this.album=s;

map.put(APEv2FieldKey.Album.name(), album);

}publicvoidsetArtist(String s)throwsFieldDataInvalidException {this.artist=s;

map.put(APEv2FieldKey.Artist.name(), s);

}publicvoidsetComment(String s)throwsFieldDataInvalidException {this.comment=s;

map.put(APEv2FieldKey.Comment.name(), s);

}publicvoidsetGenre(String s)throwsFieldDataInvalidException {this.genre=s;

map.put(APEv2FieldKey.Genre.name(), s);

}publicvoidsetTitle(String s)throwsFieldDataInvalidException {this.title=s;

map.put(APEv2FieldKey.Title.name(), s);

}publicvoidsetTrack(String s)throwsFieldDataInvalidException {this.track=s;

map.put(APEv2FieldKey.Track.name(), s);

}publicvoidsetYear(String s)throwsFieldDataInvalidException {this.year=s;

map.put(APEv2FieldKey.Year.name(), s);

}publicTagField createTagField(TagFieldKey genericKey, String value)throwsKeyNotFoundException, FieldDataInvalidException {thrownewUnsupportedOperationException("Not supported yet.");

}publicString getFirst(String id) {thrownewUnsupportedOperationException("Not supported yet.");

}publicString getFirst(TagFieldKey id)throwsKeyNotFoundException {thrownewUnsupportedOperationException("Not supported yet.");

}publicTagField getFirstField(String id) {thrownewUnsupportedOperationException("Not supported yet.");

}publicvoiddeleteTagField(TagFieldKey tagFieldKey)throwsKeyNotFoundException {thrownewUnsupportedOperationException("Not supported yet.");

}publicIterator getFields() {thrownewUnsupportedOperationException("Not supported yet.");

}publicintgetFieldCount() {thrownewUnsupportedOperationException("Not supported yet.");

}publicbooleansetEncoding(String enc)throwsFieldDataInvalidException {returnfalse;

}publicListget(TagFieldKey id)throwsKeyNotFoundException {thrownewUnsupportedOperationException("Not supported yet.");

}publicstaticvoidmain(String[] args)throwsException {

System.out.println(0xD2);//APEv2Tag tag = new APEv2Tag(new File("D:\\难道爱一个人有错吗.mp3"));//tag.load();//System.out.println("tag.album:" + tag.getFirstAlbum());//System.out.println("tag.title:" + tag.getFirstTitle());//System.out.println("tag.artist:" + tag.getFirstArtist());}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值