JAudioTagger is an audio tagging library written in Java language. It currently
fully supports
Mp3,
Mp4 (Mp4 audio, M4a and M4p audio)
Ogg Vorbis,
Flac and
Wma, there is limited support for
Wav and
Real format.
Features of JAudioTagger
- Provide a generic interface for the most popular thirty attributes for all the fully supported formats
- Supports reading and writing of mp4,m4a and mp4p (protected) files, including multiple images and reverse dns fields
- Supports Multiple Page Ogg Vorbis Comments
- Supports MP3 ID3v1,ID3v1.1, ID3v2.2, v2.3 and v2.4 are transparently
- Allows easy conversion between ID3 tag versions
- Supports Flac, including embedded and linked image support
- Provides proper object representations of most fields, rather than a simple byte representation
- Fully supports Unicode Text Encoding
- Is being actively developed and supported
- Uses an automatic testsuite to ensure code compatibility betweens versions
- Uses a Code Coverage tool to ensure code is actually being tested
- Is being used by a number of applications
About ID3
ID3 is a metadata container format often used to store metadata of audio files. ID3 is a de facto standard for metadata in mp3 files. There is no
standardization body involved in creation of standards for ID3 tags. There are two unrelated versions of ID3: ID3v1 and ID3v2.
ID3v1
ID3v1 takes the form of a 128-byte segment at the end of an MP3 file
containing a fixed set of data fields. There are two sub versions of
ID3v1 called ID3v1.1 and ID3v1.2. ID3v1.1 has small difference when compared to ID3v1. In ID3v1.1, last 2 bytes of comment tag was used to store track number.
Field |
Length |
Description |
header |
3 |
"TAG" |
title |
30 |
30 characters of the title |
artist |
30 |
30 characters of the artist name |
album |
30 |
30 characters of the album name |
year |
4 |
A four-digit year |
comment |
28 or 30 |
The comment. |
zero-byte |
1 |
If a track number is stored, this byte contains a binary 0. |
track |
1 |
The number of the track on the album, or 0. Invalid, if previous byte is not a binary 0. |
genre |
1 |
Index in a list of genres, or 255 |
ID3v2
ID3v2 tags are of variable size, and usually occur at the start of the file, to aid streaming media. They consist of a number of frames, each of which contains a piece of metadata. For example, the TIT2 frame contains the title, and the WOAR frame contains the URL of the artist's website. Frames can be up to 16MB in length, while total tag size is limited to 256MB. The internationalization problem was solved by allowing the encoding of strings not only in ISO-8859-1, but also in Unicode.
ID3v2 frame specification
Frame |
Album sort order |
N/A |
TSOA |
Album/Movie/Show title |
TALB |
Attached picture |
APIC |
Audio encryption |
AENC |
Audio seek point index |
N/A |
ASPI |
Band/orchestra/accompaniment |
TPE2 |
Beats per minute (BPM) |
TBPM |
Comments |
COMM |
Commercial frame |
COMR |
Commercial information |
WCOM |
Composer |
TCOM |
Conductor/performer refinement |
TPE3 |
Content group description |
TIT1 |
Content type |
TCON |
Copyright message |
TCOP |
Copyright/Legal information |
WCOP |
Date |
TDAT |
TDRC |
Encoded by |
TENC |
Encoding time |
N/A |
TDEN |
Encryption method registration |
ENCR |
Equalization |
EQUA |
EQU2 |
Event timing codes |
ETCO |
File owner/licensee |
TOWN |
File type |
TFLT |
General encapsulated object |
GEOB |
Group identification registration |
GRID |
Initial key |
TKEY |
International Standard Recording Code (ISRC) |
TSRC |
Internet radio station name |
TRSN |
Internet radio station owner |
TRSO |
Interpreted, remixed, or otherwise modified by |
TPE4 |
Involved people list |
IPLS |
TIPL |
Language(s) |
TLAN |
Lead performer(s)/Soloist(s) |
TPE1 |
Length |
TLEN |
Linked information |
LINK |
Lyricist/Text writer |
TEXT |
Media type |
TMED |
Mood |
N/A |
TMOO |
MPEG location lookup table |
MLLT |
Music CD identifier |
MCDI |
Musician credits list |
N/A |
TMCL |
Official artist/performer webpage |
WOAR |
Official audio file webpage |
WOAF |
Official audio source webpage |
WOAS |
Official internet radio station homepage |
WORS |
Original album/movie/show title |
TOAL |
Original artist(s)/performer(s) |
TOPE |
Original filename |
TOFN |
Original lyricist(s)/text writer(s) |
TOLY |
Original release year |
TORY |
TDOR |
Ownership frame |
OWNE |
Part of a set |
TPOS |
Payment |
WPAY |
Performer sort order |
N/A |
TSOP |
Play counter |
PCNT |
Playlist delay |
TDLY |
Popularimeter |
POPM |
Position synchronisation frame |
POSS |
Private frame |
PRIV |
Produced notice |
N/A |
TPRO |
Publisher |
TPUB |
Publishers official webpage |
WPUB |
Recommended buffer size |
RBUF |
Recording dates |
TRDA |
TDRC |
Recording time |
N/A |
TDRC |
Relative volume adjustment |
RVAD |
RVA2 |
Release time |
N/A |
TDRL |
Reverb |
RVRB |
Seek frame |
N/A |
SEEK |
Set subtitle |
N/A |
TSST |
Signature frame |
N/A |
SIGN |
Size |
TSIZ |
Dropped |
Software/Hardware and settings used for encoding |
TSSE |
Subtitle/Description refinement |
TIT3 |
Synchronized lyric/text |
SYLT |
Synchronized tempo codes |
SYTC |
Tagging time |
N/A |
TDTG |
Terms of use |
USER |
Time |
TIME |
TDRC |
Title sort order |
N/A |
TSOT |
Title/songname/content description |
TIT2 |
Track number/Position in set |
TRCK |
Unique file identifier |
UFID |
Unsynchronized lyric/text transcription |
USLT |
User defined text information frame |
TXXX |
User defined URL link frame |
WXXX |
Year |
TYER |
TDRC |
Add JAudioTagger library to android application.
- Download latest version of JAudioTagger from its releases page.
- Copy the downloaded jar file to libs folder in your app folder.
- In Android Studio add jar library dependency by going to File > Project Structure > app > Dependencies > + > Jar dependency
Using JAudioTagger in Android
Metadata container class.
import java.util.List;
public class Metadata {
//header metadata
private String uri, //uri of audio file
format; //audio file format
private int sampleRate, //number of samples taken per second
trackLength; //track length in seconds
private long fileSize; //file size in bytes
private boolean isLossless; //if the audio codec is lossless or lossy
//audio metadata
private String title,
album,
track,
year,
rating,
comment,
lyrics;
private List coverArtList;
private List artistList,
albumArtistList,
genreList;
public Metadata(String uri, String format, int sampleRate, int trackLength, long fileSize, boolean isLossless, String title, String album, String track, String year, String rating, String comment, String lyrics, List coverArtList, List artistList, List albumArtistList, List genreList) {
this.uri = uri;
this.format = format;
this.sampleRate = sampleRate;
this.trackLength = trackLength;
this.fileSize = fileSize;
this.isLossless = isLossless;
this.title = title;
this.album = album;
this.track = track;
this.year = year;
this.rating = rating;
this.comment = comment;
this.lyrics = lyrics;
this.coverArtList = coverArtList;
this.artistList = artistList;
this.albumArtistList = albumArtistList;
this.genreList = genreList;
}
public String getUri() {
return uri;
}
public String getFormat() {
return format;
}
public int getSampleRate() {
return sampleRate;
}
public int getTrackLength() {
return trackLength;
}
public long getFileSize() {
return fileSize;
}
public boolean isLossless() {
return isLossless;
}
public String getTitle() {
return title;
}
public String getAlbum() {
return album;
}
public String getTrack() {
return track;
}
public String getYear() {
return year;
}
public String getRating() {
return rating;
}
public String getComment() {
return comment;
}
public String getLyrics() {
return lyrics;
}
public List getCoverArtList() {
return coverArtList;
}
public List getArtistList() {
return artistList;
}
public List getAlbumArtistList() {
return albumArtistList;
}
public List getGenreList() {
return genreList;
}
}
Methods to read and write metadata.
public static Metadata readMetadata(String uri) throws TagException, ReadOnlyFileException, CannotReadException, InvalidAudioFrameException, IOException {
File file = new File(uri);
AudioFile audioFile = AudioFileIO.read(file);
AudioHeader header = audioFile.getAudioHeader();
Tag tag = audioFile.getTagAndConvertOrCreateAndSetDefault();
//header metadata
String format = header.getFormat();
int sampleRate = header.getSampleRateAsNumber(),
trackLength = header.getTrackLength();
long fileSize = file.length();
boolean isLossless = header.isLossless();
//audio metadata
String title = tag.getFirst(FieldKey.TITLE),
album = tag.getFirst(FieldKey.ALBUM),
track = tag.getFirst(FieldKey.TRACK),
year = tag.getFirst(FieldKey.YEAR),
rating = tag.getFirst(FieldKey.RATING),
comment = tag.getFirst(FieldKey.COMMENT),
lyrics = tag.getFirst(FieldKey.LYRICS);
byte[] coverArt = tag.getFirstArtwork().getBinaryData();
List artistList = tag.getAll(FieldKey.ARTIST),
albumArtistList = tag.getAll(FieldKey.ALBUM_ARTIST),
genreList = tag.getAll(FieldKey.GENRE);
return new Metadata(uri,
format,
sampleRate,
trackLength,
fileSize,
isLossless,
title,
album,
track,
year,
rating,
comment,
lyrics,
coverArt,
artistList,
albumArtistList,
genreList);
}
public static void writeMetadata(Metadata metadata) throws TagException, ReadOnlyFileException, CannotReadException, InvalidAudioFrameException, IOException, CannotWriteException {
AudioFile audioFile = AudioFileIO.read(new File(metadata.getUri()));
ID3v24Tag tag = new ID3v24Tag();
tag.setField(FieldKey.TITLE, metadata.getTitle());
tag.setField(FieldKey.ALBUM, metadata.getAlbum());
tag.setField(FieldKey.TRACK, metadata.getTrack());
tag.setField(FieldKey.YEAR, metadata.getYear());
tag.setField(FieldKey.RATING, metadata.getRating());
tag.setField(FieldKey.COMMENT, metadata.getComment());
tag.setField(FieldKey.LYRICS, metadata.getLyrics());
Artwork artwork = new AndroidArtwork();
artwork.setBinaryData(metadata.getCoverArt());
tag.setField(artwork);
addAll(tag, FieldKey.ARTIST, metadata.getArtistList());
addAll(tag, FieldKey.ALBUM_ARTIST, metadata.getAlbumArtistList());
addAll(tag, FieldKey.GENRE, metadata.getGenreList());
audioFile.setTag(tag);
AudioFileIO.write(audioFile);
}
private static void addAll(Tag tag, FieldKey fieldKey, List dataList) throws FieldDataInvalidException {
for (String s : dataList) {
tag.addField(fieldKey, s);
}
}
Convert artwork binary data into Bitmap image.
public Bitmap getBitmap(byte[] imageData) {
return BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
}
Comments
Post a Comment