Methods Summary |
---|
protected void | addFrame(AbstractID3v2Frame frame)
try
{
//Special case to handle TDRC frame from V24 that needs breaking up into separate frame in V23
if ((frame.getIdentifier().equals(ID3v24Frames.FRAME_ID_YEAR)) && (frame.getBody() instanceof FrameBodyTDRC))
{
translateFrame(frame);
}
else if (frame instanceof ID3v22Frame)
{
copyFrameIntoMap(frame.getIdentifier(),frame);
}
else
{
ID3v22Frame newFrame = new ID3v22Frame(frame);
copyFrameIntoMap(newFrame.getIdentifier(), newFrame);
}
}
catch (InvalidFrameException ife)
{
logger.log(Level.SEVERE, "Unable to convert frame:" + frame.getIdentifier());
}
|
protected void | copyPrimitives(AbstractID3v2Tag copyObj)Copy primitives applicable to v2.2
logger.config("Copying primitives");
super.copyPrimitives(copyObj);
//Set the primitive types specific to v2_2.
if (copyObj instanceof ID3v22Tag)
{
ID3v22Tag copyObject = (ID3v22Tag) copyObj;
this.compression = copyObject.compression;
this.unsynchronization = copyObject.unsynchronization;
}
else if (copyObj instanceof ID3v23Tag)
{
ID3v23Tag copyObject = (ID3v23Tag) copyObj;
this.compression = copyObject.compression;
this.unsynchronization = copyObject.unsynchronization;
}
else if (copyObj instanceof ID3v24Tag)
{
ID3v24Tag copyObject = (ID3v24Tag) copyObj;
this.compression = false;
this.unsynchronization = copyObject.unsynchronization;
}
|
public TagField | createArtworkField(byte[] data, java.lang.String mimeType)
AbstractID3v2Frame frame = createFrame(getFrameAndSubIdFromGenericKey(FieldKey.COVER_ART).getFrameId());
FrameBodyPIC body = (FrameBodyPIC) frame.getBody();
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, data);
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, PictureTypes.DEFAULT_ID);
body.setObjectValue(DataTypes.OBJ_IMAGE_FORMAT, ImageFormats.getFormatForMimeType(mimeType));
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
return frame;
|
public TagField | createField(ID3v22FieldKey id3Key, java.lang.String value)Create Frame for Id3 Key
Only textual data supported at the moment, should only be used with frames that
support a simple string argument.
if (id3Key == null)
{
throw new KeyNotFoundException();
}
return super.doCreateTagField(new FrameAndSubId(id3Key.getFrameId(), id3Key.getSubId()), value);
|
public TagField | createField(org.jaudiotagger.tag.images.Artwork artwork){@inheritDoc}
AbstractID3v2Frame frame = createFrame(getFrameAndSubIdFromGenericKey(FieldKey.COVER_ART).getFrameId());
FrameBodyPIC body = (FrameBodyPIC) frame.getBody();
if(!artwork.isLinked())
{
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, artwork.getBinaryData());
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, artwork.getPictureType());
body.setObjectValue(DataTypes.OBJ_IMAGE_FORMAT, ImageFormats.getFormatForMimeType(artwork.getMimeType()));
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
return frame;
}
else
{
try
{
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA,artwork.getImageUrl().getBytes("ISO-8859-1"));
}
catch(UnsupportedEncodingException uoe)
{
throw new RuntimeException(uoe.getMessage());
}
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, artwork.getPictureType());
body.setObjectValue(DataTypes.OBJ_IMAGE_FORMAT, FrameBodyAPIC.IMAGE_IS_URL);
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
return frame;
}
|
public ID3v22Frame | createFrame(java.lang.String id)Create Frame
return new ID3v22Frame(id);
|
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);
|
public void | deleteField(ID3v22FieldKey id3v22FieldKey)Delete fields with this id3v22FieldKey
if (id3v22FieldKey == null)
{
throw new KeyNotFoundException();
}
super.doDeleteTagField(new FrameAndSubId(id3v22FieldKey.getFrameId(), id3v22FieldKey.getSubId()));
|
public void | deleteField(java.lang.String id)Delete fields with this (frame) id
super.doDeleteTagField(new FrameAndSubId(id,null));
|
public boolean | equals(java.lang.Object obj)
if (!(obj instanceof ID3v22Tag))
{
return false;
}
ID3v22Tag object = (ID3v22Tag) obj;
if (this.compression != object.compression)
{
return false;
}
return this.unsynchronization == object.unsynchronization && super.equals(obj);
|
public java.util.List | getArtworkList(){@inheritDoc}
List<TagField> coverartList = getFields(FieldKey.COVER_ART);
List<Artwork> artworkList = new ArrayList<Artwork>(coverartList.size());
for (TagField next : coverartList)
{
FrameBodyPIC coverArt = (FrameBodyPIC) ((AbstractID3v2Frame) next).getBody();
Artwork artwork = ArtworkFactory.getNew();
artwork.setMimeType(ImageFormats.getMimeTypeForFormat(coverArt.getFormatType()));
artwork.setPictureType(coverArt.getPictureType());
if (coverArt.isImageUrl())
{
artwork.setLinked(true);
artwork.setImageUrl(coverArt.getImageUrl());
}
else
{
artwork.setBinaryData(coverArt.getImageData());
}
artworkList.add(artwork);
}
return artworkList;
|
public java.lang.String | getFirst(ID3v22FieldKey id3v22FieldKey)Retrieve the first value that exists for this id3v22key
if (id3v22FieldKey == null)
{
throw new KeyNotFoundException();
}
FrameAndSubId frameAndSubId = new FrameAndSubId(id3v22FieldKey.getFrameId(), id3v22FieldKey.getSubId());
if (id3v22FieldKey == ID3v22FieldKey.TRACK)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTRCK)frame.getBody()).getTrackNo());
}
else if (id3v22FieldKey == ID3v22FieldKey.TRACK_TOTAL)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTRCK)frame.getBody()).getTrackTotal());
}
else if (id3v22FieldKey == ID3v22FieldKey.DISC_NO)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTPOS)frame.getBody()).getDiscNo());
}
else if (id3v22FieldKey == ID3v22FieldKey.DISC_TOTAL)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTPOS)frame.getBody()).getDiscTotal());
}
else
{
return super.doGetValueAtIndex(frameAndSubId, 0);
}
|
protected FrameAndSubId | getFrameAndSubIdFromGenericKey(FieldKey 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();
|
public java.lang.String | getIdentifier()
return "ID3v2_2.20";
|
public byte | getMajorVersion()Retrieve the Major Version
return MAJOR_VERSION;
|
public java.util.Comparator | getPreferredFrameOrderComparator()
return ID3v22PreferredFrameOrderComparator.getInstanceof();
|
public byte | getRelease()Retrieve the Release
return RELEASE;
|
public byte | getRevision()Retrieve the Revision
return REVISION;
|
public int | getSize()Return frame size based upon the sizes of the frames rather than the size
including padding recorded in the tag header
int size = TAG_HEADER_LENGTH;
size += super.getSize();
return size;
|
public boolean | isCompression()
return compression;
|
public boolean | isUnsynchronization()
return unsynchronization;
|
public void | read(java.nio.ByteBuffer byteBuffer){@inheritDoc}
int size;
if (!seek(byteBuffer))
{
throw new TagNotFoundException("ID3v2.20 tag not found");
}
logger.config(getLoggingFilename() + ":" + "Reading tag from file");
//Read the flags
readHeaderFlags(byteBuffer);
// Read the size
size = ID3SyncSafeInteger.bufferToValue(byteBuffer);
//Slice Buffer, so position markers tally with size (i.e do not include tagheader)
ByteBuffer bufferWithoutHeader = byteBuffer.slice();
//We need to synchronize the buffer
if (unsynchronization)
{
bufferWithoutHeader = ID3Unsynchronization.synchronize(bufferWithoutHeader);
}
readFrames(bufferWithoutHeader, size);
logger.config(getLoggingFilename() + ":" + "Loaded Frames,there are:" + frameMap.keySet().size());
|
protected void | readFrames(java.nio.ByteBuffer byteBuffer, int size)Read frames from tag
//Now start looking for frames
ID3v22Frame next;
frameMap = new LinkedHashMap();
encryptedFrameMap = 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 Padding, no more frames
catch (PaddingException ex)
{
logger.config(getLoggingFilename() + ":Found padding starting at:" + byteBuffer.position());
break;
}
//Found Empty Frame
catch (EmptyFrameException ex)
{
logger.warning(getLoggingFilename() + ":" + "Empty Frame:" + ex.getMessage());
this.emptyFrameBytes += ID3v22Frame.FRAME_HEADER_SIZE;
}
catch (InvalidFrameIdentifierException ifie)
{
logger.config(getLoggingFilename() + ":" + "Invalid Frame Identifier:" + ifie.getMessage());
this.invalidFrames++;
//Dont try and find any more frames
break;
}
//Problem trying to find frame
catch (InvalidFrameException ife)
{
logger.warning(getLoggingFilename() + ":" + "Invalid Frame:" + ife.getMessage());
this.invalidFrames++;
//Dont try and find any more frames
break;
}
//Failed reading frame but may just have invalid data but correct length so lets carry on
//in case we can read the next frame
catch(InvalidDataTypeException idete)
{
logger.warning(getLoggingFilename() + ":Corrupt Frame:" + idete.getMessage());
this.invalidFrames++;
continue;
}
}
|
private void | readHeaderFlags(java.nio.ByteBuffer byteBuffer)Read tag Header Flags
//Flags
byte flags = byteBuffer.get();
unsynchronization = (flags & MASK_V22_UNSYNCHRONIZATION) != 0;
compression = (flags & MASK_V22_COMPRESSION) != 0;
if (unsynchronization)
{
logger.config(ErrorMessage.ID3_TAG_UNSYNCHRONIZED.getMsg(getLoggingFilename()));
}
if (compression)
{
logger.config(ErrorMessage.ID3_TAG_COMPRESSED.getMsg(getLoggingFilename()));
}
//Not allowable/Unknown Flags
if ((flags & FileConstants.BIT5) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT5));
}
if ((flags & FileConstants.BIT4) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT4));
}
if ((flags & FileConstants.BIT3) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT3));
}
if ((flags & FileConstants.BIT2) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT2));
}
if ((flags & FileConstants.BIT1) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT1));
}
if ((flags & FileConstants.BIT0) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT3));
}
|
protected void | translateFrame(AbstractID3v2Frame frame)This is used when we need to translate a single frame into multiple frames,
currently required for TDRC frames.
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);
}
|
public void | write(java.io.File file, long audioStartLocation){@inheritDoc}
setLoggingFilename(file.getName());
logger.config("Writing tag to file:"+getLoggingFilename());
// Write Body Buffer
byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray();
// Unsynchronize if option enabled and unsync required
unsynchronization = TagOptionSingleton.getInstance().isUnsyncTags() && ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer);
if (isUnsynchronization())
{
bodyByteBuffer = ID3Unsynchronization.unsynchronize(bodyByteBuffer);
logger.config(getLoggingFilename() + ":bodybytebuffer:sizeafterunsynchronisation:" + bodyByteBuffer.length);
}
int sizeIncPadding = calculateTagSize(bodyByteBuffer.length + TAG_HEADER_LENGTH, (int) audioStartLocation);
int padding = sizeIncPadding - (bodyByteBuffer.length + TAG_HEADER_LENGTH);
logger.config(getLoggingFilename() + ":Current audiostart:" + audioStartLocation);
logger.config(getLoggingFilename() + ":Size including padding:" + sizeIncPadding);
logger.config(getLoggingFilename() + ":Padding:" + padding);
ByteBuffer headerBuffer = writeHeaderToBuffer(padding, bodyByteBuffer.length);
writeBufferToFile(file,headerBuffer, bodyByteBuffer,padding,sizeIncPadding,audioStartLocation);
|
public void | write(java.nio.channels.WritableByteChannel channel){@inheritDoc}
logger.config(getLoggingFilename() + ":Writing tag to channel");
byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray();
logger.config(getLoggingFilename() + ":bodybytebuffer:sizebeforeunsynchronisation:" + bodyByteBuffer.length);
//Unsynchronize if option enabled and unsync required
unsynchronization = TagOptionSingleton.getInstance().isUnsyncTags() && ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer);
if (isUnsynchronization())
{
bodyByteBuffer = ID3Unsynchronization.unsynchronize(bodyByteBuffer);
logger.config(getLoggingFilename() + ":bodybytebuffer:sizeafterunsynchronisation:" + bodyByteBuffer.length);
}
ByteBuffer headerBuffer = writeHeaderToBuffer(0, bodyByteBuffer.length);
channel.write(headerBuffer);
channel.write(ByteBuffer.wrap(bodyByteBuffer));
|
private java.nio.ByteBuffer | writeHeaderToBuffer(int padding, int size)Write the ID3 header to the ByteBuffer.
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)
{
flags |= (byte) MASK_V22_UNSYNCHRONIZATION;
}
if (compression)
{
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;
|