📄 id3v22frame.java
字号:
* Creates a new ID3v22Frame datatype by reading from byteBuffer.
*
* @param byteBuffer to read from
*/
public ID3v22Frame(ByteBuffer byteBuffer, String loggingFilename) throws InvalidFrameException
{
setLoggingFilename(loggingFilename);
read(byteBuffer);
}
/**
* Creates a new ID3v23Frame datatype by reading from byteBuffer.
*
* @param byteBuffer to read from
* @deprecated use {@link #ID3v22Frame(ByteBuffer,String)} instead
*/
public ID3v22Frame(ByteBuffer byteBuffer) throws InvalidFrameException
{
this(byteBuffer, "");
}
/**
* Return size of frame
*
* @return int size of frame
*/
public int getSize()
{
return frameBody.getSize() + FRAME_HEADER_SIZE;
}
/**
* Read frame from file.
* Read the frame header then delegate reading of data to frame body.
*
* @param byteBuffer
*/
public void read(ByteBuffer byteBuffer) throws InvalidFrameException
{
byte[] buffer = new byte[FRAME_ID_SIZE];
if (byteBuffer.position() + FRAME_HEADER_SIZE >= byteBuffer.limit())
{
logger.warning("No space to find another frame:");
throw new InvalidFrameException(" No space to find another frame");
}
// Read the FrameID Identifier
byteBuffer.get(buffer, 0, FRAME_ID_SIZE);
identifier = new String(buffer);
logger.info("Read Frame from file identifier is:" + identifier);
// Is this a valid identifier?
if (isValidID3v2FrameIdentifier(identifier) == false)
{
logger.info("Invalid identifier:" + identifier);
byteBuffer.position(byteBuffer.position() - (FRAME_ID_SIZE - 1));
throw new InvalidFrameIdentifierException(identifier + " is not a valid ID3v2.20 frame");
}
//Read Frame Size (same size as Frame Id so reuse buffer)
byteBuffer.get(buffer, 0, FRAME_SIZE_SIZE);
frameSize = decodeSize(buffer);
if (frameSize < 0)
{
throw new InvalidFrameException(identifier + " has invalid size of:" + frameSize);
}
else if (frameSize == 0)
{
logger.warning("Empty Frame:" + identifier);
throw new EmptyFrameException(identifier + " is empty frame");
}
else if (frameSize > byteBuffer.remaining())
{
logger.warning("Invalid Frame size larger than size before mp3 audio:" + identifier);
throw new InvalidFrameException(identifier + " is invalid frame");
}
else
{
logger.fine("Frame Size Is:" + frameSize);
//Convert v2.2 to v2.4 id just for reading the data
String id = (String) ID3Tags.convertFrameID22To24(identifier);
if (id == null)
{
//OK,it may be convertable to a v.3 id even though not valid v.4
id = (String) ID3Tags.convertFrameID22To23(identifier);
if (id == null)
{
// Is it a valid v22 identifier so should be able to find a
// frame body for it.
if (ID3Tags.isID3v22FrameIdentifier(identifier) == true)
{
id = identifier;
}
// Unknown so will be created as FrameBodyUnsupported
else
{
id = UNSUPPORTED_ID;
}
}
}
logger.fine("Identifier was:" + identifier + " reading using:" + id);
//Create Buffer that only contains the body of this frame rather than the remainder of tag
ByteBuffer frameBodyBuffer = byteBuffer.slice();
frameBodyBuffer.limit(frameSize);
try
{
frameBody = readBody(id, frameBodyBuffer, frameSize);
}
finally
{
//Update position of main buffer, so no attempt is made to reread these bytes
byteBuffer.position(byteBuffer.position() + frameSize);
}
}
}
/**
* Read Frame Size, which has to be decoded
*/
private int decodeSize(byte[] buffer)
{
BigInteger bi = new BigInteger(buffer);
int tmpSize = bi.intValue();
if (tmpSize < 0)
{
logger.warning("Invalid Frame Size of:" + tmpSize + "Decoded from bin:" + Integer.toBinaryString(tmpSize) + "Decoded from hex:" + Integer.toHexString(tmpSize));
}
return tmpSize;
}
/**
* Write Frame raw data
*
* @throws IOException
*/
public void write(ByteArrayOutputStream tagBuffer)
{
logger.info("Write Frame to Buffer" + getIdentifier());
//This is where we will write header, move position to where we can
//write body
ByteBuffer headerBuffer = ByteBuffer.allocate(FRAME_HEADER_SIZE);
//Write Frame Body Data
ByteArrayOutputStream bodyOutputStream = new ByteArrayOutputStream();
((AbstractID3v2FrameBody) frameBody).write(bodyOutputStream);
//Write Frame Header
//Write Frame ID must adjust can only be 3 bytes long
headerBuffer.put(Utils.getDefaultBytes(getIdentifier(),"ISO-8859-1"), 0, FRAME_ID_SIZE);
encodeSize(headerBuffer, frameBody.getSize());
//Add header to the Byte Array Output Stream
try
{
tagBuffer.write(headerBuffer.array());
//Add body to the Byte Array Output Stream
tagBuffer.write(bodyOutputStream.toByteArray());
}
catch(IOException ioe)
{
//This could never happen coz not writing to file, so convert to RuntimeException
throw new RuntimeException(ioe);
}
}
/**
* Write Frame Size (can now be accurately calculated, have to convert 4 byte int
* to 3 byte format.
*/
private void encodeSize(ByteBuffer headerBuffer, int size)
{
headerBuffer.put((byte) ((size & 0x00FF0000) >> 16));
headerBuffer.put((byte) ((size & 0x0000FF00) >> 8));
headerBuffer.put((byte) (size & 0x000000FF));
logger.fine("Frame Size Is Actual:" + size + ":Encoded bin:" + Integer.toBinaryString(size) + ":Encoded Hex" + Integer.toHexString(size));
}
/**
* Does the frame identifier meet the syntax for a idv3v2 frame identifier.
* must start with a capital letter and only contain capital letters and numbers
*
* @param identifier
* @return
*/
public boolean isValidID3v2FrameIdentifier(String identifier)
{
Matcher m = validFrameIdentifier.matcher(identifier);
return m.matches();
}
/**
* Return String Representation of body
*/
public void createStructure()
{
MP3File.getStructureFormatter().openHeadingElement(TYPE_FRAME, getIdentifier());
MP3File.getStructureFormatter().addElement(TYPE_FRAME_SIZE, frameSize);
frameBody.createStructure();
MP3File.getStructureFormatter().closeHeadingElement(TYPE_FRAME);
}
/**
*
* @return true if considered a common frame
*/
public boolean isCommon()
{
return ID3v22Frames.getInstanceOf().isCommon(getId());
}
/**
*
* @return true if considered a common frame
*/
public boolean isBinary()
{
return ID3v22Frames.getInstanceOf().isBinary(getId());
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -