📄 id3v24frame.java
字号:
/*
* MusicTag Copyright (C)2003,2004
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not,
* you can get a copy from http://www.opensource.org/licenses/lgpl-license.php or write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.hadeslee.audiotag.tag.id3;
import com.hadeslee.audiotag.FileConstants;
import com.hadeslee.audiotag.audio.mp3.MP3File;
import com.hadeslee.audiotag.audio.generic.Utils;
import com.hadeslee.audiotag.tag.EmptyFrameException;
import com.hadeslee.audiotag.tag.InvalidFrameException;
import com.hadeslee.audiotag.tag.InvalidFrameIdentifierException;
import com.hadeslee.audiotag.tag.InvalidTagException;
import com.hadeslee.audiotag.tag.TagOptionSingleton;
import com.hadeslee.audiotag.tag.datatype.Lyrics3Line;
import com.hadeslee.audiotag.tag.id3.framebody.AbstractID3v2FrameBody;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyCOMM;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyDeprecated;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodySYLT;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyTALB;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyTCOM;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyTIT2;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyTPE1;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyUSLT;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyUnsupported;
import com.hadeslee.audiotag.tag.id3.framebody.ID3v24FrameBody;
import com.hadeslee.audiotag.tag.lyrics3.FieldFrameBodyAUT;
import com.hadeslee.audiotag.tag.lyrics3.FieldFrameBodyEAL;
import com.hadeslee.audiotag.tag.lyrics3.FieldFrameBodyEAR;
import com.hadeslee.audiotag.tag.lyrics3.FieldFrameBodyETT;
import com.hadeslee.audiotag.tag.lyrics3.FieldFrameBodyINF;
import com.hadeslee.audiotag.tag.lyrics3.FieldFrameBodyLYR;
import com.hadeslee.audiotag.tag.lyrics3.Lyrics3v2Field;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Represents an ID3v2.4 frame.
*
* @author : Paul Taylor
* @author : Eric Farng
* @version $Id: ID3v24Frame.java,v 1.42 2007/11/29 12:05:26 paultaylor Exp $
*/
public class ID3v24Frame extends AbstractID3v2Frame
{
Pattern validFrameIdentifier = Pattern.compile("[A-Z][0-9A-Z]{3}");
protected static final int FRAME_DATA_LENGTH_SIZE =4;
protected static final int FRAME_ID_SIZE = 4;
protected static final int FRAME_FLAGS_SIZE = 2;
protected static final int FRAME_SIZE_SIZE = 4;
protected static final int FRAME_ENCRYPTION_INDICATOR_SIZE =1;
protected static final int FRAME_GROUPING_INDICATOR_SIZE =1;
protected static final int FRAME_HEADER_SIZE = FRAME_ID_SIZE + FRAME_SIZE_SIZE + FRAME_FLAGS_SIZE;
public ID3v24Frame()
{
}
/**
* Creates a new ID3v2_4Frame of type identifier. An empty
* body of the correct type will be automatically created.
* This constructor should be used when wish to create a new
* frame from scratch using user input
*
* @param identifier defines the type of body to be created
*/
public ID3v24Frame(String identifier)
{
//Super Constructor creates a frame with empty body of type specified
super(identifier);
statusFlags = new StatusFlags();
encodingFlags = new EncodingFlags();
}
/**
* Copy Constructor:Creates a new ID3v2_4Frame datatype based on another frame.
*/
public ID3v24Frame(ID3v24Frame frame)
{
super(frame);
statusFlags = new StatusFlags(frame.getStatusFlags().getOriginalFlags());
encodingFlags = new EncodingFlags(frame.getEncodingFlags().getFlags());
}
private void createV24FrameFromV23Frame(ID3v23Frame frame)throws InvalidFrameException
{
// Is it a straight conversion e.g TALB - TALB
identifier = ID3Tags.convertFrameID23To24(frame.getIdentifier());
if (identifier != null)
{
logger.info("V3:Orig id is:" + frame.getIdentifier() + ":New id is:" + identifier);
this.frameBody = (AbstractID3v2FrameBody) ID3Tags.copyObject(frame.getBody());
this.frameBody.setHeader(this);
return;
}
// Is it a known v3 frame which needs forcing to v4 frame e.g. TYER - TDRC
else if (ID3Tags.isID3v23FrameIdentifier(frame.getIdentifier()) == true)
{
identifier = ID3Tags.forceFrameID23To24(frame.getIdentifier());
if (identifier != null)
{
logger.info("V3:Orig id is:" + frame.getIdentifier() + ":New id is:" + identifier);
this.frameBody = this.readBody(identifier, (AbstractID3v2FrameBody) frame.getBody());
this.frameBody.setHeader(this);
return;
}
// No mechanism exists to convert it to a v24 frame, e.g deprecated frame e.g TSIZ, so hold
// as a deprecated frame consisting of an array of bytes*/
else
{
this.frameBody = new FrameBodyDeprecated((AbstractID3v2FrameBody) frame.getBody());
this.frameBody.setHeader(this);
identifier = frame.getIdentifier();
logger.info("V3:Deprecated:Orig id is:" + frame.getIdentifier() + ":New id is:" + identifier);
return;
}
}
// Unknown Frame e.g NCON or TDRL (because TDRL unknown to V23)
else
{
this.frameBody = new FrameBodyUnsupported((FrameBodyUnsupported) frame.getBody());
this.frameBody.setHeader(this);
identifier = frame.getIdentifier();
logger.info("V3:Unknown:Orig id is:" + frame.getIdentifier() + ":New id is:" + identifier);
return;
}
}
/**
* Creates a new ID3v2_4Frame datatype based on another frame of different version
* Converts the framebody to the equivalent v24 framebody or to UnsupportedFrameBody if identifier
* is unknown.
*
* @param frame to construct a new frame from
*/
public ID3v24Frame(AbstractID3v2Frame frame) throws InvalidFrameException
{
//Should not be called
if ((frame instanceof ID3v24Frame == true))
{
throw new UnsupportedOperationException("Copy Constructor not called. Please type cast the argument");
}
//Flags
if (frame instanceof ID3v23Frame)
{
statusFlags = new StatusFlags((ID3v23Frame.StatusFlags) ((ID3v23Frame) frame).getStatusFlags());
encodingFlags = new EncodingFlags(((ID3v23Frame) frame).getEncodingFlags().getFlags());
}
else
{
statusFlags = new StatusFlags();
encodingFlags = new EncodingFlags();
}
// Convert Identifier. If the id was a known id for the original
// version we should be able to convert it to an v24 frame, although it may mean minor
// modification to the data. If it was not recognised originally it should remain
// unknown.
if (frame instanceof ID3v23Frame)
{
createV24FrameFromV23Frame((ID3v23Frame)frame);
}
else if (frame instanceof ID3v22Frame)
{
ID3v23Frame v23Frame = new ID3v23Frame(frame);
createV24FrameFromV23Frame(v23Frame);
}
this.frameBody.setHeader(this);
}
/**
* Creates a new ID3v2_4Frame datatype based on Lyrics3.
*
* @param field
* @throws InvalidTagException
*/
public ID3v24Frame(Lyrics3v2Field field)
throws InvalidTagException
{
String id = field.getIdentifier();
String value;
if (id.equals("IND"))
{
throw new InvalidTagException("Cannot create ID3v2.40 frame from Lyrics3 indications field.");
}
else if (id.equals("LYR"))
{
FieldFrameBodyLYR lyric = (FieldFrameBodyLYR) field.getBody();
Lyrics3Line line;
Iterator iterator = lyric.iterator();
FrameBodySYLT sync;
FrameBodyUSLT unsync;
boolean hasTimeStamp = lyric.hasTimeStamp();
// we'll create only one frame here.
// if there is any timestamp at all, we will create a sync'ed frame.
sync = new FrameBodySYLT((byte) 0, "ENG", (byte) 2, (byte) 1, "",new byte[0]);
unsync = new FrameBodyUSLT((byte) 0, "ENG", "", "");
while (iterator.hasNext())
{
line = (Lyrics3Line) iterator.next();
if (hasTimeStamp)
{
// sync.addLyric(line);
}
else
{
unsync.addLyric(line);
}
}
if (hasTimeStamp)
{
this.frameBody = sync;
this.frameBody.setHeader(this);
}
else
{
this.frameBody = unsync;
this.frameBody.setHeader(this);
}
}
else if (id.equals("INF"))
{
value = ((FieldFrameBodyINF) field.getBody()).getAdditionalInformation();
this.frameBody = new FrameBodyCOMM((byte) 0, "ENG", "", value);
this.frameBody.setHeader(this);
}
else if (id.equals("AUT"))
{
value = ((FieldFrameBodyAUT) field.getBody()).getAuthor();
this.frameBody = new FrameBodyTCOM((byte) 0, value);
this.frameBody.setHeader(this);
}
else if (id.equals("EAL"))
{
value = ((FieldFrameBodyEAL) field.getBody()).getAlbum();
this.frameBody = new FrameBodyTALB((byte) 0, value);
this.frameBody.setHeader(this);
}
else if (id.equals("EAR"))
{
value = ((FieldFrameBodyEAR) field.getBody()).getArtist();
this.frameBody = new FrameBodyTPE1((byte) 0, value);
this.frameBody.setHeader(this);
}
else if (id.equals("ETT"))
{
value = ((FieldFrameBodyETT) field.getBody()).getTitle();
this.frameBody = new FrameBodyTIT2((byte) 0, value);
this.frameBody.setHeader(this);
}
else if (id.equals("IMG"))
{
throw new InvalidTagException("Cannot create ID3v2.40 frame from Lyrics3 image field.");
}
else
{
throw new InvalidTagException("Cannot caret ID3v2.40 frame from " + id + " Lyrics3 field");
}
}
/**
* Creates a new ID3v24Frame datatype by reading from byteBuffer.
*
* @param byteBuffer to read from
*/
public ID3v24Frame(ByteBuffer byteBuffer,String loggingFilename)
throws InvalidFrameException
{
setLoggingFilename(loggingFilename);
read(byteBuffer);
}
/**
* Creates a new ID3v24Frame datatype by reading from byteBuffer.
*
* @param byteBuffer to read from
*
* @deprecated use {@link #ID3v24Frame(ByteBuffer,String)} instead
*/
public ID3v24Frame(ByteBuffer byteBuffer)
throws InvalidFrameException
{
this(byteBuffer,"");
}
/**
* @param obj
* @return if obj is equivalent to this frame
*/
public boolean equals(Object obj)
{
if ((obj instanceof ID3v24Frame) == false)
{
return false;
}
return super.equals(obj);
}
/**
* Return size of frame
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -