7

Lately, I've been trying to write a program that can change the ID3 tags of an mp3 file. I managed to write code to get those tags quite easily, but I have no idea how to write code to modify the tags. I assumed that there may be no easy solution, so I decided to try out some libraries. It may be my fault, but none of them work..

Anyway, my question is: how do I write my own code to modify ID3 tags? If it's not that easy, are there any libraries you can recommend?

Cardinal System
  • 2,749
  • 3
  • 21
  • 42
krp
  • 71
  • 1
  • 1
  • 2
  • 1
    This question should have been closed. It is both "too broad" - *"how do I write my own code to modify ID3 tags?"* and a request for a recommendation. – Stephen C Dec 16 '20 at 02:28
  • @StephenC while the question itself was not asked very well, it still seems to have significant value to the community. With over 13,000 views, it must be a question that a lot of other users are asking. – Cardinal System Dec 17 '20 at 03:28
  • The problem is not that it was not asked well. The problem is that it is a request for a recommendation. And requests for recommendations are **explicitly** off-topic. It doesn't matter that many users would *like* StackOverflow to be a recommendations site. It isn't, and the "what not to ask" page is very clear about it. – Stephen C Dec 17 '20 at 03:32
  • If you (or anyone else) would like request a recommendation for a Java library that can modify id3 tags, a more appropriate place to ask would be https://softwarerecs.stackexchange.com/ – Stephen C Dec 17 '20 at 03:35
  • @StephenC is there a process to migrate a question to a different site? – Cardinal System Dec 17 '20 at 03:48
  • Not an old question like this. AFAIK. – Stephen C Dec 17 '20 at 03:58
  • @StephenC in that case, I would like to place another bounty on a question more suited for StackOverflow. [This question](https://stackoverflow.com/q/41459061/5645656) seems more on topic. Would you agree? – Cardinal System Dec 17 '20 at 04:08
  • Questions about the appropriate use of bonuses, recommendation questions, migration and so on belong on meta.stackoverflow.com – Stephen C Dec 17 '20 at 04:11

3 Answers3

3

You should have a look at the library jAudioTagger. Below is an example that writes a custom tag (TXXX) to an audio file:

/**
 * This will write a custom ID3 tag (TXXX).
 * This works only with MP3 files (Flac with ID3-Tag not tested).
 * @param description The description of the custom tag i.e. "catalognr"
 * There can only be one custom TXXX tag with that description in one MP3 file
 * @param text The actual text to be written into the new tag field
 * @return True if the tag has been properly written, false otherwise
 */

public boolean setCustomTag(AudioFile audioFile, String description, String text){
    FrameBodyTXXX txxxBody = new FrameBodyTXXX();
    txxxBody.setDescription(description);
    txxxBody.setText(text);

    // Get the tag from the audio file
    // If there is no ID3Tag create an ID3v2.3 tag
    Tag tag = audioFile.getTagOrCreateAndSetDefault();
    // If there is only a ID3v1 tag, copy data into new ID3v2.3 tag
    if(!(tag instanceof ID3v23Tag || tag instanceof ID3v24Tag)){
        Tag newTagV23 = null;
        if(tag instanceof ID3v1Tag){
            newTagV23 = new ID3v23Tag((ID3v1Tag)audioFile.getTag()); // Copy old tag data               
        }
        if(tag instanceof ID3v22Tag){
            newTagV23 = new ID3v23Tag((ID3v11Tag)audioFile.getTag()); // Copy old tag data              
        }           
        audioFile.setTag(newTagV23);
    }

    AbstractID3v2Frame frame = null;
    if(tag instanceof ID3v23Tag){
        frame = new ID3v23Frame("TXXX");
    }
    else if(tag instanceof ID3v24Tag){
        frame = new ID3v24Frame("TXXX");
    }

    frame.setBody(txxxBody);

    try {
        tag.addField(frame);
    } catch (FieldDataInvalidException e) {
        e.printStackTrace();
        return false;
    }

    try {
        audioFile.commit();
    } catch (CannotWriteException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}
Pwdr
  • 3,712
  • 4
  • 28
  • 38
2

I ended up coding a tag editor myself since I didn't want to use a library. It's for ID3v1 tags only. Full Code

Here's how it works: enter image description here

So all you have to do is write 128 bytes to the end of the file. Starting with TAG, followed by 30 bytes for the title, 30 for the artist, etc. The genre list can be found here.

    public void writeID3v1Tags(File file, String title, String artist, String album, String year, String comment, int genreId) { throws IOException {
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
        FileChannel channel = randomAccessFile.getChannel();

        if (!hasID3v1Tag(channel)) {
            channel.position(channel.size());
            writeTag(channel, "TAG", 3);
        }

        writeTag(channel, title, 30);
        writeTag(channel, artist, 30);
        writeTag(channel, album, 30);
        writeTag(channel, year, 4);
        writeTag(channel, comment, 30);
        writeTag(channel, String.valueOf((char) genreId), 1);

        channel.close();
    }

    private void writeTag(FileChannel channel, String tagValue, int maxLength) throws IOException {
        int length = tagValue.length();
        if (length > maxLength) {
            tagValue = tagValue.substring(0, maxLength);
            length = tagValue.length();
        }

        ByteBuffer byteBuffer = ByteBuffer.wrap(tagValue.getBytes());
        channel.write(byteBuffer);

        byteBuffer = ByteBuffer.allocate(maxLength - length);
        channel.write(byteBuffer);
    }

    private boolean hasID3v1Tag(FileChannel channel) throws IOException {
        channel.position(channel.size() - 128);
        String prefix = readTag(channel, 3);
        return "TAG".equals(prefix);
    }

If you want more tags (like album cover, lyrics, and much more) you need to use ID3v2. It works basically the same but is a little bit more complex, more info under https://id3.org/id3v2.3.0

nhcodes
  • 1,206
  • 8
  • 20
2

This library:

http://javamusictag.sourceforge.net/

provides a means of reading and writing id3 tags.

Binaromong
  • 540
  • 7
  • 26