📄 id3v22tag.java
字号:
//We need to synchronize the buffer
if(unsynchronization==true)
{
bufferWithoutHeader=ID3Unsynchronization.synchronize(bufferWithoutHeader);
}
readFrames(bufferWithoutHeader,size);
logger.info(getLoggingFilename()+":"+"Loaded Frames,there are:" + frameMap.keySet().size());
}
/**
* Read frames from tag
*/
protected void readFrames(ByteBuffer byteBuffer, int size)
{
//Now start looking for frames
ID3v22Frame next;
frameMap = new LinkedHashMap();
//Read the size from the Tag Header
this.fileReadSize = size;
logger.finest(getLoggingFilename()+":"+"Start of frame body at:" + byteBuffer.position() + ",frames sizes and padding is:" + size);
/* todo not done yet. Read the first Frame, there seems to be quite a
** common case of extra data being between the tag header and the first
** frame so should we allow for this when reading first frame, but not subsequent frames
*/
// Read the frames until got to upto the size as specified in header
while (byteBuffer.position()<size)
{
try
{
//Read Frame
logger.finest(getLoggingFilename()+":"+"looking for next frame at:" + byteBuffer.position());
next = new ID3v22Frame(byteBuffer,getLoggingFilename());
String id = next.getIdentifier();
loadFrameIntoMap(id, next);
}
//Found Empty Frame
catch (EmptyFrameException ex)
{
logger.warning(getLoggingFilename()+":"+"Empty Frame:"+ex.getMessage());
this.emptyFrameBytes += ID3v22Frame.FRAME_HEADER_SIZE;
}
catch ( InvalidFrameIdentifierException ifie)
{
logger.info(getLoggingFilename()+":"+"Invalid Frame Identifier:"+ifie.getMessage());
this.invalidFrameBytes++;
//Dont try and find any more frames
break;
}
//Problem trying to find frame
catch (InvalidFrameException ife)
{
logger.warning(getLoggingFilename()+":"+"Invalid Frame:"+ife.getMessage());
this.invalidFrameBytes++;
//Dont try and find any more frames
break;
}
;
}
}
/**
* This is used when we need to translate a single frame into multiple frames,
* currently required for TDRC frames.
*/
protected void translateFrame(AbstractID3v2Frame frame)
{
FrameBodyTDRC tmpBody = (FrameBodyTDRC) frame.getBody();
ID3v22Frame newFrame;
if (tmpBody.getYear().length() != 0)
{
//Create Year frame (v2.2 id,but uses v2.3 body)
newFrame = new ID3v22Frame(ID3v22Frames.FRAME_ID_V2_TYER);
((AbstractFrameBodyTextInfo) newFrame.getBody()).setText(tmpBody.getYear());
frameMap.put(newFrame.getIdentifier(), newFrame);
}
if (tmpBody.getTime().length() != 0)
{
//Create Time frame (v2.2 id,but uses v2.3 body)
newFrame = new ID3v22Frame(ID3v22Frames.FRAME_ID_V2_TIME);
((AbstractFrameBodyTextInfo) newFrame.getBody()).setText(tmpBody.getTime());
frameMap.put(newFrame.getIdentifier(), newFrame);
}
}
/**
* Write the ID3 header to the ByteBuffer.
*
* TODO compression support required.
*
* @return ByteBuffer
* @throws IOException
*/
private ByteBuffer writeHeaderToBuffer(int padding,int size) throws IOException
{
compression = false;
//Create Header Buffer
ByteBuffer headerBuffer = ByteBuffer.allocate(TAG_HEADER_LENGTH);
//TAGID
headerBuffer.put(TAG_ID);
//Major Version
headerBuffer.put(getMajorVersion());
//Minor Version
headerBuffer.put(getRevision());
//Flags
byte flags = (byte) 0;
if (unsynchronization == true)
{
flags |= (byte) MASK_V22_UNSYNCHRONIZATION;
}
if (compression == true)
{
flags |= (byte) MASK_V22_COMPRESSION;
}
headerBuffer.put(flags);
//Size As Recorded in Header, don't include the main header length
headerBuffer.put(ID3SyncSafeInteger.valueToBuffer(padding + size));
headerBuffer.flip();
return headerBuffer;
}
/**
* Write tag to file
*
* @param file The file to write to
* @throws IOException
*/
public void write(File file, long audioStartLocation)
throws IOException
{
logger.info("Writing tag to file");
// Write Body Buffer */
byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray();
// Unsynchronize if option enabled and unsync required
if(TagOptionSingleton.getInstance().isUnsyncTags())
{
unsynchronization = ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer);
}
else
{
unsynchronization=false;
}
if(isUnsynchronization())
{
bodyByteBuffer=ID3Unsynchronization.unsynchronize(bodyByteBuffer);
logger.info(getLoggingFilename()+":bodybytebuffer:sizeafterunsynchronisation:"+bodyByteBuffer.length);
}
int sizeIncPadding = calculateTagSize(bodyByteBuffer.length + TAG_HEADER_LENGTH, (int) audioStartLocation);
int padding = sizeIncPadding - (bodyByteBuffer.length + TAG_HEADER_LENGTH) ;
logger.info(getLoggingFilename()+":Current audiostart:"+audioStartLocation);
logger.info(getLoggingFilename()+":Size including padding:"+sizeIncPadding);
logger.info(getLoggingFilename()+":Padding:"+padding);
ByteBuffer headerBuffer = writeHeaderToBuffer(padding,bodyByteBuffer.length);
//We need to adjust location of audio File
if (sizeIncPadding > audioStartLocation)
{
logger.info(getLoggingFilename()+":Adjusting Padding");
adjustPadding(file, sizeIncPadding, audioStartLocation);
}
//Write changes to file
FileChannel fc = null;
try
{
fc = new RandomAccessFile(file, "rw").getChannel();
fc.write(headerBuffer);
fc.write(ByteBuffer.wrap(bodyByteBuffer));
fc.write(ByteBuffer.wrap(new byte[padding]));
}
finally
{
if(fc!=null)
{
fc.close();
}
}
}
/**
* Write tag to channel
*
* @param channel
* @throws IOException
*/
public void write(WritableByteChannel channel)
throws IOException
{
logger.info(getLoggingFilename()+":Writing tag to channel");
byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray();
logger.info(getLoggingFilename()+":bodybytebuffer:sizebeforeunsynchronisation:"+bodyByteBuffer.length);
//Unsynchronize if option enabled and unsync required
if(TagOptionSingleton.getInstance().isUnsyncTags())
{
unsynchronization = ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer);
}
else
{
unsynchronization=false;
}
if(isUnsynchronization())
{
bodyByteBuffer=ID3Unsynchronization.unsynchronize(bodyByteBuffer);
logger.info(getLoggingFilename()+":bodybytebuffer:sizeafterunsynchronisation:"+bodyByteBuffer.length);
}
ByteBuffer headerBuffer = writeHeaderToBuffer(0,bodyByteBuffer.length);
channel.write(headerBuffer);
channel.write(ByteBuffer.wrap(bodyByteBuffer));
}
public void createStructure()
{
MP3File.getStructureFormatter().openHeadingElement(TYPE_TAG, getIdentifier());
super.createStructureHeader();
//Header
MP3File.getStructureFormatter().openHeadingElement(TYPE_HEADER, "");
MP3File.getStructureFormatter().addElement(TYPE_COMPRESSION, this.compression);
MP3File.getStructureFormatter().addElement(TYPE_UNSYNCHRONISATION, this.unsynchronization);
MP3File.getStructureFormatter().closeHeadingElement(TYPE_HEADER);
//Body
super.createStructureBody();
MP3File.getStructureFormatter().closeHeadingElement(TYPE_TAG);
}
/**
*
* @return is tag unsynchronized
*/
public boolean isUnsynchronization()
{
return unsynchronization;
}
/**
*
* @return is tag compressed
*/
public boolean isCompression()
{
return compression;
}
protected String getArtistId()
{
return ID3v22Frames.FRAME_ID_V2_ARTIST;
}
protected String getAlbumId()
{
return ID3v22Frames.FRAME_ID_V2_ALBUM;
}
protected String getTitleId()
{
return ID3v22Frames.FRAME_ID_V2_TITLE;
}
protected String getTrackId()
{
return ID3v22Frames.FRAME_ID_V2_TRACK;
}
protected String getYearId()
{
return ID3v22Frames.FRAME_ID_V2_TYER;
}
protected String getCommentId()
{
return ID3v22Frames.FRAME_ID_V2_COMMENT;
}
protected String getGenreId()
{
return ID3v22Frames.FRAME_ID_V2_GENRE;
}
/**
* Create Frame
* @param id frameid
* @return
*/
public ID3v22Frame createFrame(String id)
{
return new ID3v22Frame(id);
}
/**
* Create Frame for Id3 Key
* <p/>
* Only textual data supported at the moment, should only be used with frames that
* support a simple string argument.
*
* @param id3Key
* @param value
* @return
* @throws KeyNotFoundException
* @throws FieldDataInvalidException
*/
public TagField createTagField(ID3v22FieldKey id3Key, String value)
throws KeyNotFoundException, FieldDataInvalidException
{
if (id3Key == null)
{
throw new KeyNotFoundException();
}
return super.doCreateTagField(new FrameAndSubId(id3Key.getFrameId(),id3Key.getSubId()),value);
}
/**
* Retrieve the first value that exists for this id3v22key
*
* @param id3v22FieldKey
* @return
*/
public String getFirst(ID3v22FieldKey id3v22FieldKey) throws KeyNotFoundException
{
if (id3v22FieldKey == null)
{
throw new KeyNotFoundException();
}
return super.doGetFirst(new FrameAndSubId(id3v22FieldKey.getFrameId(),id3v22FieldKey.getSubId()));
}
/**
* Delete fields with this id3v22FieldKey
*
* @param id3v22FieldKey
*/
public void deleteTagField
(ID3v22FieldKey
id3v22FieldKey) throws KeyNotFoundException
{
if (id3v22FieldKey == null)
{
throw new KeyNotFoundException();
}
super.doDeleteTagField(new FrameAndSubId(id3v22FieldKey.getFrameId(),id3v22FieldKey.getSubId()));
}
protected FrameAndSubId getFrameAndSubIdFromGenericKey(TagFieldKey genericKey)
{
ID3v22FieldKey id3v22FieldKey = ID3v22Frames.getInstanceOf().getId3KeyFromGenericKey(genericKey);
if (id3v22FieldKey == null)
{
throw new KeyNotFoundException();
}
return new FrameAndSubId(id3v22FieldKey.getFrameId(),id3v22FieldKey.getSubId());
}
protected ID3Frames getID3Frames()
{
return ID3v22Frames.getInstanceOf();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -