Additional information for Mp3 files
Reading Data
The ID3 format used by Mp3 is more complicated than other metadata formats, so the interface is also more complex. An Mp3 can contain both a ID3v1 tag and an ID3v2 tag, both tags are optional. The ID3v1 tag can be version 1.0 or version 1.1. An ID3v2 tag can be version 2.2, 2.3 or 2.4 and the differences between the versions is quite considerable.
The stuff you might want to know about but you can't change is stored in the AudioHeader class
MP3File f = (Mp3File)AudioFileIO.read(testFile);
MP3AudioHeader audioHeader = f.getAudioHeader();
System.out.println(audioHeader.getTrackLength());
System.out.println(audioHeader.getSampleRateAsNumber());
System.out.println(mp3AudioHeader.getChannels());
System.out.println(mp3AudioHeader.isVariableBitRate());
Mp3 provides a subclass called MP3AudioHeader that contains additional information.
System.out.println(mp3AudioHeader.getTrackLengthAsString());
System.out.println(mp3AudioHeader.getMpegVersion());
System.out.println(mp3AudioHeader.getMpegLayer());
System.out.println(mp3AudioHeader.isOriginal());
System.out.println(mp3AudioHeader.isCopyrighted());
System.out.println(mp3AudioHeader.isPrivate());
System.out.println(mp3AudioHeader.isProtected());
System.out.println(mp3AudioHeader.getBitRate());
System.out.println(mp3AudioHeader.getEncodingType());
System.out.println(mp3AudioHeader.getEncoder());
The metadata information that you can change is stored in tags. If the file contains and ID3v2 tag the getTag() method will return the ID3v2 Tag , if it does not exist but there is a ID3v1 tag it will return this instead, otherwise it will return null. You can use getID3v1Tag() and getID3v2Tag() for more control. Alternatively Jaudiotagger provides a getID3v2TagAsv24() method, this returns the v2Tag converted to v24 format if it was not already in v24 format, the advantage of this is that you can treat all Mp3 files as if their v2 tag is in v24 format whether or not it actually is.
MP3File f = (Mp3File)AudioFileIO.read(testFile);
Tag tag = f.getTag();
ID3v1Tag v1Tag = (ID3v1Tag)tag;
AbstractID3v2Tag v2tag = f.getID3v2Tag()
ID3v24Tag v24tag = (AbstractID3v2Tag)f.getID3v2TagAsv24();
The v1 tag only contains a very limited set of fields, these can be read as follows
System.out.println(tag.getFirstArtist());
System.out.println(tag.getFirstAlbum());
System.out.println(tag.getFirstTitle());
System.out.println(tag.getFirstComment());
System.out.println(tag.getFirstYear());
System.out.println(tag.getFirstTrack());
The rest of this document deals with the ID3v2 tag, you can check that an ID3v2 tag exists with
f.hasID3v2Tag();
In ID3v2, fields are known as frames, for simple text fields you can extract the information with
System.out.println(v2Tag.getFirst(ID3v24Frames.FRAME_ID_ARTIST));
System.out.println(v2Tag.getFirst(ID3v24Frames.FRAME_ID_ALBUM));
System.out.println(v2Tag.getFirst(ID3v24Frames.FRAME_ID_YEAR));
Or you can retrieve the frame itself and then get details of its body, this is most useful when dealing with one of the manu binary fields supported in ID3v2
AbstractID3v2Frame frame = v2Tag.getFirstField(ID3v24Frames.FRAME_ID_ARTIST);
System.out.println(text.getBody().getId();
if(frame.getBody() instanceof AbstractFrameBodyTextInfo)
{
AbstractFrameBodyTextInfo textBody = (AbstractFrameBodyTextInfo)frame.getBody();
System.out.println(text.getBody().getText();
}
Retreiving cover art can be done as follows
BufferedImage bi=null;
TagField imageField = af.getTag().get(TagFieldKey.COVER_ART).get(0);
if(imageField instanceof AbstractID3v2Frame)
{
FrameBodyAPIC imageFrameBody = (FrameBodyAPIC)((AbstractID3v2Frame)imageField).getBody();
if(!imageFrameBody.isImageUrl())
{
byte[] imageRawData = (byte[])imageFrameBody.getObjectValue(DataTypes.OBJ_PICTURE_DATA);
bi=ImageIO.read(new ByteArrayInputStream(imageRawData));
}
}
Writing Data
You can create a new tag of your chosen version if one doesnt exist as follows
ID3v24Tag v2tag = new ID3v24Tag();
v2tag.setComment("Comment");
mp3File.setID3v2Tag(v2tag);
You can add images
RandomAccessFile imageFile = new RandomAccessFile(new File("testdata", "coverart.png"), "r");
byte[] imagedata = new byte[(int) imageFile.length()];
imageFile.read(imagedata);
v2tag.add(tag.createArtworkField(imagedata,"image/png"));
af.commit();
When adding images you can add linked images in addition to embedding images
v2tag.add(v2tag.createLinkedArtworkField("../testdata/coverart.jpg"));
|